diff --git a/dist/liquid.js b/dist/liquid.js
index a856edee8..b8da5d8ef 100644
--- a/dist/liquid.js
+++ b/dist/liquid.js
@@ -6,199 +6,198 @@ var _ = require('./src/util/underscore.js');
var isTruthy = require('./src/syntax.js').isTruthy;
var escapeMap = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": '''
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": '''
};
var unescapeMap = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- ''': "'"
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ ''': "'"
};
var filters = {
- 'abs': function abs(v) {
- return Math.abs(v);
- },
- 'append': function append(v, arg) {
- return v + arg;
- },
- 'capitalize': function capitalize(str) {
- return stringify(str).charAt(0).toUpperCase() + str.slice(1);
- },
- 'ceil': function ceil(v) {
- return Math.ceil(v);
- },
- 'date': function date(v, arg) {
- if (v === 'now') v = new Date();
- return v instanceof Date ? strftime(v, arg) : '';
- },
- 'default': function _default(v, arg) {
- return isTruthy(v) ? v : arg;
- },
- 'divided_by': function divided_by(v, arg) {
- return Math.floor(v / arg);
- },
- 'downcase': function downcase(v) {
- return v.toLowerCase();
- },
- 'escape': escape,
+ 'abs': function abs(v) {
+ return Math.abs(v);
+ },
+ 'append': function append(v, arg) {
+ return v + arg;
+ },
+ 'capitalize': function capitalize(str) {
+ return stringify(str).charAt(0).toUpperCase() + str.slice(1);
+ },
+ 'ceil': function ceil(v) {
+ return Math.ceil(v);
+ },
+ 'date': function date(v, arg) {
+ if (v === 'now') v = new Date();
+ return v instanceof Date ? strftime(v, arg) : '';
+ },
+ 'default': function _default(v, arg) {
+ return isTruthy(v) ? v : arg;
+ },
+ 'divided_by': function divided_by(v, arg) {
+ return Math.floor(v / arg);
+ },
+ 'downcase': function downcase(v) {
+ return v.toLowerCase();
+ },
+ 'escape': escape,
- 'escape_once': function escape_once(str) {
- return escape(unescape(str));
- },
- 'first': function first(v) {
- return v[0];
- },
- 'floor': function floor(v) {
- return Math.floor(v);
- },
- 'join': function join(v, arg) {
- return v.join(arg);
- },
- 'last': function last(v) {
- return v[v.length - 1];
- },
- 'lstrip': function lstrip(v) {
- return stringify(v).replace(/^\s+/, '');
- },
- 'map': function map(arr, arg) {
- return arr.map(function (v) {
- return v[arg];
- });
- },
- 'minus': bindFixed(function (v, arg) {
- return v - arg;
- }),
- 'modulo': bindFixed(function (v, arg) {
- return v % arg;
- }),
- 'newline_to_br': function newline_to_br(v) {
- return v.replace(/\n/g, '
');
- },
- 'plus': bindFixed(function (v, arg) {
- return Number(v) + Number(arg);
- }),
- 'prepend': function prepend(v, arg) {
- return arg + v;
- },
- 'remove': function remove(v, arg) {
- return v.split(arg).join('');
- },
- 'remove_first': function remove_first(v, l) {
- return v.replace(l, '');
- },
- 'replace': function replace(v, pattern, replacement) {
- return stringify(v).split(pattern).join(replacement);
- },
- 'replace_first': function replace_first(v, arg1, arg2) {
- return stringify(v).replace(arg1, arg2);
- },
- 'reverse': function reverse(v) {
- return v.reverse();
- },
- 'round': function round(v, arg) {
- var amp = Math.pow(10, arg || 0);
- return Math.round(v * amp, arg) / amp;
- },
- 'rstrip': function rstrip(str) {
- return stringify(str).replace(/\s+$/, '');
- },
- 'size': function size(v) {
- return v.length;
- },
- 'slice': function slice(v, begin, length) {
- return v.substr(begin, length === undefined ? 1 : length);
- },
- 'sort': function sort(v, arg) {
- return v.sort(arg);
- },
- 'split': function split(v, arg) {
- return stringify(v).split(arg);
- },
- 'strip': function strip(v) {
- return stringify(v).trim();
- },
- 'strip_html': function strip_html(v) {
- return stringify(v).replace(/<\/?\s*\w+\s*\/?>/g, '');
- },
- 'strip_newlines': function strip_newlines(v) {
- return stringify(v).replace(/\n/g, '');
- },
- 'times': function times(v, arg) {
- return v * arg;
- },
- 'truncate': function truncate(v, l, o) {
- v = stringify(v);
- o = o === undefined ? '...' : o;
- l = l || 16;
- if (v.length <= l) return v;
- return v.substr(0, l - o.length) + o;
- },
- 'truncatewords': function truncatewords(v, l, o) {
- if (o === undefined) o = '...';
- var arr = v.split(' ');
- var ret = arr.slice(0, l).join(' ');
- if (arr.length > l) ret += o;
- return ret;
- },
- 'uniq': function uniq(arr) {
- var u = {};
- return (arr || []).filter(function (val) {
- if (u.hasOwnProperty(val)) {
- return false;
- }
- u[val] = true;
- return true;
- });
- },
- 'upcase': function upcase(str) {
- return stringify(str).toUpperCase();
- },
- 'url_encode': encodeURIComponent
+ 'escape_once': function escape_once(str) {
+ return escape(unescape(str));
+ },
+ 'first': function first(v) {
+ return v[0];
+ },
+ 'floor': function floor(v) {
+ return Math.floor(v);
+ },
+ 'join': function join(v, arg) {
+ return v.join(arg);
+ },
+ 'last': function last(v) {
+ return v[v.length - 1];
+ },
+ 'lstrip': function lstrip(v) {
+ return stringify(v).replace(/^\s+/, '');
+ },
+ 'map': function map(arr, arg) {
+ return arr.map(function (v) {
+ return v[arg];
+ });
+ },
+ 'minus': bindFixed(function (v, arg) {
+ return v - arg;
+ }),
+ 'modulo': bindFixed(function (v, arg) {
+ return v % arg;
+ }),
+ 'newline_to_br': function newline_to_br(v) {
+ return v.replace(/\n/g, '
');
+ },
+ 'plus': bindFixed(function (v, arg) {
+ return Number(v) + Number(arg);
+ }),
+ 'prepend': function prepend(v, arg) {
+ return arg + v;
+ },
+ 'remove': function remove(v, arg) {
+ return v.split(arg).join('');
+ },
+ 'remove_first': function remove_first(v, l) {
+ return v.replace(l, '');
+ },
+ 'replace': function replace(v, pattern, replacement) {
+ return stringify(v).split(pattern).join(replacement);
+ },
+ 'replace_first': function replace_first(v, arg1, arg2) {
+ return stringify(v).replace(arg1, arg2);
+ },
+ 'reverse': function reverse(v) {
+ return v.reverse();
+ },
+ 'round': function round(v, arg) {
+ var amp = Math.pow(10, arg || 0);
+ return Math.round(v * amp, arg) / amp;
+ },
+ 'rstrip': function rstrip(str) {
+ return stringify(str).replace(/\s+$/, '');
+ },
+ 'size': function size(v) {
+ return v.length;
+ },
+ 'slice': function slice(v, begin, length) {
+ return v.substr(begin, length === undefined ? 1 : length);
+ },
+ 'sort': function sort(v, arg) {
+ return v.sort(arg);
+ },
+ 'split': function split(v, arg) {
+ return stringify(v).split(arg);
+ },
+ 'strip': function strip(v) {
+ return stringify(v).trim();
+ },
+ 'strip_html': function strip_html(v) {
+ return stringify(v).replace(/<\/?\s*\w+\s*\/?>/g, '');
+ },
+ 'strip_newlines': function strip_newlines(v) {
+ return stringify(v).replace(/\n/g, '');
+ },
+ 'times': function times(v, arg) {
+ return v * arg;
+ },
+ 'truncate': function truncate(v, l, o) {
+ v = stringify(v);
+ o = o === undefined ? '...' : o;
+ l = l || 16;
+ if (v.length <= l) return v;
+ return v.substr(0, l - o.length) + o;
+ },
+ 'truncatewords': function truncatewords(v, l, o) {
+ if (o === undefined) o = '...';
+ var arr = v.split(' ');
+ var ret = arr.slice(0, l).join(' ');
+ if (arr.length > l) ret += o;
+ return ret;
+ },
+ 'uniq': function uniq(arr) {
+ var u = {};
+ return (arr || []).filter(function (val) {
+ if (u.hasOwnProperty(val)) {
+ return false;
+ }
+ u[val] = true;
+ return true;
+ });
+ },
+ 'upcase': function upcase(str) {
+ return stringify(str).toUpperCase();
+ },
+ 'url_encode': encodeURIComponent
};
function escape(str) {
- return stringify(str).replace(/&|<|>|"|'/g, function (m) {
- return escapeMap[m];
- });
+ return stringify(str).replace(/&|<|>|"|'/g, function (m) {
+ return escapeMap[m];
+ });
}
function unescape(str) {
- return stringify(str).replace(/&(amp|lt|gt|#34|#39);/g, function (m) {
- return unescapeMap[m];
- });
+ return stringify(str).replace(/&(amp|lt|gt|#34|#39);/g, function (m) {
+ return unescapeMap[m];
+ });
}
function getFixed(v) {
- var p = (v + "").split(".");
- return p.length > 1 ? p[1].length : 0;
+ var p = (v + '').split('.');
+ return p.length > 1 ? p[1].length : 0;
}
function getMaxFixed(l, r) {
- return Math.max(getFixed(l), getFixed(r));
+ return Math.max(getFixed(l), getFixed(r));
}
function stringify(obj) {
- obj = obj || "";
- return obj + '';
+ return obj + '';
}
function bindFixed(cb) {
- return function (l, r) {
- var f = getMaxFixed(l, r);
- return cb(l, r).toFixed(f);
- };
+ return function (l, r) {
+ var f = getMaxFixed(l, r);
+ return cb(l, r).toFixed(f);
+ };
}
function registerAll(liquid) {
- return _.forOwn(filters, function (func, name) {
- return liquid.registerFilter(name, func);
- });
+ return _.forOwn(filters, function (func, name) {
+ return liquid.registerFilter(name, func);
+ });
}
registerAll.filters = filters;
@@ -258,11 +257,6 @@ var _engine = {
return _this.parse(html);
}).then(function (tpl) {
return _this.render(tpl, ctx, opts);
- }).catch(function (e) {
- if (e instanceof Errors.RenderBreakError) {
- return e.html;
- }
- throw e;
});
},
renderFile: function renderFile(filepath, ctx, opts) {
@@ -294,9 +288,7 @@ var _engine = {
return path;
});
}).catch(function (e) {
- if (e.code === 'ENOENT') {
- e.message = 'Failed to lookup ' + filepath + ' in: ' + root;
- }
+ e.message = e.code + ': Failed to lookup ' + filepath + ' in: ' + root;
throw e;
});
},
@@ -639,6 +631,7 @@ function parseLiteral(str) {
if (res) {
return str.slice(1, -1);
}
+ throw new TypeError('cannot parse \'' + str + '\' as literal');
}
module.exports = {
@@ -907,7 +900,6 @@ module.exports = factory;
var _ = require('./util/underscore.js');
var lexical = require('./lexical.js');
var assert = require('./util/assert.js');
-var toStr = Object.prototype.toString;
var Scope = {
getAll: function getAll() {
@@ -918,32 +910,16 @@ var Scope = {
return ctx;
},
get: function get(str) {
- for (var i = this.scopes.length - 1; i >= 0; i--) {
- try {
- return this.getPropertyByPath(this.scopes[i], str);
- } catch (e) {
- if (/undefined variable/.test(e.message)) {
- continue;
- }
- if (/Cannot read property/.test(e.message)) {
- if (this.opts.strict_variables) {
- e.message += ': ' + str;
- throw e;
- } else {
- continue;
- }
- } else {
- e.message += ': ' + str;
- throw e;
- }
+ try {
+ return this.getPropertyByPath(this.scopes, str);
+ } catch (e) {
+ if (!/undefined variable/.test(e.message) || this.opts.strict_variables) {
+ throw e;
}
}
- if (this.opts.strict_variables) {
- throw new TypeError('undefined variable: ' + str);
- }
},
set: function set(k, v) {
- this.setPropertyByPath(this.scopes[this.scopes.length - 1], k, v);
+ setPropertyByPath(this.scopes[this.scopes.length - 1], k, v);
return this;
},
push: function push(ctx) {
@@ -960,39 +936,20 @@ var Scope = {
shift: function shift() {
return this.scopes.shift();
},
- setPropertyByPath: function setPropertyByPath(obj, path, val) {
- if (_.isString(path)) {
- var paths = path.replace(/\[/g, '.').replace(/\]/g, '').split('.');
- for (var i = 0; i < paths.length; i++) {
- var key = paths[i];
- if (i === paths.length - 1) {
- return obj[key] = val;
- }
- if (undefined === obj[key]) obj[key] = {};
- // case for readonly objects
- obj = obj[key] || {};
- }
- }
- },
- getPropertyByPath: function getPropertyByPath(obj, path) {
+ getPropertyByPath: function getPropertyByPath(scopes, path) {
var paths = this.propertyAccessSeq(path + '');
- var varName = paths.shift();
- if (!obj.hasOwnProperty(varName)) {
- throw new TypeError('undefined variable');
+ if (!paths.length) {
+ throw new TypeError('undefined variable: ' + path);
}
- var variable = obj[varName];
- var lastName = paths.pop();
- paths.forEach(function (p) {
- return variable = variable[p];
- });
- if (undefined !== lastName) {
- if (lastName === 'size' && (toStr.call(variable) === '[object Array]' || toStr.call(variable) === '[object String]')) {
- return variable.length;
+ var key = paths.shift();
+ var value = getValueFromScopes(key, scopes);
+ return paths.reduce(function (value, key) {
+ if (_.isNil(value)) {
+ throw new TypeError('undefined variable: ' + key);
}
- variable = variable[lastName];
- }
- return variable;
+ return getValueFromParent(key, value);
+ }, value);
},
/*
@@ -1055,6 +1012,33 @@ var Scope = {
}
};
+function setPropertyByPath(obj, path, val) {
+ var paths = (path + '').replace(/\[/g, '.').replace(/\]/g, '').split('.');
+ for (var i = 0; i < paths.length; i++) {
+ var key = paths[i];
+ if (i === paths.length - 1) {
+ return obj[key] = val;
+ }
+ if (undefined === obj[key]) obj[key] = {};
+ // case for readonly objects
+ obj = obj[key] || {};
+ }
+}
+
+function getValueFromParent(key, value) {
+ return key === 'size' && (_.isArray(value) || _.isString(value)) ? value.length : value[key];
+}
+
+function getValueFromScopes(key, scopes) {
+ for (var i = scopes.length - 1; i > -1; i--) {
+ var scope = scopes[i];
+ if (scope.hasOwnProperty(key)) {
+ return scope[key];
+ }
+ }
+ throw new TypeError('undefined variable: ' + key);
+}
+
function matchRightBracket(str, begin) {
var stack = 1; // count of '[' - count of ']'
for (var i = begin; i < str.length; i++) {
@@ -1134,6 +1118,7 @@ function evalValue(str, scope) {
if (lexical.isVariable(str)) {
return scope.get(str);
}
+ throw new TypeError('cannot eval \'' + str + '\' as value');
}
function isTruthy(val) {
@@ -1152,7 +1137,6 @@ module.exports = {
'use strict';
var lexical = require('./lexical.js');
-var _ = require('./util/underscore.js');
var Promise = require('any-promise');
var Syntax = require('./syntax.js');
var assert = require('./util/assert.js');
@@ -1180,13 +1164,7 @@ module.exports = function () {
return Promise.resolve('');
}
return Promise.resolve().then(function () {
- return typeof impl.render === 'function' ? impl.render(scope, obj) : '';
- }).catch(function (e) {
- if (_.isError(e)) {
- throw e;
- }
- var msg = 'Please reject with an Error in ' + impl.render + ', got ' + e;
- throw new Error(msg);
+ return impl.render(scope, obj);
});
},
parse: function parse(token, tokens) {
@@ -1224,7 +1202,7 @@ module.exports = function () {
};
};
-},{"./lexical.js":8,"./syntax.js":13,"./util/assert.js":16,"./util/underscore.js":21,"any-promise":3}],15:[function(require,module,exports){
+},{"./lexical.js":8,"./syntax.js":13,"./util/assert.js":16,"any-promise":3}],15:[function(require,module,exports){
'use strict';
var lexical = require('./lexical.js');
@@ -1331,9 +1309,6 @@ var AssertionError = require('./error.js').AssertionError;
function assert(predicate, message) {
if (!predicate) {
- if (message instanceof Error) {
- throw message;
- }
message = message || 'expect ' + predicate + ' to be true';
throw new AssertionError(message);
}
@@ -1346,11 +1321,15 @@ module.exports = assert;
var _ = require('./underscore.js');
-function TokenizationError(message, token) {
+function initError() {
+ this.name = this.constructor.name;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
- this.name = this.constructor.name;
+}
+
+function initLiquidError(message, token) {
+ initError.call(this);
this.input = token.input;
this.line = token.line;
@@ -1358,7 +1337,11 @@ function TokenizationError(message, token) {
var context = mkContext(token.input, token.line);
this.message = mkMessage(message, token);
- this.stack = context + '\n' + (this.stack || '');
+ this.stack = context + '\n' + (this.stack || this.message);
+}
+
+function TokenizationError(message, token) {
+ initLiquidError.call(this, message, token);
}
TokenizationError.prototype = Object.create(Error.prototype);
TokenizationError.prototype.constructor = TokenizationError;
@@ -1366,15 +1349,8 @@ TokenizationError.prototype.constructor = TokenizationError;
function ParseError(e, token) {
_.assign(this, e);
this.originalError = e;
- this.name = this.constructor.name;
- this.input = token.input;
- this.line = token.line;
- this.file = token.file;
-
- var context = mkContext(token.input, token.line);
- this.message = mkMessage(e.message || 'Unkown Error', token);
- this.stack = context + '\n' + (e.stack || '');
+ initLiquidError.call(this, e.message, token);
}
ParseError.prototype = Object.create(Error.prototype);
ParseError.prototype.constructor = ParseError;
@@ -1386,35 +1362,22 @@ function RenderError(e, tpl) {
}
_.assign(this, e);
this.originalError = e;
- this.name = this.constructor.name;
- this.input = tpl.token.input;
- this.line = tpl.token.line;
- this.file = tpl.token.file;
-
- var context = mkContext(tpl.token.input, tpl.token.line);
- this.message = mkMessage(e.message || 'Unkown Error', tpl.token);
- this.stack = context + '\n' + (e.stack || '');
+ initLiquidError.call(this, e.message, tpl.token);
}
RenderError.prototype = Object.create(Error.prototype);
RenderError.prototype.constructor = RenderError;
function RenderBreakError(message) {
- if (Error.captureStackTrace) {
- Error.captureStackTrace(this, this.constructor);
- }
- this.name = this.constructor.name;
- this.message = message || '';
+ initError.call(this);
+ this.message = message + '';
}
RenderBreakError.prototype = Object.create(Error.prototype);
RenderBreakError.prototype.constructor = RenderBreakError;
function AssertionError(message) {
- if (Error.captureStackTrace) {
- Error.captureStackTrace(this, this.constructor);
- }
- this.name = this.constructor.name;
- this.message = message;
+ initError.call(this);
+ this.message = message + '';
}
AssertionError.prototype = Object.create(Error.prototype);
AssertionError.prototype.constructor = AssertionError;
@@ -1688,6 +1651,7 @@ var formatCodes = {
},
z: function z(d) {
var tz = d.getTimezoneOffset() / 60 * 100;
+ console.log('tz', tz);
return (tz > 0 ? '-' : '+') + _number.pad(Math.abs(tz), 4);
},
'%': function _() {
@@ -1728,6 +1692,8 @@ module.exports = strftime;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
+var toStr = Object.prototype.toString;
+
/*
* Checks if value is classified as a String primitive or object.
* @param {any} value The value to check.
@@ -1737,6 +1703,15 @@ function isString(value) {
return value instanceof String || typeof value === 'string';
}
+function isNil(value) {
+ return value === null || value === undefined;
+}
+
+function isArray(value) {
+ // be compatible with IE 8
+ return toStr.call(value) === '[object Array]';
+}
+
function isError(value) {
var signature = Object.prototype.toString.call(value);
// [object XXXError]
@@ -1782,7 +1757,6 @@ function assign(object) {
}
function _assignBinary(dst, src) {
- if (!dst) return dst;
forOwn(src, function (v, k) {
dst[k] = v;
});
@@ -1844,6 +1818,8 @@ function range(start, stop, step) {
exports.isString = isString;
exports.isObject = isObject;
+exports.isArray = isArray;
+exports.isNil = isNil;
exports.isError = isError;
exports.range = range;
@@ -1923,55 +1899,51 @@ module.exports = function (liquid) {
'use strict';
var Liquid = require('..');
-var assert = require('../src/util/assert.js');
module.exports = function (liquid) {
- liquid.registerTag('case', {
+ liquid.registerTag('case', {
- parse: function parse(tagToken, remainTokens) {
- var _this = this;
+ parse: function parse(tagToken, remainTokens) {
+ var _this = this;
- this.cond = tagToken.args;
- this.cases = [];
- this.elseTemplates = [];
+ this.cond = tagToken.args;
+ this.cases = [];
+ this.elseTemplates = [];
- var p = [],
- stream = liquid.parser.parseStream(remainTokens).on('tag:when', function (token) {
- if (!_this.cases[token.args]) {
- _this.cases.push({
- val: token.args,
- templates: p = []
- });
- }
- }).on('tag:else', function (token) {
- return p = _this.elseTemplates;
- }).on('tag:endcase', function (token) {
- return stream.stop();
- }).on('template', function (tpl) {
- return p.push(tpl);
- }).on('end', function (x) {
- throw new Error('tag ' + tagToken.raw + ' not closed');
- });
+ var p = [];
+ var stream = liquid.parser.parseStream(remainTokens).on('tag:when', function (token) {
+ _this.cases.push({
+ val: token.args,
+ templates: p = []
+ });
+ }).on('tag:else', function () {
+ return p = _this.elseTemplates;
+ }).on('tag:endcase', function (token) {
+ return stream.stop();
+ }).on('template', function (tpl) {
+ return p.push(tpl);
+ }).on('end', function (x) {
+ throw new Error('tag ' + tagToken.raw + ' not closed');
+ });
- stream.start();
- },
+ stream.start();
+ },
- render: function render(scope, hash) {
- for (var i = 0; i < this.cases.length; i++) {
- var branch = this.cases[i];
- var val = Liquid.evalExp(branch.val, scope);
- var cond = Liquid.evalExp(this.cond, scope);
- if (val === cond) {
- return liquid.renderer.renderTemplates(branch.templates, scope);
- }
- }
- return liquid.renderer.renderTemplates(this.elseTemplates, scope);
+ render: function render(scope, hash) {
+ for (var i = 0; i < this.cases.length; i++) {
+ var branch = this.cases[i];
+ var val = Liquid.evalExp(branch.val, scope);
+ var cond = Liquid.evalExp(this.cond, scope);
+ if (val === cond) {
+ return liquid.renderer.renderTemplates(branch.templates, scope);
}
-
- });
+ }
+ return liquid.renderer.renderTemplates(this.elseTemplates, scope);
+ }
+ });
};
-},{"..":2,"../src/util/assert.js":16}],25:[function(require,module,exports){
+},{"..":2}],25:[function(require,module,exports){
'use strict';
module.exports = function (liquid) {
@@ -2172,52 +2144,49 @@ module.exports = function (liquid) {
var Liquid = require('..');
module.exports = function (liquid) {
- liquid.registerTag('if', {
+ liquid.registerTag('if', {
- parse: function parse(tagToken, remainTokens) {
- var _this = this;
+ parse: function parse(tagToken, remainTokens) {
+ var _this = this;
- this.branches = [];
- this.elseTemplates = [];
+ this.branches = [];
+ this.elseTemplates = [];
- var p,
- stream = liquid.parser.parseStream(remainTokens).on('start', function (x) {
- return _this.branches.push({
- cond: tagToken.args,
- templates: p = []
- });
- }).on('tag:elsif', function (token) {
- if (!_this.branches[token.args]) {
- _this.branches.push({
- cond: token.args,
- templates: p = []
- });
- }
- }).on('tag:else', function (token) {
- return p = _this.elseTemplates;
- }).on('tag:endif', function (token) {
- return stream.stop();
- }).on('template', function (tpl) {
- return p.push(tpl);
- }).on('end', function (x) {
- throw new Error('tag ' + tagToken.raw + ' not closed');
- });
+ var p;
+ var stream = liquid.parser.parseStream(remainTokens).on('start', function () {
+ return _this.branches.push({
+ cond: tagToken.args,
+ templates: p = []
+ });
+ }).on('tag:elsif', function (token) {
+ _this.branches.push({
+ cond: token.args,
+ templates: p = []
+ });
+ }).on('tag:else', function () {
+ return p = _this.elseTemplates;
+ }).on('tag:endif', function (token) {
+ return stream.stop();
+ }).on('template', function (tpl) {
+ return p.push(tpl);
+ }).on('end', function (x) {
+ throw new Error('tag ' + tagToken.raw + ' not closed');
+ });
- stream.start();
- },
+ stream.start();
+ },
- render: function render(scope, hash) {
- for (var i = 0; i < this.branches.length; i++) {
- var branch = this.branches[i];
- var cond = Liquid.evalExp(branch.cond, scope);
- if (Liquid.isTruthy(cond)) {
- return liquid.renderer.renderTemplates(branch.templates, scope);
- }
- }
- return liquid.renderer.renderTemplates(this.elseTemplates, scope);
+ render: function render(scope, hash) {
+ for (var i = 0; i < this.branches.length; i++) {
+ var branch = this.branches[i];
+ var cond = Liquid.evalExp(branch.cond, scope);
+ if (Liquid.isTruthy(cond)) {
+ return liquid.renderer.renderTemplates(branch.templates, scope);
}
-
- });
+ }
+ return liquid.renderer.renderTemplates(this.elseTemplates, scope);
+ }
+ });
};
},{"..":2}],30:[function(require,module,exports){
@@ -2420,105 +2389,91 @@ module.exports = function (liquid) {
'use strict';
var Liquid = require('..');
-var Promise = require('any-promise');
+var mapSeries = require('../src/util/promise.js').mapSeries;
var lexical = Liquid.lexical;
var assert = require('../src/util/assert.js');
var re = new RegExp('^(' + lexical.identifier.source + ')\\s+in\\s+' + ('(' + lexical.value.source + ')') + ('(?:\\s+' + lexical.hash.source + ')*$'));
module.exports = function (liquid) {
- liquid.registerTag('tablerow', {
+ liquid.registerTag('tablerow', {
- parse: function parse(tagToken, remainTokens) {
- var _this = this;
+ parse: function parse(tagToken, remainTokens) {
+ var _this = this;
- var match = re.exec(tagToken.args);
- assert(match, 'illegal tag: ' + tagToken.raw);
- this.variable = match[1];
- this.collection = match[2];
+ var match = re.exec(tagToken.args);
+ assert(match, 'illegal tag: ' + tagToken.raw);
- this.templates = [];
+ this.variable = match[1];
+ this.collection = match[2];
+ this.templates = [];
- var p,
- stream = liquid.parser.parseStream(remainTokens).on('start', function (x) {
- return p = _this.templates;
- }).on('tag:endtablerow', function (token) {
- return stream.stop();
- }).on('template', function (tpl) {
- return p.push(tpl);
- }).on('end', function (x) {
- throw new Error('tag ' + tagToken.raw + ' not closed');
- });
+ var p;
+ var stream = liquid.parser.parseStream(remainTokens).on('start', function () {
+ return p = _this.templates;
+ }).on('tag:endtablerow', function (token) {
+ return stream.stop();
+ }).on('template', function (tpl) {
+ return p.push(tpl);
+ }).on('end', function () {
+ throw new Error('tag ' + tagToken.raw + ' not closed');
+ });
- stream.start();
- },
+ stream.start();
+ },
- render: function render(scope, hash) {
- var _this2 = this;
+ render: function render(scope, hash) {
+ var _this2 = this;
- var collection = Liquid.evalExp(this.collection, scope) || [];
+ var collection = Liquid.evalExp(this.collection, scope) || [];
- var html = '
';
- var offset = hash.offset || 0;
- var limit = hash.limit === undefined ? collection.length : hash.limit;
+ var html = '';
+ var offset = hash.offset || 0;
+ var limit = hash.limit === undefined ? collection.length : hash.limit;
- var cols = hash.cols,
- row,
- col;
- if (!cols) throw new Error('illegal cols: ' + cols);
+ var cols = hash.cols;
+ var row;
+ var col;
+ if (!cols) throw new Error('illegal cols: ' + cols);
- // build array of arguments to pass to sequential promises...
- collection = collection.slice(offset, offset + limit);
- var contexts = [];
- collection.some(function (item, i) {
- var ctx = {};
- ctx[_this2.variable] = item;
- // We are just putting together an array of the arguments we will be passing to our sequential promises
- contexts.push(ctx);
- });
+ // build array of arguments to pass to sequential promises...
+ collection = collection.slice(offset, offset + limit);
+ var contexts = [];
+ collection.some(function (item, i) {
+ var ctx = {};
+ ctx[_this2.variable] = item;
+ contexts.push(ctx);
+ });
- // This executes an array of promises sequentially for every argument in the contexts array - http://webcache.googleusercontent.com/search?q=cache:rNbMUn9TPtkJ:joost.vunderink.net/blog/2014/12/15/processing-an-array-of-promises-sequentially-in-node-js/+&cd=5&hl=en&ct=clnk&gl=us
- // It's fundamentally equivalent to the following...
- // emptyPromise.then(renderTemplates(args0).then(renderTemplates(args1).then(renderTemplates(args2)...
- var lastPromise = contexts.reduce(function (promise, context, currentIndex) {
- return promise.then(function (partial) {
- row = Math.floor(currentIndex / cols) + 1;
- col = currentIndex % cols + 1;
- if (col === 1) {
- if (row !== 1) {
- html += '';
- }
- html += '';
- }
-
- //ctx[this.variable] = context;
-
- return html += '| ';
- }).then(function (partial) {
- scope.push(context);
- return liquid.renderer.renderTemplates(_this2.templates, scope);
- }).then(function (partial) {
- scope.pop(context);
- html += partial;
- return html += ' | ';
- });
- }, Promise.resolve('')); // start the reduce chain with a resolved Promise. After first run, the "promise" argument
- // in our reduce callback will be the returned promise from our "then" above. In this
- // case, the promise returned from liquid.renderer.renderTemplates.
-
- return lastPromise.then(function () {
- if (row > 0) {
- html += '
';
- }
- html += '
';
- return html;
- }).catch(function (error) {
- throw error;
- });
+ return mapSeries(contexts, function (context, idx) {
+ row = Math.floor(idx / cols) + 1;
+ col = idx % cols + 1;
+ if (col === 1) {
+ if (row !== 1) {
+ html += '';
+ }
+ html += '';
}
- });
+
+ html += '| ';
+ scope.push(context);
+ return liquid.renderer.renderTemplates(_this2.templates, scope).then(function (partial) {
+ scope.pop(context);
+ html += partial;
+ html += ' | ';
+ return html;
+ });
+ }).then(function () {
+ if (row > 0) {
+ html += '
';
+ }
+ html += '
';
+ return html;
+ });
+ }
+ });
};
-},{"..":2,"../src/util/assert.js":16,"any-promise":3}],36:[function(require,module,exports){
+},{"..":2,"../src/util/assert.js":16,"../src/util/promise.js":19}],36:[function(require,module,exports){
'use strict';
var Liquid = require('..');
diff --git a/dist/liquid.min.js b/dist/liquid.min.js
index 8c3ef0567..c88042980 100644
--- a/dist/liquid.min.js
+++ b/dist/liquid.min.js
@@ -1 +1 @@
-!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Liquid=e()}}(function(){return function e(t,r,n){function s(o,u){if(!r[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var l=r[o]={exports:{}};t[o][0].call(l.exports,function(e){var r=t[o][1][e];return s(r||e)},l,l.exports,e,t,r,n)}return r[o].exports}for(var i="function"==typeof require&&require,o=0;o|"|'/g,function(e){return h[e]})}function s(e){return u(e).replace(/&(amp|lt|gt|#34|#39);/g,function(e){return g[e]})}function i(e){var t=(e+"").split(".");return t.length>1?t[1].length:0}function o(e,t){return Math.max(i(e),i(t))}function u(e){return(e=e||"")+""}function a(e){return function(t,r){var n=o(t,r);return e(t,r).toFixed(n)}}function c(e){return f.forOwn(d,function(t,r){return e.registerFilter(r,t)})}var l=e("./src/util/strftime.js"),f=e("./src/util/underscore.js"),p=e("./src/syntax.js").isTruthy,h={"&":"&","<":"<",">":">",'"':""","'":"'"},g={"&":"&","<":"<",">":">",""":'"',"'":"'"},d={abs:function(e){return Math.abs(e)},append:function(e,t){return e+t},capitalize:function(e){return u(e).charAt(0).toUpperCase()+e.slice(1)},ceil:function(e){return Math.ceil(e)},date:function(e,t){return"now"===e&&(e=new Date),e instanceof Date?l(e,t):""},default:function(e,t){return p(e)?e:t},divided_by:function(e,t){return Math.floor(e/t)},downcase:function(e){return e.toLowerCase()},escape:n,escape_once:function(e){return n(s(e))},first:function(e){return e[0]},floor:function(e){return Math.floor(e)},join:function(e,t){return e.join(t)},last:function(e){return e[e.length-1]},lstrip:function(e){return u(e).replace(/^\s+/,"")},map:function(e,t){return e.map(function(e){return e[t]})},minus:a(function(e,t){return e-t}),modulo:a(function(e,t){return e%t}),newline_to_br:function(e){return e.replace(/\n/g,"
")},plus:a(function(e,t){return Number(e)+Number(t)}),prepend:function(e,t){return t+e},remove:function(e,t){return e.split(t).join("")},remove_first:function(e,t){return e.replace(t,"")},replace:function(e,t,r){return u(e).split(t).join(r)},replace_first:function(e,t,r){return u(e).replace(t,r)},reverse:function(e){return e.reverse()},round:function(e,t){var r=Math.pow(10,t||0);return Math.round(e*r,t)/r},rstrip:function(e){return u(e).replace(/\s+$/,"")},size:function(e){return e.length},slice:function(e,t,r){return e.substr(t,void 0===r?1:r)},sort:function(e,t){return e.sort(t)},split:function(e,t){return u(e).split(t)},strip:function(e){return u(e).trim()},strip_html:function(e){return u(e).replace(/<\/?\s*\w+\s*\/?>/g,"")},strip_newlines:function(e){return u(e).replace(/\n/g,"")},times:function(e,t){return e*t},truncate:function(e,t,r){return e=u(e),r=void 0===r?"...":r,t=t||16,e.length<=t?e:e.substr(0,t-r.length)+r},truncatewords:function(e,t,r){void 0===r&&(r="...");var n=e.split(" "),s=n.slice(0,t).join(" ");return n.length>t&&(s+=r),s},uniq:function(e){var t={};return(e||[]).filter(function(e){return!t.hasOwnProperty(e)&&(t[e]=!0,!0)})},upcase:function(e){return u(e).toUpperCase()},url_encode:encodeURIComponent};c.filters=d,t.exports=c},{"./src/syntax.js":13,"./src/util/strftime.js":20,"./src/util/underscore.js":21}],2:[function(e,t,r){"use strict";function n(e){(e=o.assign({root:["."],cache:!1,extname:".liquid",trim_right:!1,trim_left:!1,strict_filters:!1,strict_variables:!1},e)).root=s(e.root);var t=Object.create(E);return t.init(g(),d(e),e),t}function s(e){return Array.isArray(e)?e:o.isString(e)?[e]:[]}var i=e("./src/scope"),o=e("./src/util/underscore.js"),u=e("./src/util/assert.js"),a=e("./src/tokenizer.js"),c=e("./src/util/fs.js").statFileAsync,l=e("./src/util/fs.js").readFileAsync,f=e("path"),p=e("./src/render.js"),h=e("./src/lexical.js"),g=e("./src/tag.js"),d=e("./src/filter.js"),v=e("./src/parser"),m=e("./src/syntax.js"),y=e("./tags"),j=e("./filters"),w=e("any-promise"),x=e("./src/util/promise.js").anySeries,b=e("./src/util/error.js"),E={init:function(e,t,r){return r.cache&&(this.cache={}),this.options=r,this.tag=e,this.filter=t,this.parser=v(e,t),this.renderer=p(),y(this),j(this),this},parse:function(e,t){var r=a.parse(e,t,this.options);return this.parser.parse(r)},render:function(e,t,r){r=o.assign({},this.options,r);var n=i.factory(t,r);return this.renderer.renderTemplates(e,n)},parseAndRender:function(e,t,r){var n=this;return w.resolve().then(function(){return n.parse(e)}).then(function(e){return n.render(e,t,r)}).catch(function(e){if(e instanceof b.RenderBreakError)return e.html;throw e})},renderFile:function(e,t,r){var n=this;return r=o.assign({},r),this.getTemplate(e,r.root).then(function(e){return n.render(e,t,r)})},evalOutput:function(e,t){var r=this.parser.parseOutput(e.trim());return this.renderer.evalOutput(r,t)},registerFilter:function(e,t){return this.filter.register(e,t)},registerTag:function(e,t){return this.tag.register(e,t)},lookup:function(e,t){t=this.options.root.concat(t||[]);var r=(t=o.uniq(t)).map(function(t){return f.resolve(t,e)});return x(r,function(e){return c(e).then(function(){return e})}).catch(function(r){throw"ENOENT"===r.code&&(r.message="Failed to lookup "+e+" in: "+t),r})},getTemplate:function(e,t){var r=this;return f.extname(e)||(e+=this.options.extname),this.lookup(e,t).then(function(e){if(r.options.cache){var t=r.cache[e];return t?w.resolve(t):l(e).then(function(e){return r.parse(e)}).then(function(t){return r.cache[e]=t})}return l(e).then(function(t){return r.parse(t,e)})})},express:function(e){e=e||{};var t=this;return function(r,n,s){u(Array.isArray(this.root)||o.isString(this.root),"illegal views root, are you using express.js?"),e.root=this.root,t.renderFile(r,n,e).then(function(e){return s(null,e)}).catch(function(e){return s(e)})}}};n.lexical=h,n.isTruthy=m.isTruthy,n.isFalsy=m.isFalsy,n.evalExp=m.evalExp,n.evalValue=m.evalValue,n.Types={ParseError:b.ParseError,TokenizationEroor:b.TokenizationError,RenderBreakError:b.RenderBreakError,AssertionError:b.AssertionError},t.exports=n},{"./filters":1,"./src/filter.js":7,"./src/lexical.js":8,"./src/parser":10,"./src/render.js":11,"./src/scope":12,"./src/syntax.js":13,"./src/tag.js":14,"./src/tokenizer.js":15,"./src/util/assert.js":16,"./src/util/error.js":17,"./src/util/fs.js":18,"./src/util/promise.js":19,"./src/util/underscore.js":21,"./tags":32,"any-promise":3,path:6}],3:[function(e,t,r){"use strict";t.exports=e("./register")().Promise},{"./register":5}],4:[function(e,t,r){"use strict";var n=null;t.exports=function(e,t){return function(r,s){r=r||null;var i=!1!==(s=s||{}).global;if(null===n&&i&&(n=e["@@any-promise/REGISTRATION"]||null),null!==n&&null!==r&&n.implementation!==r)throw new Error('any-promise already defined as "'+n.implementation+'". You can only register an implementation before the first call to require("any-promise") and an implementation cannot be changed');return null===n&&(n=null!==r&&void 0!==s.Promise?{Promise:s.Promise,implementation:r}:t(r),i&&(e["@@any-promise/REGISTRATION"]=n)),n}}},{}],5:[function(e,t,r){"use strict";t.exports=e("./loader")(window,function(){if(void 0===window.Promise)throw new Error("any-promise browser requires a polyfill or explicit registration e.g: require('any-promise/register/bluebird')");return{Promise:window.Promise,implementation:"window.Promise"}})},{"./loader":4}],6:[function(e,t,r){"use strict"},{}],7:[function(e,t,r){"use strict";var n=e("./lexical.js"),s=e("./syntax.js"),i=e("./util/assert.js"),o=e("./util/underscore.js"),u=new RegExp(""+n.value.source,"g");t.exports=function(e){e=o.assign({},e);var t={},r={render:function(e,t){var r=this.args.map(function(e){return s.evalValue(e,t)});return r.unshift(e),this.filter.apply(null,r)},parse:function(r){var s=n.filterLine.exec(r);i(s,"illegal filter: "+r);var o=s[1],a=s[2]||"",c=t[o];if("function"!=typeof c){if(e.strict_filters)throw new TypeError("undefined filter: "+o);return this.name=o,this.filter=function(e){return e},this.args=[],this}for(var l=[];s=u.exec(a.trim());){var f=s[0];new RegExp(f+"\\s*:","g").test(s.input)?l.push("'"+f+"'"):l.push(f)}return this.name=o,this.filter=c,this.args=l,this}};return{construct:function(e){return Object.create(r).parse(e)},register:function(e,r){t[e]=r},clear:function(){t={}}}}},{"./lexical.js":8,"./syntax.js":13,"./util/assert.js":16,"./util/underscore.js":21}],8:[function(e,t,r){"use strict";var n=/'[^']*'/,s=/"[^"]*"/,i=new RegExp(n.source+"|"+s.source),o=new RegExp("(?:"+i.source+"|[^'\"])*"),u=/-?\d+/,a=/-?\d+\.?\d*|\.?\d+/,c=/true|false/,l=/[\w-]+/,f=new RegExp("\\[(?:"+i.source+"|[\\w-\\.]+)\\]"),p=new RegExp("(?:"+i.source+"|"+c.source+"|"+a.source+")"),h=new RegExp(l.source+"(?:\\."+l.source+"|"+f.source+")*"),g=new RegExp("(?:"+h.source+"|"+a.source+")"),d=new RegExp("\\("+g.source+"\\.\\."+g.source+"\\)"),v=new RegExp("\\(("+g.source+")\\.\\.("+g.source+")\\)"),m=new RegExp("(?:"+h.source+"|"+p.source+"|"+d.source+")"),y=new RegExp("(?:"+l.source+")\\s*:\\s*(?:"+m.source+")"),j=new RegExp("("+l.source+")\\s*:\\s*("+m.source+")","g"),w=new RegExp("^\\s*("+l.source+")\\s*([\\s\\S]*)\\s*$"),x=new RegExp("^"+p.source+"$","i"),b=new RegExp("^"+h.source+"$"),E=new RegExp("^"+a.source+"$"),T=new RegExp("^"+c.source+"$","i"),k=new RegExp("^"+i.source+"$"),S=new RegExp("^"+v.source+"$"),R=new RegExp("^"+u.source+"$"),O=new RegExp("(?:"+l.source+"\\s*:\\s*)?"+m.source),A=new RegExp(O.source+"(\\s*,\\s*"+O.source+")*"),M=new RegExp(l.source+"(?:\\s*:\\s*"+A.source+")?","g"),P=new RegExp("("+l.source+")(?:\\s*:\\s*("+A.source+"))?"),q=new RegExp("^"+P.source+"$"),L=[/\s+or\s+/,/\s+and\s+/,/==|!=|<=|>=|<|>|\s+contains\s+/];t.exports={quoted:i,number:a,bool:c,literal:p,filter:M,integer:u,hash:y,hashCapture:j,range:d,rangeCapture:v,identifier:l,value:m,quoteBalanced:o,operators:L,quotedLine:k,numberLine:E,boolLine:T,rangeLine:S,literalLine:x,filterLine:q,tagLine:w,isLiteral:function(e){return x.test(e)},isVariable:function(e){return b.test(e)},parseLiteral:function(e){var t=e.match(E);return t?Number(e):(t=e.match(T))?"true"===e.toLowerCase():(t=e.match(k))?e.slice(1,-1):void 0},isRange:function(e){return S.test(e)},matchValue:function(e){return m.exec(e)},isInteger:function(e){return R.test(e)}}},{}],9:[function(e,t,r){"use strict";var n={"==":function(e,t){return e===t},"!=":function(e,t){return e!==t},">":function(e,t){return null!==e&&null!==t&&e>t},"<":function(e,t){return null!==e&&null!==t&&e=":function(e,t){return null!==e&&null!==t&&e>=t},"<=":function(e,t){return null!==e&&null!==t&&e<=t},contains:function(e,t){return!!e&&("function"==typeof e.indexOf&&e.indexOf(t)>-1)},and:function(e,t){return e&&t},or:function(e,t){return e||t}};t.exports=n},{}],10:[function(e,t,r){"use strict";var n=e("./lexical.js"),s=e("./util/error.js").ParseError,i=e("./util/assert.js");t.exports=function(e,t){function r(e,t){try{var r=null;return r="tag"===e.type?o(e,t):"output"===e.type?u(e.value):e,r.token=e,r}catch(t){throw new s(t,e)}}function o(t,r){return"continue"===t.name||"break"===t.name?t:e.construct(t,r)}function u(e){var r=n.matchValue(e);i(r,"illegal output string: "+e);var s=r[0];e=e.substr(r.index+r[0].length);for(var o=[];r=n.filter.exec(e);)o.push([r[0].trim()]);return{type:"output",initial:s,filters:o.map(function(e){return t.construct(e)})}}var a={init:function(e){return this.tokens=e,this.handlers={},this},on:function(e,t){return this.handlers[e]=t,this},trigger:function(e,t){var r=this.handlers[e];if("function"==typeof r)return r(t),!0},start:function(){this.trigger("start");for(var e;!this.stopRequested&&(e=this.tokens.shift());)if(!(this.trigger("token",e)||"tag"===e.type&&this.trigger("tag:"+e.name,e))){var t=r(e,this.tokens);this.trigger("template",t)}return this.stopRequested||this.trigger("end"),this},stop:function(){return this.stopRequested=!0,this}};return{parse:function(e){for(var t,n=[];t=e.shift();)n.push(r(t,e));return n},parseTag:o,parseStream:function(e){return Object.create(a).init(e)},parseOutput:u}}},{"./lexical.js":8,"./util/assert.js":16,"./util/error.js":17}],11:[function(e,t,r){"use strict";function n(e){return"string"==typeof e?e:JSON.stringify(e)}var s=e("./syntax.js"),i=e("any-promise"),o=e("./util/promise.js").mapSeries,u=e("./util/error.js").RenderBreakError,a=e("./util/error.js").RenderError,c=e("./util/assert.js"),l={renderTemplates:function(e,t){function r(e){var r=this;return"tag"===e.type?this.renderTag(e,t).then(function(e){return void 0===e?"":e}):"output"===e.type?i.resolve().then(function(){return r.evalOutput(e,t)}).then(function(e){return void 0===e?"":n(e)}):i.resolve(e.value)}var s=this;c(t,"unable to evalTemplates: scope undefined");var l="";return o(e,function(e){return r.call(s,e).then(function(e){return l+=e}).catch(function(t){if(t instanceof u)throw t.resolvedHTML=l,t;throw new a(t,e)})}).then(function(){return l})},renderTag:function(e,t){return"continue"===e.name?i.reject(new u("continue")):"break"===e.name?i.reject(new u("break")):e.render(t)},evalOutput:function(e,t){return c(t,"unable to evalOutput: scope undefined"),e.filters.reduce(function(e,r){return r.render(e,t)},s.evalExp(e.initial,t))}};t.exports=function(){return Object.create(l)}},{"./syntax.js":13,"./util/assert.js":16,"./util/error.js":17,"./util/promise.js":19,"any-promise":3}],12:[function(e,t,r){"use strict";function n(e,t){for(var r=1,n=t;n=0;t--)s.assign(e,this.scopes[t]);return e},get:function(e){for(var t=this.scopes.length-1;t>=0;t--)try{return this.getPropertyByPath(this.scopes[t],e)}catch(t){if(/undefined variable/.test(t.message))continue;if(/Cannot read property/.test(t.message)){if(this.opts.strict_variables)throw t.message+=": "+e,t;continue}throw t.message+=": "+e,t}if(this.opts.strict_variables)throw new TypeError("undefined variable: "+e)},set:function(e,t){return this.setPropertyByPath(this.scopes[this.scopes.length-1],e,t),this},push:function(e){return o(e,"trying to push "+e+" into scopes"),this.scopes.push(e)},pop:function(){return this.scopes.pop()},unshift:function(e){return o(e,"trying to push "+e+" into scopes"),this.scopes.unshift(e)},shift:function(){return this.scopes.shift()},setPropertyByPath:function(e,t,r){if(s.isString(t))for(var n=t.replace(/\[/g,".").replace(/\]/g,"").split("."),i=0;id&&(f=e.slice(d,l.index),h.push({type:"html",raw:f,value:f})),l[1]){var y=(p=a("tag",1,l)).value.match(s.tagLine);if(!y)throw new i("illegal tag syntax",p);p.name=y[1],p.args=y[2];var j=(f||"").split("\n");p.indent=j[j.length-1].length,h.push(p)}else p=a("output",3,l),h.push(p);d=g.lastIndex}return e.length>d&&(f=e.slice(d,e.length),h.push({type:"html",raw:f,value:f})),h},r.whiteSpaceCtrl=n},{"../src/util/assert.js":16,"./lexical.js":8,"./util/error.js":17,"./util/underscore.js":21}],16:[function(e,t,r){"use strict";var n=e("./error.js").AssertionError;t.exports=function(e,t){if(!e){if(t instanceof Error)throw t;throw t=t||"expect "+e+" to be true",new n(t)}}},{"./error.js":17}],17:[function(e,t,r){"use strict";function n(e,t){Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.input=t.input,this.line=t.line,this.file=t.file;var r=a(t.input,t.line);this.message=l(e,t),this.stack=r+"\n"+(this.stack||"")}function s(e,t){f.assign(this,e),this.originalError=e,this.name=this.constructor.name,this.input=t.input,this.line=t.line,this.file=t.file;var r=a(t.input,t.line);this.message=l(e.message||"Unkown Error",t),this.stack=r+"\n"+(e.stack||"")}function i(e,t){if(e instanceof i)return e;f.assign(this,e),this.originalError=e,this.name=this.constructor.name,this.input=t.token.input,this.line=t.token.line,this.file=t.token.file;var r=a(t.token.input,t.token.line);this.message=l(e.message||"Unkown Error",t.token),this.stack=r+"\n"+(e.stack||"")}function o(e){Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||""}function u(e){Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e}function a(e,t){var r=e.split("\n"),n=Math.max(t-2,1),s=Math.min(t+3,r.length);return f.range(n,s+1).map(function(e){return[e===t?">> ":" ",c(e,s),"| ",r[e-1]].join("")}).join("\n")}function c(e,t){var r=(t+"").length,n=e+"";return Array(r-n.length).join(" ")+n}function l(e,t){return e=e||"",t.file&&(e+=", file:"+t.file),t.line&&(e+=", line:"+t.line),e}var f=e("./underscore.js");(n.prototype=Object.create(Error.prototype)).constructor=n,(s.prototype=Object.create(Error.prototype)).constructor=s,i.prototype=Object.create(Error.prototype),i.prototype.constructor=i,(o.prototype=Object.create(Error.prototype)).constructor=o,(u.prototype=Object.create(Error.prototype)).constructor=u,t.exports={TokenizationError:n,ParseError:s,RenderBreakError:o,AssertionError:u,RenderError:i}},{"./underscore.js":21}],18:[function(e,t,r){"use strict";var n=e("fs");t.exports={readFileAsync:function(e){return new Promise(function(t,r){n.readFile(e,"utf8",function(e,n){e?r(e):t(n)})})},statFileAsync:function(e){return new Promise(function(t,r){n.stat(e,function(e,n){return e?r(e):t(n)})})}}},{fs:6}],19:[function(e,t,r){"use strict";var n=e("any-promise");r.anySeries=function(e,t){var r=n.reject(new Error("init"));return e.forEach(function(n,s){r=r.catch(function(r){return t(n,s,e)})}),r},r.mapSeries=function(e,t){var r=n.resolve("init"),s=[];return e.forEach(function(n,i){r=r.then(function(){return t(n,i,e)}).then(function(e){return s.push(e)})}),r.then(function(){return s})}},{"any-promise":3}],20:[function(e,t,r){"use strict";var n=["January","February","March","April","May","June","July","August","September","October","November","December"],s=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],i=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],o=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],u={1:"st",2:"nd",3:"rd",default:"th"},a={daysInMonth:function(e){return[31,a.isLeapYear(e)?29:28,31,30,31,30,31,31,30,31,30,31]},getDayOfYear:function(e){for(var t=0,r=0;r0;)n=r+n;return n}},l={a:function(e){return o[e.getDay()]},A:function(e){return i[e.getDay()]},b:function(e){return s[e.getMonth()]},B:function(e){return n[e.getMonth()]},c:function(e){return e.toLocaleString()},C:function(e){return a.century(e)},d:function(e){return c.pad(e.getDate(),2)},e:function(e){return c.pad(e.getDate(),2," ")},H:function(e){return c.pad(e.getHours(),2)},I:function(e){return c.pad(e.getHours()%12||12,2)},j:function(e){return c.pad(a.getDayOfYear(e),3)},k:function(e){return c.pad(e.getHours(),2," ")},l:function(e){return c.pad(e.getHours()%12||12,2," ")},L:function(e){return c.pad(e.getMilliseconds(),3)},m:function(e){return c.pad(e.getMonth()+1,2)},M:function(e){return c.pad(e.getMinutes(),2)},p:function(e){return e.getHours()<12?"AM":"PM"},P:function(e){return e.getHours()<12?"am":"pm"},q:function(e){return a.getSuffix(e)},s:function(e){return Math.round(e.valueOf()/1e3)},S:function(e){return c.pad(e.getSeconds(),2)},u:function(e){return e.getDay()||7},U:function(e){return a.getWeekOfYear(e,0)},w:function(e){return e.getDay()},W:function(e){return a.getWeekOfYear(e,1)},x:function(e){return e.toLocaleDateString()},X:function(e){return e.toLocaleTimeString()},y:function(e){return e.getFullYear().toString().substring(2,4)},Y:function(e){return e.getFullYear()},z:function(e){var t=e.getTimezoneOffset()/60*100;return(t>0?"-":"+")+c.pad(Math.abs(t),4)},"%":function(){return"%"}};l.h=l.b,l.N=l.L;t.exports=function(e,t){for(var r="",n=t;;){var s=/%./g,i=s.exec(n);if(!i)return r+n;r+=n.slice(0,s.lastIndex-2),n=n.slice(s.lastIndex);var o=i[0].charAt(1),u=l[o];r+=u?u.call(this,e):"%"+o}}},{}],21:[function(e,t,r){"use strict";function n(e,t){e=e||{};for(var r in e)if(e.hasOwnProperty(r)&&!1===t(e[r],r,e))break;return e}function s(e,t){return e?(n(t,function(t,r){e[r]=t}),e):e}function i(e){var t=void 0===e?"undefined":o(e);return null!=e&&("object"===t||"function"===t)}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};r.isString=function(e){return e instanceof String||"string"==typeof e},r.isObject=i,r.isError=function(e){return"Error"===Object.prototype.toString.call(e).substr(-6,5)||"string"==typeof e.message&&"string"==typeof e.name},r.range=function(e,t,r){1===arguments.length&&(t=e,e=0),r=r||1;for(var n=[],s=e;s0?a=[a]:o.isObject(a)&&(a=Object.keys(a))),!Array.isArray(a)||!a.length)return e.renderer.renderTemplates(this.elseTemplates,t);var c=a.length,l=r.offset||0,f=void 0===r.limit?a.length:r.limit;a=a.slice(l,l+f),this.reversed&&a.reverse();var p=a.map(function(e,t){var r={};return r[s.variable]=e,r.forloop={first:0===t,index:t+1,index0:t,last:t===c-1,length:c,rindex:c-t,rindex0:c-t-1},r}),h="";return i(p,function(r){return t.push(r),e.renderer.renderTemplates(s.templates,t).then(function(e){return h+=e}).catch(function(e){if(!(e instanceof u&&(h+=e.resolvedHTML,"continue"===e.message)))throw e}).then(function(){return t.pop()})}).catch(function(e){if(!(e instanceof u&&"break"===e.message))throw e}).then(function(){return h})}})}},{"..":2,"../src/util/assert.js":16,"../src/util/promise.js":19,"../src/util/underscore.js":21}],29:[function(e,t,r){"use strict";var n=e("..");t.exports=function(e){e.registerTag("if",{parse:function(t,r){var n=this;this.branches=[],this.elseTemplates=[];var s,i=e.parser.parseStream(r).on("start",function(e){return n.branches.push({cond:t.args,templates:s=[]})}).on("tag:elsif",function(e){n.branches[e.args]||n.branches.push({cond:e.args,templates:s=[]})}).on("tag:else",function(e){return s=n.elseTemplates}).on("tag:endif",function(e){return i.stop()}).on("template",function(e){return s.push(e)}).on("end",function(e){throw new Error("tag "+t.raw+" not closed")});i.start()},render:function(t,r){for(var s=0;s",l=r.offset||0,f=void 0===r.limit?a.length:r.limit,p=r.cols;if(!p)throw new Error("illegal cols: "+p);var h=[];return(a=a.slice(l,l+f)).some(function(e,t){var r={};r[u.variable]=e,h.push(r)}),h.reduce(function(r,n,s){return r.then(function(e){return i=Math.floor(s/p)+1,1===(o=s%p+1)&&(1!==i&&(c+=""),c+=''),c+='| '}).then(function(r){return t.push(n),e.renderer.renderTemplates(u.templates,t)}).then(function(e){return t.pop(n),c+=e,c+=" | "})},s.resolve("")).then(function(){return i>0&&(c+="
"),c+=""}).catch(function(e){throw e})}})}},{"..":2,"../src/util/assert.js":16,"any-promise":3}],36:[function(e,t,r){"use strict";var n=e("..");t.exports=function(e){e.registerTag("unless",{parse:function(t,r){var n=this;this.templates=[],this.elseTemplates=[];var s,i=e.parser.parseStream(r).on("start",function(e){s=n.templates,n.cond=t.args}).on("tag:else",function(e){return s=n.elseTemplates}).on("tag:endunless",function(e){return i.stop()}).on("template",function(e){return s.push(e)}).on("end",function(e){throw new Error("tag "+t.raw+" not closed")});i.start()},render:function(t,r){var s=n.evalExp(this.cond,t);return n.isFalsy(s)?e.renderer.renderTemplates(this.templates,t):e.renderer.renderTemplates(this.elseTemplates,t)}})}},{"..":2}]},{},[2])(2)});
\ No newline at end of file
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Liquid=e()}}(function(){return function e(r,t,n){function s(o,u){if(!t[o]){if(!r[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var l=t[o]={exports:{}};r[o][0].call(l.exports,function(e){var t=r[o][1][e];return s(t||e)},l,l.exports,e,r,t,n)}return t[o].exports}for(var i="function"==typeof require&&require,o=0;o|"|'/g,function(e){return h[e]})}function s(e){return u(e).replace(/&(amp|lt|gt|#34|#39);/g,function(e){return g[e]})}function i(e){var r=(e+"").split(".");return r.length>1?r[1].length:0}function o(e,r){return Math.max(i(e),i(r))}function u(e){return e+""}function a(e){return function(r,t){var n=o(r,t);return e(r,t).toFixed(n)}}function c(e){return f.forOwn(d,function(r,t){return e.registerFilter(t,r)})}var l=e("./src/util/strftime.js"),f=e("./src/util/underscore.js"),p=e("./src/syntax.js").isTruthy,h={"&":"&","<":"<",">":">",'"':""","'":"'"},g={"&":"&","<":"<",">":">",""":'"',"'":"'"},d={abs:function(e){return Math.abs(e)},append:function(e,r){return e+r},capitalize:function(e){return u(e).charAt(0).toUpperCase()+e.slice(1)},ceil:function(e){return Math.ceil(e)},date:function(e,r){return"now"===e&&(e=new Date),e instanceof Date?l(e,r):""},default:function(e,r){return p(e)?e:r},divided_by:function(e,r){return Math.floor(e/r)},downcase:function(e){return e.toLowerCase()},escape:n,escape_once:function(e){return n(s(e))},first:function(e){return e[0]},floor:function(e){return Math.floor(e)},join:function(e,r){return e.join(r)},last:function(e){return e[e.length-1]},lstrip:function(e){return u(e).replace(/^\s+/,"")},map:function(e,r){return e.map(function(e){return e[r]})},minus:a(function(e,r){return e-r}),modulo:a(function(e,r){return e%r}),newline_to_br:function(e){return e.replace(/\n/g,"
")},plus:a(function(e,r){return Number(e)+Number(r)}),prepend:function(e,r){return r+e},remove:function(e,r){return e.split(r).join("")},remove_first:function(e,r){return e.replace(r,"")},replace:function(e,r,t){return u(e).split(r).join(t)},replace_first:function(e,r,t){return u(e).replace(r,t)},reverse:function(e){return e.reverse()},round:function(e,r){var t=Math.pow(10,r||0);return Math.round(e*t,r)/t},rstrip:function(e){return u(e).replace(/\s+$/,"")},size:function(e){return e.length},slice:function(e,r,t){return e.substr(r,void 0===t?1:t)},sort:function(e,r){return e.sort(r)},split:function(e,r){return u(e).split(r)},strip:function(e){return u(e).trim()},strip_html:function(e){return u(e).replace(/<\/?\s*\w+\s*\/?>/g,"")},strip_newlines:function(e){return u(e).replace(/\n/g,"")},times:function(e,r){return e*r},truncate:function(e,r,t){return e=u(e),t=void 0===t?"...":t,r=r||16,e.length<=r?e:e.substr(0,r-t.length)+t},truncatewords:function(e,r,t){void 0===t&&(t="...");var n=e.split(" "),s=n.slice(0,r).join(" ");return n.length>r&&(s+=t),s},uniq:function(e){var r={};return(e||[]).filter(function(e){return!r.hasOwnProperty(e)&&(r[e]=!0,!0)})},upcase:function(e){return u(e).toUpperCase()},url_encode:encodeURIComponent};c.filters=d,r.exports=c},{"./src/syntax.js":13,"./src/util/strftime.js":20,"./src/util/underscore.js":21}],2:[function(e,r,t){"use strict";function n(e){(e=o.assign({root:["."],cache:!1,extname:".liquid",trim_right:!1,trim_left:!1,strict_filters:!1,strict_variables:!1},e)).root=s(e.root);var r=Object.create(E);return r.init(g(),d(e),e),r}function s(e){return Array.isArray(e)?e:o.isString(e)?[e]:[]}var i=e("./src/scope"),o=e("./src/util/underscore.js"),u=e("./src/util/assert.js"),a=e("./src/tokenizer.js"),c=e("./src/util/fs.js").statFileAsync,l=e("./src/util/fs.js").readFileAsync,f=e("path"),p=e("./src/render.js"),h=e("./src/lexical.js"),g=e("./src/tag.js"),d=e("./src/filter.js"),v=e("./src/parser"),m=e("./src/syntax.js"),y=e("./tags"),j=e("./filters"),w=e("any-promise"),x=e("./src/util/promise.js").anySeries,b=e("./src/util/error.js"),E={init:function(e,r,t){return t.cache&&(this.cache={}),this.options=t,this.tag=e,this.filter=r,this.parser=v(e,r),this.renderer=p(),y(this),j(this),this},parse:function(e,r){var t=a.parse(e,r,this.options);return this.parser.parse(t)},render:function(e,r,t){t=o.assign({},this.options,t);var n=i.factory(r,t);return this.renderer.renderTemplates(e,n)},parseAndRender:function(e,r,t){var n=this;return w.resolve().then(function(){return n.parse(e)}).then(function(e){return n.render(e,r,t)})},renderFile:function(e,r,t){var n=this;return t=o.assign({},t),this.getTemplate(e,t.root).then(function(e){return n.render(e,r,t)})},evalOutput:function(e,r){var t=this.parser.parseOutput(e.trim());return this.renderer.evalOutput(t,r)},registerFilter:function(e,r){return this.filter.register(e,r)},registerTag:function(e,r){return this.tag.register(e,r)},lookup:function(e,r){r=this.options.root.concat(r||[]);var t=(r=o.uniq(r)).map(function(r){return f.resolve(r,e)});return x(t,function(e){return c(e).then(function(){return e})}).catch(function(t){throw t.message=t.code+": Failed to lookup "+e+" in: "+r,t})},getTemplate:function(e,r){var t=this;return f.extname(e)||(e+=this.options.extname),this.lookup(e,r).then(function(e){if(t.options.cache){var r=t.cache[e];return r?w.resolve(r):l(e).then(function(e){return t.parse(e)}).then(function(r){return t.cache[e]=r})}return l(e).then(function(r){return t.parse(r,e)})})},express:function(e){e=e||{};var r=this;return function(t,n,s){u(Array.isArray(this.root)||o.isString(this.root),"illegal views root, are you using express.js?"),e.root=this.root,r.renderFile(t,n,e).then(function(e){return s(null,e)}).catch(function(e){return s(e)})}}};n.lexical=h,n.isTruthy=m.isTruthy,n.isFalsy=m.isFalsy,n.evalExp=m.evalExp,n.evalValue=m.evalValue,n.Types={ParseError:b.ParseError,TokenizationEroor:b.TokenizationError,RenderBreakError:b.RenderBreakError,AssertionError:b.AssertionError},r.exports=n},{"./filters":1,"./src/filter.js":7,"./src/lexical.js":8,"./src/parser":10,"./src/render.js":11,"./src/scope":12,"./src/syntax.js":13,"./src/tag.js":14,"./src/tokenizer.js":15,"./src/util/assert.js":16,"./src/util/error.js":17,"./src/util/fs.js":18,"./src/util/promise.js":19,"./src/util/underscore.js":21,"./tags":32,"any-promise":3,path:6}],3:[function(e,r,t){"use strict";r.exports=e("./register")().Promise},{"./register":5}],4:[function(e,r,t){"use strict";var n=null;r.exports=function(e,r){return function(t,s){t=t||null;var i=!1!==(s=s||{}).global;if(null===n&&i&&(n=e["@@any-promise/REGISTRATION"]||null),null!==n&&null!==t&&n.implementation!==t)throw new Error('any-promise already defined as "'+n.implementation+'". You can only register an implementation before the first call to require("any-promise") and an implementation cannot be changed');return null===n&&(n=null!==t&&void 0!==s.Promise?{Promise:s.Promise,implementation:t}:r(t),i&&(e["@@any-promise/REGISTRATION"]=n)),n}}},{}],5:[function(e,r,t){"use strict";r.exports=e("./loader")(window,function(){if(void 0===window.Promise)throw new Error("any-promise browser requires a polyfill or explicit registration e.g: require('any-promise/register/bluebird')");return{Promise:window.Promise,implementation:"window.Promise"}})},{"./loader":4}],6:[function(e,r,t){"use strict"},{}],7:[function(e,r,t){"use strict";var n=e("./lexical.js"),s=e("./syntax.js"),i=e("./util/assert.js"),o=e("./util/underscore.js"),u=new RegExp(""+n.value.source,"g");r.exports=function(e){e=o.assign({},e);var r={},t={render:function(e,r){var t=this.args.map(function(e){return s.evalValue(e,r)});return t.unshift(e),this.filter.apply(null,t)},parse:function(t){var s=n.filterLine.exec(t);i(s,"illegal filter: "+t);var o=s[1],a=s[2]||"",c=r[o];if("function"!=typeof c){if(e.strict_filters)throw new TypeError("undefined filter: "+o);return this.name=o,this.filter=function(e){return e},this.args=[],this}for(var l=[];s=u.exec(a.trim());){var f=s[0];new RegExp(f+"\\s*:","g").test(s.input)?l.push("'"+f+"'"):l.push(f)}return this.name=o,this.filter=c,this.args=l,this}};return{construct:function(e){return Object.create(t).parse(e)},register:function(e,t){r[e]=t},clear:function(){r={}}}}},{"./lexical.js":8,"./syntax.js":13,"./util/assert.js":16,"./util/underscore.js":21}],8:[function(e,r,t){"use strict";var n=/'[^']*'/,s=/"[^"]*"/,i=new RegExp(n.source+"|"+s.source),o=new RegExp("(?:"+i.source+"|[^'\"])*"),u=/-?\d+/,a=/-?\d+\.?\d*|\.?\d+/,c=/true|false/,l=/[\w-]+/,f=new RegExp("\\[(?:"+i.source+"|[\\w-\\.]+)\\]"),p=new RegExp("(?:"+i.source+"|"+c.source+"|"+a.source+")"),h=new RegExp(l.source+"(?:\\."+l.source+"|"+f.source+")*"),g=new RegExp("(?:"+h.source+"|"+a.source+")"),d=new RegExp("\\("+g.source+"\\.\\."+g.source+"\\)"),v=new RegExp("\\(("+g.source+")\\.\\.("+g.source+")\\)"),m=new RegExp("(?:"+h.source+"|"+p.source+"|"+d.source+")"),y=new RegExp("(?:"+l.source+")\\s*:\\s*(?:"+m.source+")"),j=new RegExp("("+l.source+")\\s*:\\s*("+m.source+")","g"),w=new RegExp("^\\s*("+l.source+")\\s*([\\s\\S]*)\\s*$"),x=new RegExp("^"+p.source+"$","i"),b=new RegExp("^"+h.source+"$"),E=new RegExp("^"+a.source+"$"),T=new RegExp("^"+c.source+"$","i"),k=new RegExp("^"+i.source+"$"),S=new RegExp("^"+v.source+"$"),R=new RegExp("^"+u.source+"$"),O=new RegExp("(?:"+l.source+"\\s*:\\s*)?"+m.source),A=new RegExp(O.source+"(\\s*,\\s*"+O.source+")*"),M=new RegExp(l.source+"(?:\\s*:\\s*"+A.source+")?","g"),q=new RegExp("("+l.source+")(?:\\s*:\\s*("+A.source+"))?"),L=new RegExp("^"+q.source+"$"),F=[/\s+or\s+/,/\s+and\s+/,/==|!=|<=|>=|<|>|\s+contains\s+/];r.exports={quoted:i,number:a,bool:c,literal:p,filter:M,integer:u,hash:y,hashCapture:j,range:d,rangeCapture:v,identifier:l,value:m,quoteBalanced:o,operators:F,quotedLine:k,numberLine:E,boolLine:T,rangeLine:S,literalLine:x,filterLine:L,tagLine:w,isLiteral:function(e){return x.test(e)},isVariable:function(e){return b.test(e)},parseLiteral:function(e){var r=e.match(E);if(r)return Number(e);if(r=e.match(T))return"true"===e.toLowerCase();if(r=e.match(k))return e.slice(1,-1);throw new TypeError("cannot parse '"+e+"' as literal")},isRange:function(e){return S.test(e)},matchValue:function(e){return m.exec(e)},isInteger:function(e){return R.test(e)}}},{}],9:[function(e,r,t){"use strict";var n={"==":function(e,r){return e===r},"!=":function(e,r){return e!==r},">":function(e,r){return null!==e&&null!==r&&e>r},"<":function(e,r){return null!==e&&null!==r&&e=":function(e,r){return null!==e&&null!==r&&e>=r},"<=":function(e,r){return null!==e&&null!==r&&e<=r},contains:function(e,r){return!!e&&("function"==typeof e.indexOf&&e.indexOf(r)>-1)},and:function(e,r){return e&&r},or:function(e,r){return e||r}};r.exports=n},{}],10:[function(e,r,t){"use strict";var n=e("./lexical.js"),s=e("./util/error.js").ParseError,i=e("./util/assert.js");r.exports=function(e,r){function t(e,r){try{var t=null;return t="tag"===e.type?o(e,r):"output"===e.type?u(e.value):e,t.token=e,t}catch(r){throw new s(r,e)}}function o(r,t){return"continue"===r.name||"break"===r.name?r:e.construct(r,t)}function u(e){var t=n.matchValue(e);i(t,"illegal output string: "+e);var s=t[0];e=e.substr(t.index+t[0].length);for(var o=[];t=n.filter.exec(e);)o.push([t[0].trim()]);return{type:"output",initial:s,filters:o.map(function(e){return r.construct(e)})}}var a={init:function(e){return this.tokens=e,this.handlers={},this},on:function(e,r){return this.handlers[e]=r,this},trigger:function(e,r){var t=this.handlers[e];if("function"==typeof t)return t(r),!0},start:function(){this.trigger("start");for(var e;!this.stopRequested&&(e=this.tokens.shift());)if(!(this.trigger("token",e)||"tag"===e.type&&this.trigger("tag:"+e.name,e))){var r=t(e,this.tokens);this.trigger("template",r)}return this.stopRequested||this.trigger("end"),this},stop:function(){return this.stopRequested=!0,this}};return{parse:function(e){for(var r,n=[];r=e.shift();)n.push(t(r,e));return n},parseTag:o,parseStream:function(e){return Object.create(a).init(e)},parseOutput:u}}},{"./lexical.js":8,"./util/assert.js":16,"./util/error.js":17}],11:[function(e,r,t){"use strict";function n(e){return"string"==typeof e?e:JSON.stringify(e)}var s=e("./syntax.js"),i=e("any-promise"),o=e("./util/promise.js").mapSeries,u=e("./util/error.js").RenderBreakError,a=e("./util/error.js").RenderError,c=e("./util/assert.js"),l={renderTemplates:function(e,r){function t(e){var t=this;return"tag"===e.type?this.renderTag(e,r).then(function(e){return void 0===e?"":e}):"output"===e.type?i.resolve().then(function(){return t.evalOutput(e,r)}).then(function(e){return void 0===e?"":n(e)}):i.resolve(e.value)}var s=this;c(r,"unable to evalTemplates: scope undefined");var l="";return o(e,function(e){return t.call(s,e).then(function(e){return l+=e}).catch(function(r){if(r instanceof u)throw r.resolvedHTML=l,r;throw new a(r,e)})}).then(function(){return l})},renderTag:function(e,r){return"continue"===e.name?i.reject(new u("continue")):"break"===e.name?i.reject(new u("break")):e.render(r)},evalOutput:function(e,r){return c(r,"unable to evalOutput: scope undefined"),e.filters.reduce(function(e,t){return t.render(e,r)},s.evalExp(e.initial,r))}};r.exports=function(){return Object.create(l)}},{"./syntax.js":13,"./util/assert.js":16,"./util/error.js":17,"./util/promise.js":19,"any-promise":3}],12:[function(e,r,t){"use strict";function n(e,r,t){for(var n=(r+"").replace(/\[/g,".").replace(/\]/g,"").split("."),s=0;s-1;t--){var n=r[t];if(n.hasOwnProperty(e))return n[e]}throw new TypeError("undefined variable: "+e)}function o(e,r){for(var t=1,n=r;n=0;r--)u.assign(e,this.scopes[r]);return e},get:function(e){try{return this.getPropertyByPath(this.scopes,e)}catch(e){if(!/undefined variable/.test(e.message)||this.opts.strict_variables)throw e}},set:function(e,r){return n(this.scopes[this.scopes.length-1],e,r),this},push:function(e){return c(e,"trying to push "+e+" into scopes"),this.scopes.push(e)},pop:function(){return this.scopes.pop()},unshift:function(e){return c(e,"trying to push "+e+" into scopes"),this.scopes.unshift(e)},shift:function(){return this.scopes.shift()},getPropertyByPath:function(e,r){var t=this.propertyAccessSeq(r+"");if(!t.length)throw new TypeError("undefined variable: "+r);var n=i(t.shift(),e);return t.reduce(function(e,r){if(u.isNil(e))throw new TypeError("undefined variable: "+r);return s(r,e)},n)},propertyAccessSeq:function(e){function r(){s.length&&n.push(s),s=""}for(var t,n=[],s="",i=0;id&&(f=e.slice(d,l.index),h.push({type:"html",raw:f,value:f})),l[1]){var y=(p=a("tag",1,l)).value.match(s.tagLine);if(!y)throw new i("illegal tag syntax",p);p.name=y[1],p.args=y[2];var j=(f||"").split("\n");p.indent=j[j.length-1].length,h.push(p)}else p=a("output",3,l),h.push(p);d=g.lastIndex}return e.length>d&&(f=e.slice(d,e.length),h.push({type:"html",raw:f,value:f})),h},t.whiteSpaceCtrl=n},{"../src/util/assert.js":16,"./lexical.js":8,"./util/error.js":17,"./util/underscore.js":21}],16:[function(e,r,t){"use strict";var n=e("./error.js").AssertionError;r.exports=function(e,r){if(!e)throw r=r||"expect "+e+" to be true",new n(r)}},{"./error.js":17}],17:[function(e,r,t){"use strict";function n(){this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}function s(e,r){n.call(this),this.input=r.input,this.line=r.line,this.file=r.file;var t=l(r.input,r.line);this.message=p(e,r),this.stack=t+"\n"+(this.stack||this.message)}function i(e,r){s.call(this,e,r)}function o(e,r){h.assign(this,e),this.originalError=e,s.call(this,e.message,r)}function u(e,r){if(e instanceof u)return e;h.assign(this,e),this.originalError=e,s.call(this,e.message,r.token)}function a(e){n.call(this),this.message=e+""}function c(e){n.call(this),this.message=e+""}function l(e,r){var t=e.split("\n"),n=Math.max(r-2,1),s=Math.min(r+3,t.length);return h.range(n,s+1).map(function(e){return[e===r?">> ":" ",f(e,s),"| ",t[e-1]].join("")}).join("\n")}function f(e,r){var t=(r+"").length,n=e+"";return Array(t-n.length).join(" ")+n}function p(e,r){return e=e||"",r.file&&(e+=", file:"+r.file),r.line&&(e+=", line:"+r.line),e}var h=e("./underscore.js");(i.prototype=Object.create(Error.prototype)).constructor=i,(o.prototype=Object.create(Error.prototype)).constructor=o,u.prototype=Object.create(Error.prototype),u.prototype.constructor=u,(a.prototype=Object.create(Error.prototype)).constructor=a,(c.prototype=Object.create(Error.prototype)).constructor=c,r.exports={TokenizationError:i,ParseError:o,RenderBreakError:a,AssertionError:c,RenderError:u}},{"./underscore.js":21}],18:[function(e,r,t){"use strict";var n=e("fs");r.exports={readFileAsync:function(e){return new Promise(function(r,t){n.readFile(e,"utf8",function(e,n){e?t(e):r(n)})})},statFileAsync:function(e){return new Promise(function(r,t){n.stat(e,function(e,n){return e?t(e):r(n)})})}}},{fs:6}],19:[function(e,r,t){"use strict";var n=e("any-promise");t.anySeries=function(e,r){var t=n.reject(new Error("init"));return e.forEach(function(n,s){t=t.catch(function(t){return r(n,s,e)})}),t},t.mapSeries=function(e,r){var t=n.resolve("init"),s=[];return e.forEach(function(n,i){t=t.then(function(){return r(n,i,e)}).then(function(e){return s.push(e)})}),t.then(function(){return s})}},{"any-promise":3}],20:[function(e,r,t){"use strict";var n=["January","February","March","April","May","June","July","August","September","October","November","December"],s=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],i=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],o=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],u={1:"st",2:"nd",3:"rd",default:"th"},a={daysInMonth:function(e){return[31,a.isLeapYear(e)?29:28,31,30,31,30,31,31,30,31,30,31]},getDayOfYear:function(e){for(var r=0,t=0;t0;)n=t+n;return n}},l={a:function(e){return o[e.getDay()]},A:function(e){return i[e.getDay()]},b:function(e){return s[e.getMonth()]},B:function(e){return n[e.getMonth()]},c:function(e){return e.toLocaleString()},C:function(e){return a.century(e)},d:function(e){return c.pad(e.getDate(),2)},e:function(e){return c.pad(e.getDate(),2," ")},H:function(e){return c.pad(e.getHours(),2)},I:function(e){return c.pad(e.getHours()%12||12,2)},j:function(e){return c.pad(a.getDayOfYear(e),3)},k:function(e){return c.pad(e.getHours(),2," ")},l:function(e){return c.pad(e.getHours()%12||12,2," ")},L:function(e){return c.pad(e.getMilliseconds(),3)},m:function(e){return c.pad(e.getMonth()+1,2)},M:function(e){return c.pad(e.getMinutes(),2)},p:function(e){return e.getHours()<12?"AM":"PM"},P:function(e){return e.getHours()<12?"am":"pm"},q:function(e){return a.getSuffix(e)},s:function(e){return Math.round(e.valueOf()/1e3)},S:function(e){return c.pad(e.getSeconds(),2)},u:function(e){return e.getDay()||7},U:function(e){return a.getWeekOfYear(e,0)},w:function(e){return e.getDay()},W:function(e){return a.getWeekOfYear(e,1)},x:function(e){return e.toLocaleDateString()},X:function(e){return e.toLocaleTimeString()},y:function(e){return e.getFullYear().toString().substring(2,4)},Y:function(e){return e.getFullYear()},z:function(e){var r=e.getTimezoneOffset()/60*100;return console.log("tz",r),(r>0?"-":"+")+c.pad(Math.abs(r),4)},"%":function(){return"%"}};l.h=l.b,l.N=l.L;r.exports=function(e,r){for(var t="",n=r;;){var s=/%./g,i=s.exec(n);if(!i)return t+n;t+=n.slice(0,s.lastIndex-2),n=n.slice(s.lastIndex);var o=i[0].charAt(1),u=l[o];t+=u?u.call(this,e):"%"+o}}},{}],21:[function(e,r,t){"use strict";function n(e,r){e=e||{};for(var t in e)if(e.hasOwnProperty(t)&&!1===r(e[t],t,e))break;return e}function s(e,r){return n(r,function(r,t){e[t]=r}),e}function i(e){var r=void 0===e?"undefined":o(e);return null!=e&&("object"===r||"function"===r)}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e},u=Object.prototype.toString;t.isString=function(e){return e instanceof String||"string"==typeof e},t.isObject=i,t.isArray=function(e){return"[object Array]"===u.call(e)},t.isNil=function(e){return null===e||void 0===e},t.isError=function(e){return"Error"===Object.prototype.toString.call(e).substr(-6,5)||"string"==typeof e.message&&"string"==typeof e.name},t.range=function(e,r,t){1===arguments.length&&(r=e,e=0),t=t||1;for(var n=[],s=e;s0?a=[a]:o.isObject(a)&&(a=Object.keys(a))),!Array.isArray(a)||!a.length)return e.renderer.renderTemplates(this.elseTemplates,r);var c=a.length,l=t.offset||0,f=void 0===t.limit?a.length:t.limit;a=a.slice(l,l+f),this.reversed&&a.reverse();var p=a.map(function(e,r){var t={};return t[s.variable]=e,t.forloop={first:0===r,index:r+1,index0:r,last:r===c-1,length:c,rindex:c-r,rindex0:c-r-1},t}),h="";return i(p,function(t){return r.push(t),e.renderer.renderTemplates(s.templates,r).then(function(e){return h+=e}).catch(function(e){if(!(e instanceof u&&(h+=e.resolvedHTML,"continue"===e.message)))throw e}).then(function(){return r.pop()})}).catch(function(e){if(!(e instanceof u&&"break"===e.message))throw e}).then(function(){return h})}})}},{"..":2,"../src/util/assert.js":16,"../src/util/promise.js":19,"../src/util/underscore.js":21}],29:[function(e,r,t){"use strict";var n=e("..");r.exports=function(e){e.registerTag("if",{parse:function(r,t){var n=this;this.branches=[],this.elseTemplates=[];var s,i=e.parser.parseStream(t).on("start",function(){return n.branches.push({cond:r.args,templates:s=[]})}).on("tag:elsif",function(e){n.branches.push({cond:e.args,templates:s=[]})}).on("tag:else",function(){return s=n.elseTemplates}).on("tag:endif",function(e){return i.stop()}).on("template",function(e){return s.push(e)}).on("end",function(e){throw new Error("tag "+r.raw+" not closed")});i.start()},render:function(r,t){for(var s=0;s",l=t.offset||0,f=void 0===t.limit?a.length:t.limit,p=t.cols;if(!p)throw new Error("illegal cols: "+p);var h=[];return(a=a.slice(l,l+f)).some(function(e,r){var t={};t[u.variable]=e,h.push(t)}),s(h,function(t,n){return i=Math.floor(n/p)+1,1===(o=n%p+1)&&(1!==i&&(c+=""),c+=''),c+='| ',r.push(t),e.renderer.renderTemplates(u.templates,r).then(function(e){return r.pop(t),c+=e,c+=" | "})}).then(function(){return i>0&&(c+="
"),c+=""})}})}},{"..":2,"../src/util/assert.js":16,"../src/util/promise.js":19}],36:[function(e,r,t){"use strict";var n=e("..");r.exports=function(e){e.registerTag("unless",{parse:function(r,t){var n=this;this.templates=[],this.elseTemplates=[];var s,i=e.parser.parseStream(t).on("start",function(e){s=n.templates,n.cond=r.args}).on("tag:else",function(e){return s=n.elseTemplates}).on("tag:endunless",function(e){return i.stop()}).on("template",function(e){return s.push(e)}).on("end",function(e){throw new Error("tag "+r.raw+" not closed")});i.start()},render:function(r,t){var s=n.evalExp(this.cond,r);return n.isFalsy(s)?e.renderer.renderTemplates(this.templates,r):e.renderer.renderTemplates(this.elseTemplates,r)}})}},{"..":2}]},{},[2])(2)});
\ No newline at end of file
diff --git a/package.json b/package.json
index 72bce2033..c0d850e50 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "liquidjs",
- "version": "1.9.3",
+ "version": "1.9.4",
"description": "A Liquid template engine for Node.js and browsers, with all shopify/liquid features.",
"main": "index.js",
"scripts": {