diff --git a/dist/liquid.js b/dist/liquid.js index 7fed0bd8a..9a1b3b547 100644 --- a/dist/liquid.js +++ b/dist/liquid.js @@ -227,139 +227,139 @@ var anySeries = require('./src/util/promise.js').anySeries; var Errors = require('./src/util/error.js'); var _engine = { - init: function init(tag, filter, options) { - if (options.cache) { - this.cache = {}; - } - this.options = options; - this.tag = tag; - this.filter = filter; - this.parser = Parser(tag, filter); - this.renderer = Render(); - - tags(this); - filters(this); - - return this; - }, - parse: function parse(html, filepath) { - var tokens = tokenizer.parse(html, filepath, this.options); - return this.parser.parse(tokens); - }, - render: function render(tpl, ctx, opts) { - opts = _.assign({}, this.options, opts); - var scope = Scope.factory(ctx, opts); - return this.renderer.renderTemplates(tpl, scope); - }, - parseAndRender: function parseAndRender(html, ctx, opts) { - var _this = this; - - return Promise.resolve().then(function () { - 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) { - var _this2 = this; - - opts = _.assign({}, opts); - return this.getTemplate(filepath, opts.root).then(function (templates) { - return _this2.render(templates, ctx, opts); - }); - }, - evalOutput: function evalOutput(str, scope) { - var tpl = this.parser.parseOutput(str.trim()); - return this.renderer.evalOutput(tpl, scope); - }, - registerFilter: function registerFilter(name, filter) { - return this.filter.register(name, filter); - }, - registerTag: function registerTag(name, tag) { - return this.tag.register(name, tag); - }, - lookup: function lookup(filepath, root) { - root = this.options.root.concat(root || []); - root = _.uniq(root); - var paths = root.map(function (root) { - return path.resolve(root, filepath); - }); - return anySeries(paths, function (path) { - return statFileAsync(path).then(function () { - return path; - }); - }).catch(function (e) { - if (e.code === 'ENOENT') { - e.message = 'Failed to lookup ' + filepath + ' in: ' + root; - } - throw e; - }); - }, - getTemplate: function getTemplate(filepath, root) { - var _this3 = this; - - if (!path.extname(filepath)) { - filepath += this.options.extname; - } - return this.lookup(filepath, root).then(function (filepath) { - if (_this3.options.cache) { - var tpl = _this3.cache[filepath]; - if (tpl) { - return Promise.resolve(tpl); - } - return readFileAsync(filepath).then(function (str) { - return _this3.parse(str); - }).then(function (tpl) { - return _this3.cache[filepath] = tpl; - }); - } else { - return readFileAsync(filepath).then(function (str) { - return _this3.parse(str, filepath); - }); - } - }); - }, - express: function express(opts) { - opts = opts || {}; - var self = this; - return function (filePath, ctx, callback) { - assert(_.isArray(this.root) || _.isString(this.root), 'illegal views root, are you using express.js?'); - opts.root = this.root; - self.renderFile(filePath, ctx, opts).then(function (html) { - return callback(null, html); - }).catch(function (e) { - return callback(e); - }); - }; + init: function init(tag, filter, options) { + if (options.cache) { + this.cache = {}; } + this.options = options; + this.tag = tag; + this.filter = filter; + this.parser = Parser(tag, filter); + this.renderer = Render(); + + tags(this); + filters(this); + + return this; + }, + parse: function parse(html, filepath) { + var tokens = tokenizer.parse(html, filepath, this.options); + return this.parser.parse(tokens); + }, + render: function render(tpl, ctx, opts) { + opts = _.assign({}, this.options, opts); + var scope = Scope.factory(ctx, opts); + return this.renderer.renderTemplates(tpl, scope); + }, + parseAndRender: function parseAndRender(html, ctx, opts) { + var _this = this; + + return Promise.resolve().then(function () { + 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) { + var _this2 = this; + + opts = _.assign({}, opts); + return this.getTemplate(filepath, opts.root).then(function (templates) { + return _this2.render(templates, ctx, opts); + }); + }, + evalOutput: function evalOutput(str, scope) { + var tpl = this.parser.parseOutput(str.trim()); + return this.renderer.evalOutput(tpl, scope); + }, + registerFilter: function registerFilter(name, filter) { + return this.filter.register(name, filter); + }, + registerTag: function registerTag(name, tag) { + return this.tag.register(name, tag); + }, + lookup: function lookup(filepath, root) { + root = this.options.root.concat(root || []); + root = _.uniq(root); + var paths = root.map(function (root) { + return path.resolve(root, filepath); + }); + return anySeries(paths, function (path) { + return statFileAsync(path).then(function () { + return path; + }); + }).catch(function (e) { + if (e.code === 'ENOENT') { + e.message = 'Failed to lookup ' + filepath + ' in: ' + root; + } + throw e; + }); + }, + getTemplate: function getTemplate(filepath, root) { + var _this3 = this; + + if (!path.extname(filepath)) { + filepath += this.options.extname; + } + return this.lookup(filepath, root).then(function (filepath) { + if (_this3.options.cache) { + var tpl = _this3.cache[filepath]; + if (tpl) { + return Promise.resolve(tpl); + } + return readFileAsync(filepath).then(function (str) { + return _this3.parse(str); + }).then(function (tpl) { + return _this3.cache[filepath] = tpl; + }); + } else { + return readFileAsync(filepath).then(function (str) { + return _this3.parse(str, filepath); + }); + } + }); + }, + express: function express(opts) { + opts = opts || {}; + var self = this; + return function (filePath, ctx, callback) { + assert(_.isArray(this.root) || _.isString(this.root), 'illegal views root, are you using express.js?'); + opts.root = this.root; + self.renderFile(filePath, ctx, opts).then(function (html) { + return callback(null, html); + }).catch(function (e) { + return callback(e); + }); + }; + } }; function factory(options) { - options = _.assign({ - root: ['.'], - cache: false, - extname: '.liquid', - trim_right: false, - trim_left: false, - strict_filters: false, - strict_variables: false - }, options); - options.root = normalizeStringArray(options.root); + options = _.assign({ + root: ['.'], + cache: false, + extname: '.liquid', + trim_right: false, + trim_left: false, + strict_filters: false, + strict_variables: false + }, options); + options.root = normalizeStringArray(options.root); - var engine = Object.create(_engine); - engine.init(Tag(), Filter(options), options); - return engine; + var engine = Object.create(_engine); + engine.init(Tag(), Filter(options), options); + return engine; } function normalizeStringArray(value) { - if (_.isArray(value)) return value; - if (_.isString(value)) return [value]; - return []; + if (_.isArray(value)) return value; + if (_.isString(value)) return [value]; + return []; } factory.lexical = lexical; @@ -368,10 +368,10 @@ factory.isFalsy = Syntax.isFalsy; factory.evalExp = Syntax.evalExp; factory.evalValue = Syntax.evalValue; factory.Types = { - ParseError: Errors.ParseError, - TokenizationEroor: Errors.TokenizationError, - RenderBreakError: Errors.RenderBreakError, - AssertionError: Errors.AssertionError + ParseError: Errors.ParseError, + TokenizationEroor: Errors.TokenizationError, + RenderBreakError: Errors.RenderBreakError, + AssertionError: Errors.AssertionError }; module.exports = factory; @@ -493,71 +493,67 @@ var _ = require('./util/underscore.js'); var valueRE = new RegExp('' + lexical.value.source, 'g'); module.exports = function (options) { - options = _.assign({}, options); - var filters = {}; + options = _.assign({}, options); + var filters = {}; - var _filterInstance = { - render: function render(output, scope) { - var args = this.args.map(function (arg) { - return Syntax.evalValue(arg, scope); - }); - args.unshift(output); - return this.filter.apply(null, args); - }, - parse: function parse(str) { - var match = lexical.filterLine.exec(str); - assert(match, 'illegal filter: ' + str); + var _filterInstance = { + render: function render(output, scope) { + var args = this.args.map(function (arg) { + return Syntax.evalValue(arg, scope); + }); + args.unshift(output); + return this.filter.apply(null, args); + }, + parse: function parse(str) { + var match = lexical.filterLine.exec(str); + assert(match, 'illegal filter: ' + str); - var name = match[1], - argList = match[2] || '', - filter = filters[name]; - if (typeof filter !== 'function') { - if (options.strict_filters) { - throw new TypeError('undefined filter: ' + name); - } - this.name = name; - this.filter = function (x) { - return x; - }; - this.args = []; - return this; - //return { - //name: name, - //error: new TypeError(`undefined filter: ${name}`) - //}; - } - - var args = []; - while (match = valueRE.exec(argList.trim())) { - var v = match[0]; - var re = new RegExp(v + '\\s*:', 'g'); - re.test(match.input) ? args.push('\'' + v + '\'') : args.push(v); - } - - this.name = name; - this.filter = filter; - this.args = args; - - return this; + var name = match[1]; + var argList = match[2] || ''; + var filter = filters[name]; + if (typeof filter !== 'function') { + if (options.strict_filters) { + throw new TypeError('undefined filter: ' + name); } - }; + this.name = name; + this.filter = function (x) { + return x; + }; + this.args = []; + return this; + } - function construct(str) { - var instance = Object.create(_filterInstance); - return instance.parse(str); + var args = []; + while (match = valueRE.exec(argList.trim())) { + var v = match[0]; + var re = new RegExp(v + '\\s*:', 'g'); + re.test(match.input) ? args.push('\'' + v + '\'') : args.push(v); + } + + this.name = name; + this.filter = filter; + this.args = args; + + return this; } + }; - function register(name, filter) { - filters[name] = filter; - } + function construct(str) { + var instance = Object.create(_filterInstance); + return instance.parse(str); + } - function clear() { - filters = {}; - } + function register(name, filter) { + filters[name] = filter; + } - return { - construct: construct, register: register, clear: clear - }; + function clear() { + filters = {}; + } + + return { + construct: construct, register: register, clear: clear + }; }; },{"./lexical.js":8,"./syntax.js":13,"./util/assert.js":16,"./util/underscore.js":21}],8:[function(require,module,exports){ @@ -611,80 +607,103 @@ var filterLine = new RegExp('^' + filterCapture.source + '$'); var operators = [/\s+or\s+/, /\s+and\s+/, /==|!=|<=|>=|<|>|\s+contains\s+/]; function isInteger(str) { - return integerLine.test(str); + return integerLine.test(str); } function isLiteral(str) { - return literalLine.test(str); + return literalLine.test(str); } function isRange(str) { - return rangeLine.test(str); + return rangeLine.test(str); } function isVariable(str) { - return variableLine.test(str); + return variableLine.test(str); } function matchValue(str) { - return value.exec(str); + return value.exec(str); } function parseLiteral(str) { - var res; - if (res = str.match(numberLine)) { - return Number(str); - } - if (res = str.match(boolLine)) { - return str.toLowerCase() === 'true'; - } - if (res = str.match(quotedLine)) { - return str.slice(1, -1); - } + var res = str.match(numberLine); + if (res) { + return Number(str); + } + res = str.match(boolLine); + if (res) { + return str.toLowerCase() === 'true'; + } + res = str.match(quotedLine); + if (res) { + return str.slice(1, -1); + } } module.exports = { - quoted: quoted, number: number, bool: bool, literal: literal, filter: filter, integer: integer, - hash: hash, hashCapture: hashCapture, - range: range, rangeCapture: rangeCapture, - identifier: identifier, value: value, quoteBalanced: quoteBalanced, operators: operators, - quotedLine: quotedLine, numberLine: numberLine, boolLine: boolLine, rangeLine: rangeLine, literalLine: literalLine, filterLine: filterLine, tagLine: tagLine, - isLiteral: isLiteral, isVariable: isVariable, parseLiteral: parseLiteral, isRange: isRange, matchValue: matchValue, isInteger: isInteger + quoted: quoted, + number: number, + bool: bool, + literal: literal, + filter: filter, + integer: integer, + hash: hash, + hashCapture: hashCapture, + range: range, + rangeCapture: rangeCapture, + identifier: identifier, + value: value, + quoteBalanced: quoteBalanced, + operators: operators, + quotedLine: quotedLine, + numberLine: numberLine, + boolLine: boolLine, + rangeLine: rangeLine, + literalLine: literalLine, + filterLine: filterLine, + tagLine: tagLine, + isLiteral: isLiteral, + isVariable: isVariable, + parseLiteral: parseLiteral, + isRange: isRange, + matchValue: matchValue, + isInteger: isInteger }; },{}],9:[function(require,module,exports){ 'use strict'; var operators = { - '==': function _(l, r) { - return l == r; - }, - '!=': function _(l, r) { - return l != r; - }, - '>': function _(l, r) { - return l !== null && r !== null && l > r; - }, - '<': function _(l, r) { - return l !== null && r !== null && l < r; - }, - '>=': function _(l, r) { - return l !== null && r !== null && l >= r; - }, - '<=': function _(l, r) { - return l !== null && r !== null && l <= r; - }, - 'contains': function contains(l, r) { - if (!l) return false; - if (typeof l.indexOf !== 'function') return false; - return l.indexOf(r) > -1; - }, - 'and': function and(l, r) { - return l && r; - }, - 'or': function or(l, r) { - return l || r; - } + '==': function _(l, r) { + return l === r; + }, + '!=': function _(l, r) { + return l !== r; + }, + '>': function _(l, r) { + return l !== null && r !== null && l > r; + }, + '<': function _(l, r) { + return l !== null && r !== null && l < r; + }, + '>=': function _(l, r) { + return l !== null && r !== null && l >= r; + }, + '<=': function _(l, r) { + return l !== null && r !== null && l <= r; + }, + 'contains': function contains(l, r) { + if (!l) return false; + if (typeof l.indexOf !== 'function') return false; + return l.indexOf(r) > -1; + }, + 'and': function and(l, r) { + return l && r; + }, + 'or': function or(l, r) { + return l || r; + } }; module.exports = operators; @@ -697,108 +716,107 @@ var ParseError = require('./util/error.js').ParseError; var assert = require('./util/assert.js'); module.exports = function (Tag, Filter) { - - var stream = { - init: function init(tokens) { - this.tokens = tokens; - this.handlers = {}; - return this; - }, - on: function on(name, cb) { - this.handlers[name] = cb; - return this; - }, - trigger: function trigger(event, arg) { - var h = this.handlers[event]; - if (typeof h === 'function') { - h(arg); - return true; - } - }, - start: function start() { - this.trigger('start'); - var token; - while (!this.stopRequested && (token = this.tokens.shift())) { - if (this.trigger('token', token)) continue; - if (token.type == 'tag' && this.trigger('tag:' + token.name, token)) { - continue; - } - var template = parseToken(token, this.tokens); - this.trigger('template', template); - } - if (!this.stopRequested) this.trigger('end'); - return this; - }, - stop: function stop() { - this.stopRequested = true; - return this; + var stream = { + init: function init(tokens) { + this.tokens = tokens; + this.handlers = {}; + return this; + }, + on: function on(name, cb) { + this.handlers[name] = cb; + return this; + }, + trigger: function trigger(event, arg) { + var h = this.handlers[event]; + if (typeof h === 'function') { + h(arg); + return true; + } + }, + start: function start() { + this.trigger('start'); + var token; + while (!this.stopRequested && (token = this.tokens.shift())) { + if (this.trigger('token', token)) continue; + if (token.type === 'tag' && this.trigger('tag:' + token.name, token)) { + continue; } - }; - - function parse(tokens) { - var token, - templates = []; - while (token = tokens.shift()) { - templates.push(parseToken(token, tokens)); - } - return templates; + var template = parseToken(token, this.tokens); + this.trigger('template', template); + } + if (!this.stopRequested) this.trigger('end'); + return this; + }, + stop: function stop() { + this.stopRequested = true; + return this; } + }; - function parseToken(token, tokens) { - try { - var tpl = null; - if (token.type === 'tag') { - tpl = parseTag(token, tokens); - } else if (token.type === 'output') { - tpl = parseOutput(token.value); - } else { - // token.type === 'html' - tpl = token; - } - tpl.token = token; - return tpl; - } catch (e) { - throw new ParseError(e, token); - } + function parse(tokens) { + var token; + var templates = []; + while (token = tokens.shift()) { + templates.push(parseToken(token, tokens)); } + return templates; + } - function parseTag(token, tokens) { - if (token.name === 'continue' || token.name === 'break') return token; - return Tag.construct(token, tokens); + function parseToken(token, tokens) { + try { + var tpl = null; + if (token.type === 'tag') { + tpl = parseTag(token, tokens); + } else if (token.type === 'output') { + tpl = parseOutput(token.value); + } else { + // token.type === 'html' + tpl = token; + } + tpl.token = token; + return tpl; + } catch (e) { + throw new ParseError(e, token); } + } - function parseOutput(str) { - var match = lexical.matchValue(str); - assert(match, 'illegal output string: ' + str); + function parseTag(token, tokens) { + if (token.name === 'continue' || token.name === 'break') return token; + return Tag.construct(token, tokens); + } - var initial = match[0]; - str = str.substr(match.index + match[0].length); + function parseOutput(str) { + var match = lexical.matchValue(str); + assert(match, 'illegal output string: ' + str); - var filters = []; - while (match = lexical.filter.exec(str)) { - filters.push([match[0].trim()]); - } + var initial = match[0]; + str = str.substr(match.index + match[0].length); - return { - type: 'output', - initial: initial, - filters: filters.map(function (str) { - return Filter.construct(str); - }) - }; - } - - function parseStream(tokens) { - var s = Object.create(stream); - return s.init(tokens); + var filters = []; + while (match = lexical.filter.exec(str)) { + filters.push([match[0].trim()]); } return { - parse: parse, - parseTag: parseTag, - parseStream: parseStream, - parseOutput: parseOutput + type: 'output', + initial: initial, + filters: filters.map(function (str) { + return Filter.construct(str); + }) }; + } + + function parseStream(tokens) { + var s = Object.create(stream); + return s.init(tokens); + } + + return { + parse: parse, + parseTag: parseTag, + parseStream: parseStream, + parseOutput: parseOutput + }; }; },{"./lexical.js":8,"./util/assert.js":16,"./util/error.js":17}],11:[function(require,module,exports){ @@ -813,72 +831,72 @@ var assert = require('./util/assert.js'); var render = { - renderTemplates: function renderTemplates(templates, scope) { - var _this = this; + renderTemplates: function renderTemplates(templates, scope) { + var _this = this; - assert(scope, 'unable to evalTemplates: scope undefined'); + assert(scope, 'unable to evalTemplates: scope undefined'); - var html = ''; - return mapSeries(templates, function (tpl) { - return renderTemplate.call(_this, tpl).then(function (partial) { - return html += partial; - }).catch(function (e) { - if (e instanceof RenderBreakError) { - e.resolvedHTML = html; - throw e; - } - throw new RenderError(e, tpl); - }); - }).then(function () { - return html; + var html = ''; + return mapSeries(templates, function (tpl) { + return renderTemplate.call(_this, tpl).then(function (partial) { + return html += partial; + }).catch(function (e) { + if (e instanceof RenderBreakError) { + e.resolvedHTML = html; + throw e; + } + throw new RenderError(e, tpl); + }); + }).then(function () { + return html; + }); + + function renderTemplate(template) { + var _this2 = this; + + if (template.type === 'tag') { + return this.renderTag(template, scope).then(function (partial) { + return partial === undefined ? '' : partial; }); - - function renderTemplate(template) { - var _this2 = this; - - if (template.type === 'tag') { - return this.renderTag(template, scope).then(function (partial) { - return partial === undefined ? '' : partial; - }); - } else if (template.type === 'output') { - return Promise.resolve().then(function () { - return _this2.evalOutput(template, scope); - }).then(function (partial) { - return partial === undefined ? '' : stringify(partial); - }); - } else { - // template.type === 'html' - return Promise.resolve(template.value); - } - } - }, - - renderTag: function renderTag(template, scope) { - if (template.name === 'continue') { - return Promise.reject(new RenderBreakError('continue')); - } - if (template.name === 'break') { - return Promise.reject(new RenderBreakError('break')); - } - return template.render(scope); - }, - - evalOutput: function evalOutput(template, scope) { - assert(scope, 'unable to evalOutput: scope undefined'); - return template.filters.reduce(function (prev, filter) { - return filter.render(prev, scope); - }, Syntax.evalExp(template.initial, scope)); + } else if (template.type === 'output') { + return Promise.resolve().then(function () { + return _this2.evalOutput(template, scope); + }).then(function (partial) { + return partial === undefined ? '' : stringify(partial); + }); + } else { + // template.type === 'html' + return Promise.resolve(template.value); + } } + }, + + renderTag: function renderTag(template, scope) { + if (template.name === 'continue') { + return Promise.reject(new RenderBreakError('continue')); + } + if (template.name === 'break') { + return Promise.reject(new RenderBreakError('break')); + } + return template.render(scope); + }, + + evalOutput: function evalOutput(template, scope) { + assert(scope, 'unable to evalOutput: scope undefined'); + return template.filters.reduce(function (prev, filter) { + return filter.render(prev, scope); + }, Syntax.evalExp(template.initial, scope)); + } }; function factory() { - var instance = Object.create(render); - return instance; + var instance = Object.create(render); + return instance; } function stringify(val) { - if (typeof val === 'string') return val; - return JSON.stringify(val); + if (typeof val === 'string') return val; + return JSON.stringify(val); } module.exports = factory; @@ -892,181 +910,177 @@ var assert = require('./util/assert.js'); var toStr = Object.prototype.toString; var Scope = { - getAll: function getAll() { - var ctx = {}; - for (var i = this.scopes.length - 1; i >= 0; i--) { - _.assign(ctx, this.scopes[i]); - } - 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; - } - } - } - 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); - return this; - }, - push: function push(ctx) { - assert(ctx, 'trying to push ' + ctx + ' into scopes'); - return this.scopes.push(ctx); - }, - pop: function pop() { - return this.scopes.pop(); - }, - unshift: function unshift(ctx) { - assert(ctx, 'trying to push ' + ctx + ' into scopes'); - return this.scopes.unshift(ctx); - }, - 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) { - var paths = this.propertyAccessSeq(path + ''); - var varName = paths.shift(); - if (!obj.hasOwnProperty(varName)) { - throw new TypeError('undefined variable'); - } - 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; - } - variable = variable[lastName]; - } - return variable; - }, - - /* - * Parse property access sequence from access string - * @example - * accessSeq("foo.bar") // ['foo', 'bar'] - * accessSeq("foo['bar']") // ['foo', 'bar'] - * accessSeq("foo['b]r']") // ['foo', 'b]r'] - * accessSeq("foo[bar.coo]") // ['foo', 'bar'], for bar.coo == 'bar' - */ - propertyAccessSeq: function propertyAccessSeq(str) { - var seq = [], - name = ''; - for (var i = 0; i < str.length; i++) { - if (str[i] === '[') { - seq.push(name); - name = ''; - - var delemiter = str[i + 1]; - // foo[bar.coo] - if (delemiter !== "'" && delemiter !== '"') { - var j = matchRightBracket(str, i + 1); - assert(j !== -1, 'unbalanced []: ' + str); - name = str.slice(i + 1, j); - // foo[1] - if (lexical.isInteger(name)) { - seq.push(name); - } - // foo["bar"] - else { - seq.push(this.get(name)); - } - name = ''; - i = j; - } - // foo["bar"] - else { - j = str.indexOf(delemiter, i + 2); - assert(j !== -1, 'unbalanced ' + delemiter + ': ' + str); - name = str.slice(i + 2, j); - seq.push(name); - name = ''; - i = j + 2; - } - } - // foo.bar - else if (str[i] === ".") { - seq.push(name); - name = ''; - } - //foo.bar - else { - name += str[i]; - } - } - if (name.length) seq.push(name); - return seq; + getAll: function getAll() { + var ctx = {}; + for (var i = this.scopes.length - 1; i >= 0; i--) { + _.assign(ctx, this.scopes[i]); } + 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; + } + } + } + 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); + return this; + }, + push: function push(ctx) { + assert(ctx, 'trying to push ' + ctx + ' into scopes'); + return this.scopes.push(ctx); + }, + pop: function pop() { + return this.scopes.pop(); + }, + unshift: function unshift(ctx) { + assert(ctx, 'trying to push ' + ctx + ' into scopes'); + return this.scopes.unshift(ctx); + }, + 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) { + var paths = this.propertyAccessSeq(path + ''); + var varName = paths.shift(); + if (!obj.hasOwnProperty(varName)) { + throw new TypeError('undefined variable'); + } + 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; + } + variable = variable[lastName]; + } + return variable; + }, + + /* + * Parse property access sequence from access string + * @example + * accessSeq("foo.bar") // ['foo', 'bar'] + * accessSeq("foo['bar']") // ['foo', 'bar'] + * accessSeq("foo['b]r']") // ['foo', 'b]r'] + * accessSeq("foo[bar.coo]") // ['foo', 'bar'], for bar.coo == 'bar' + */ + propertyAccessSeq: function propertyAccessSeq(str) { + var seq = []; + var name = ''; + for (var i = 0; i < str.length; i++) { + if (str[i] === '[') { + seq.push(name); + name = ''; + + var delemiter = str[i + 1]; + if (delemiter !== "'" && delemiter !== '"') { + // foo[bar.coo] + var j = matchRightBracket(str, i + 1); + assert(j !== -1, 'unbalanced []: ' + str); + name = str.slice(i + 1, j); + if (lexical.isInteger(name)) { + // foo[1] + seq.push(name); + } else { + // foo["bar"] + seq.push(this.get(name)); + } + name = ''; + i = j; + } else { + // foo["bar"] + j = str.indexOf(delemiter, i + 2); + assert(j !== -1, 'unbalanced ' + delemiter + ': ' + str); + name = str.slice(i + 2, j); + seq.push(name); + name = ''; + i = j + 2; + } + } else if (str[i] === '.') { + // foo.bar + seq.push(name); + name = ''; + } else { + // foo.bar + name += str[i]; + } + } + if (name.length) seq.push(name); + return seq; + } }; function matchRightBracket(str, begin) { - var stack = 1; // count of '[' - count of ']' - for (var i = begin; i < str.length; i++) { - if (str[i] === '[') { - stack++; - } - if (str[i] === ']') { - stack--; - if (stack === 0) { - return i; - } - } + var stack = 1; // count of '[' - count of ']' + for (var i = begin; i < str.length; i++) { + if (str[i] === '[') { + stack++; } - return -1; + if (str[i] === ']') { + stack--; + if (stack === 0) { + return i; + } + } + } + return -1; } exports.factory = function (ctx, opts) { - opts = _.assign({ - strict_variables: false, - strict_filters: false, - blocks: {}, - root: [] - }, opts); + opts = _.assign({ + strict_variables: false, + strict_filters: false, + blocks: {}, + root: [] + }, opts); - ctx = _.assign(ctx, { - liquid: opts - }); + ctx = _.assign(ctx, { + liquid: opts + }); - var scope = Object.create(Scope); - scope.opts = opts; - scope.scopes = [ctx]; - return scope; + var scope = Object.create(Scope); + scope.opts = opts; + scope.scopes = [ctx]; + return scope; }; },{"./lexical.js":8,"./util/assert.js":16,"./util/underscore.js":21}],13:[function(require,module,exports){ @@ -1077,55 +1091,55 @@ var lexical = require('./lexical.js'); var assert = require('../src/util/assert.js'); function evalExp(exp, scope) { - assert(scope, 'unable to evalExp: scope undefined'); - var operatorREs = lexical.operators, - match; - for (var i = 0; i < operatorREs.length; i++) { - var operatorRE = operatorREs[i]; - var expRE = new RegExp('^(' + lexical.quoteBalanced.source + ')(' + operatorRE.source + ')(' + lexical.quoteBalanced.source + ')$'); - if (match = exp.match(expRE)) { - var l = evalExp(match[1], scope); - var op = operators[match[2].trim()]; - var r = evalExp(match[3], scope); - return op(l, r); - } + assert(scope, 'unable to evalExp: scope undefined'); + var operatorREs = lexical.operators; + var match; + for (var i = 0; i < operatorREs.length; i++) { + var operatorRE = operatorREs[i]; + var expRE = new RegExp('^(' + lexical.quoteBalanced.source + ')(' + operatorRE.source + ')(' + lexical.quoteBalanced.source + ')$'); + if (match = exp.match(expRE)) { + var l = evalExp(match[1], scope); + var op = operators[match[2].trim()]; + var r = evalExp(match[3], scope); + return op(l, r); } + } - if (match = exp.match(lexical.rangeLine)) { - var low = evalValue(match[1], scope), - high = evalValue(match[2], scope); - var range = []; - for (var j = low; j <= high; j++) { - range.push(j); - } - return range; + if (match = exp.match(lexical.rangeLine)) { + var low = evalValue(match[1], scope); + var high = evalValue(match[2], scope); + var range = []; + for (var j = low; j <= high; j++) { + range.push(j); } + return range; + } - return evalValue(exp, scope); + return evalValue(exp, scope); } function evalValue(str, scope) { - str = str && str.trim(); - if (!str) return undefined; + str = str && str.trim(); + if (!str) return undefined; - if (lexical.isLiteral(str)) { - return lexical.parseLiteral(str); - } - if (lexical.isVariable(str)) { - return scope.get(str); - } + if (lexical.isLiteral(str)) { + return lexical.parseLiteral(str); + } + if (lexical.isVariable(str)) { + return scope.get(str); + } } function isTruthy(val) { - return !isFalsy(val); + return !isFalsy(val); } function isFalsy(val) { - return false === val || undefined === val || null === val;; + return val === false || undefined === val || val === null; } module.exports = { - evalExp: evalExp, evalValue: evalValue, isTruthy: isTruthy, isFalsy: isFalsy + evalExp: evalExp, evalValue: evalValue, isTruthy: isTruthy, isFalsy: isFalsy }; },{"../src/util/assert.js":16,"./lexical.js":8,"./operators.js":9}],14:[function(require,module,exports){ @@ -1138,70 +1152,70 @@ var Syntax = require('./syntax.js'); var assert = require('./util/assert.js'); function hash(markup, scope) { - var obj = {}, - match; - lexical.hashCapture.lastIndex = 0; - while (match = lexical.hashCapture.exec(markup)) { - var k = match[1], - v = match[2]; - obj[k] = Syntax.evalValue(v, scope); - } - return obj; + var obj = {}; + var match; + lexical.hashCapture.lastIndex = 0; + while (match = lexical.hashCapture.exec(markup)) { + var k = match[1]; + var v = match[2]; + obj[k] = Syntax.evalValue(v, scope); + } + return obj; } module.exports = function () { - var tagImpls = {}; + var tagImpls = {}; - var _tagInstance = { - render: function render(scope) { - var obj = hash(this.token.args, scope); - var impl = this.tagImpl; - if (typeof impl.render !== '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); - }); - }, - parse: function parse(token, tokens) { - this.type = 'tag'; - this.token = token; - this.name = token.name; - - var tagImpl = tagImpls[this.name]; - assert(tagImpl, 'tag ' + this.name + ' not found'); - this.tagImpl = Object.create(tagImpl); - if (this.tagImpl.parse) { - this.tagImpl.parse(token, tokens); - } + var _tagInstance = { + render: function render(scope) { + var obj = hash(this.token.args, scope); + var impl = this.tagImpl; + if (typeof impl.render !== '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); + }); + }, + parse: function parse(token, tokens) { + this.type = 'tag'; + this.token = token; + this.name = token.name; - function register(name, tag) { - tagImpls[name] = tag; + var tagImpl = tagImpls[this.name]; + assert(tagImpl, 'tag ' + this.name + ' not found'); + this.tagImpl = Object.create(tagImpl); + if (this.tagImpl.parse) { + this.tagImpl.parse(token, tokens); + } } + }; - function construct(token, tokens) { - var instance = Object.create(_tagInstance); - instance.parse(token, tokens); - return instance; - } + function register(name, tag) { + tagImpls[name] = tag; + } - function clear() { - tagImpls = {}; - } + function construct(token, tokens) { + var instance = Object.create(_tagInstance); + instance.parse(token, tokens); + return instance; + } - return { - construct: construct, - register: register, - clear: clear - }; + function clear() { + tagImpls = {}; + } + + return { + construct: construct, + register: register, + clear: clear + }; }; },{"./lexical.js":8,"./syntax.js":13,"./util/assert.js":16,"./util/underscore.js":21,"any-promise":3}],15:[function(require,module,exports){ @@ -1213,89 +1227,88 @@ var _ = require('./util/underscore.js'); var assert = require('../src/util/assert.js'); function parse(html, filepath, options) { - assert(_.isString(html), 'illegal input type'); + assert(_.isString(html), 'illegal input type'); - html = whiteSpaceCtrl(html, options); + html = whiteSpaceCtrl(html, options); - var tokens = []; - var syntax = /({%-?([\s\S]*?)-?%})|({{([\s\S]*?)}})/g; - var result, htmlFragment, token; - var lastMatchEnd = 0, - lastMatchBegin = -1, - parsedLinesCount = 0; + var tokens = []; + var syntax = /({%-?([\s\S]*?)-?%})|({{([\s\S]*?)}})/g; + var result, htmlFragment, token; + var lastMatchEnd = 0; + var lastMatchBegin = -1; + var parsedLinesCount = 0; - while ((result = syntax.exec(html)) !== null) { - // passed html fragments - if (result.index > lastMatchEnd) { - htmlFragment = html.slice(lastMatchEnd, result.index); - tokens.push({ - type: 'html', - raw: htmlFragment, - value: htmlFragment - }); - } - // tag appeared - if (result[1]) { - token = factory('tag', 1, result); - - var match = token.value.match(lexical.tagLine); - if (!match) { - throw new TokenizationError('illegal tag syntax', token); - } - token.name = match[1]; - token.args = match[2]; - - tokens.push(token); - } - // output - else { - token = factory('output', 3, result); - tokens.push(token); - } - lastMatchEnd = syntax.lastIndex; + while ((result = syntax.exec(html)) !== null) { + // passed html fragments + if (result.index > lastMatchEnd) { + htmlFragment = html.slice(lastMatchEnd, result.index); + tokens.push({ + type: 'html', + raw: htmlFragment, + value: htmlFragment + }); } + if (result[1]) { + // tag appeared + token = factory('tag', 1, result); - // remaining html - if (html.length > lastMatchEnd) { - htmlFragment = html.slice(lastMatchEnd, html.length); - tokens.push({ - type: 'html', - raw: htmlFragment, - value: htmlFragment - }); - } - return tokens; + var match = token.value.match(lexical.tagLine); + if (!match) { + throw new TokenizationError('illegal tag syntax', token); + } + token.name = match[1]; + token.args = match[2]; - function factory(type, offset, match) { - return { - type: type, - raw: match[offset], - value: match[offset + 1].trim(), - line: getLineNum(match), - input: html, - file: filepath - }; + tokens.push(token); + } else { + // output + token = factory('output', 3, result); + tokens.push(token); } + lastMatchEnd = syntax.lastIndex; + } - function getLineNum(match) { - var lines = match.input.slice(lastMatchBegin + 1, match.index).split('\n'); - parsedLinesCount += lines.length - 1; - lastMatchBegin = match.index; - return parsedLinesCount + 1; - } + // remaining html + if (html.length > lastMatchEnd) { + htmlFragment = html.slice(lastMatchEnd, html.length); + tokens.push({ + type: 'html', + raw: htmlFragment, + value: htmlFragment + }); + } + return tokens; + + function factory(type, offset, match) { + return { + type: type, + raw: match[offset], + value: match[offset + 1].trim(), + line: getLineNum(match), + input: html, + file: filepath + }; + } + + function getLineNum(match) { + var lines = match.input.slice(lastMatchBegin + 1, match.index).split('\n'); + parsedLinesCount += lines.length - 1; + lastMatchBegin = match.index; + return parsedLinesCount + 1; + } } function whiteSpaceCtrl(html, options) { - options = options || {}; - if (options.trim_left) { - html = html.replace(/{%-?/g, '{%-'); - } - if (options.trim_right) { - html = html.replace(/-?%}/g, '-%}'); - } - var rLeft = options.greedy ? /\s+({%-)/g : /[\t\r ]*({%-)/g; - var rRight = options.greedy ? /(-%})\s+/g : /(-%})[\t\r ]*\n?/g; - return html.replace(rLeft, '$1').replace(rRight, '$1'); + options = options || {}; + if (options.trim_left) { + html = html.replace(/{%-?/g, '{%-'); + } + if (options.trim_right) { + html = html.replace(/-?%}/g, '-%}'); + } + var rLeft = options.greedy ? /\s+({%-)/g : /[\t\r ]*({%-)/g; + var rRight = options.greedy ? /(-%})\s+/g : /(-%})[\t\r ]*\n?/g; + return html.replace(rLeft, '$1').replace(rRight, '$1'); } exports.parse = parse; @@ -1307,13 +1320,13 @@ exports.whiteSpaceCtrl = whiteSpaceCtrl; var AssertionError = require('./error.js').AssertionError; function assert(predicate, message) { - if (!predicate) { - if (message instanceof Error) { - throw message; - } - var message = message || 'expect ' + predicate + ' to be true'; - throw new AssertionError(message); + if (!predicate) { + if (message instanceof Error) { + throw message; } + message = message || 'expect ' + predicate + ' to be true'; + throw new AssertionError(message); + } } module.exports = assert; @@ -1324,114 +1337,114 @@ module.exports = assert; var _ = require('./underscore.js'); function TokenizationError(message, token) { - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } - this.name = this.constructor.name; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + this.name = this.constructor.name; - this.input = token.input; - this.line = token.line; - this.file = token.file; + this.input = token.input; + this.line = token.line; + this.file = token.file; - var context = mkContext(token.input, token.line); - this.message = mkMessage(message, token); - this.stack = context + '\n' + (this.stack || ''); + var context = mkContext(token.input, token.line); + this.message = mkMessage(message, token); + this.stack = context + '\n' + (this.stack || ''); } TokenizationError.prototype = Object.create(Error.prototype); TokenizationError.prototype.constructor = TokenizationError; function ParseError(e, token) { - _.assign(this, e); - this.originalError = e; - this.name = this.constructor.name; + _.assign(this, e); + this.originalError = e; + this.name = this.constructor.name; - this.input = token.input; - this.line = token.line; - this.file = token.file; + 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 || ''); + var context = mkContext(token.input, token.line); + this.message = mkMessage(e.message || 'Unkown Error', token); + this.stack = context + '\n' + (e.stack || ''); } ParseError.prototype = Object.create(Error.prototype); ParseError.prototype.constructor = ParseError; function RenderError(e, tpl) { - // return the original render error - if (e instanceof RenderError) { - return e; - } - _.assign(this, e); - this.originalError = e; - this.name = this.constructor.name; + // return the original render error + if (e instanceof RenderError) { + return e; + } + _.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; + 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 || ''); + var context = mkContext(tpl.token.input, tpl.token.line); + this.message = mkMessage(e.message || 'Unkown Error', tpl.token); + this.stack = context + '\n' + (e.stack || ''); } 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 || ''; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + this.name = this.constructor.name; + 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; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + this.name = this.constructor.name; + this.message = message; } AssertionError.prototype = Object.create(Error.prototype); AssertionError.prototype.constructor = AssertionError; function mkContext(input, line) { - var lines = input.split('\n'); - var begin = Math.max(line - 2, 1); - var end = Math.min(line + 3, lines.length); + var lines = input.split('\n'); + var begin = Math.max(line - 2, 1); + var end = Math.min(line + 3, lines.length); - var context = _.range(begin, end + 1).map(function (l) { - return [l === line ? '>> ' : ' ', align(l, end), '| ', lines[l - 1]].join(''); - }).join('\n'); + var context = _.range(begin, end + 1).map(function (l) { + return [l === line ? '>> ' : ' ', align(l, end), '| ', lines[l - 1]].join(''); + }).join('\n'); - return context; + return context; } function align(n, max) { - var length = (max + '').length; - var str = n + ''; - var blank = Array(length - str.length).join(' '); - return blank + str; + var length = (max + '').length; + var str = n + ''; + var blank = Array(length - str.length).join(' '); + return blank + str; } function mkMessage(msg, token) { - msg = msg || ''; - if (token.file) { - msg += ', file:' + token.file; - } - if (token.line) { - msg += ', line:' + token.line; - } - return msg; + msg = msg || ''; + if (token.file) { + msg += ', file:' + token.file; + } + if (token.line) { + msg += ', line:' + token.line; + } + return msg; } module.exports = { - TokenizationError: TokenizationError, - ParseError: ParseError, - RenderBreakError: RenderBreakError, - AssertionError: AssertionError, - RenderError: RenderError + TokenizationError: TokenizationError, + ParseError: ParseError, + RenderBreakError: RenderBreakError, + AssertionError: AssertionError, + RenderError: RenderError }; },{"./underscore.js":21}],18:[function(require,module,exports){ @@ -1440,24 +1453,24 @@ module.exports = { var fs = require('fs'); function readFileAsync(filepath) { - return new Promise(function (resolve, reject) { - fs.readFile(filepath, 'utf8', function (err, content) { - err ? reject(err) : resolve(content); - }); + return new Promise(function (resolve, reject) { + fs.readFile(filepath, 'utf8', function (err, content) { + err ? reject(err) : resolve(content); }); + }); }; function statFileAsync(path) { - return new Promise(function (resolve, reject) { - fs.stat(path, function (err, stat) { - return err ? reject(err) : resolve(stat); - }); + return new Promise(function (resolve, reject) { + fs.stat(path, function (err, stat) { + return err ? reject(err) : resolve(stat); }); + }); }; module.exports = { - readFileAsync: readFileAsync, - statFileAsync: statFileAsync + readFileAsync: readFileAsync, + statFileAsync: statFileAsync }; },{"fs":6}],19:[function(require,module,exports){ @@ -1469,233 +1482,233 @@ var Promise = require('any-promise'); * Call functions in serial until someone resolved. * @param {Array} iterable the array to iterate with. * @param {Array} iteratee returns a new promise. - * The iteratee is invoked with three arguments: (value, index, iterable). + * The iteratee is invoked with three arguments: (value, index, iterable). */ function anySeries(iterable, iteratee) { - var ret = Promise.reject(new Error('init')); - iterable.forEach(function (item, idx) { - ret = ret.catch(function (e) { - return iteratee(item, idx, iterable); - }); + var ret = Promise.reject(new Error('init')); + iterable.forEach(function (item, idx) { + ret = ret.catch(function (e) { + return iteratee(item, idx, iterable); }); - return ret; + }); + return ret; } /* * Call functions in serial until someone rejected. * @param {Array} iterable the array to iterate with. * @param {Array} iteratee returns a new promise. - * The iteratee is invoked with three arguments: (value, index, iterable). + * The iteratee is invoked with three arguments: (value, index, iterable). */ function mapSeries(iterable, iteratee) { - var ret = Promise.resolve('init'); - var result = []; - iterable.forEach(function (item, idx) { - ret = ret.then(function () { - return iteratee(item, idx, iterable); - }).then(function (x) { - return result.push(x); - }); - }); - return ret.then(function () { - return result; + var ret = Promise.resolve('init'); + var result = []; + iterable.forEach(function (item, idx) { + ret = ret.then(function () { + return iteratee(item, idx, iterable); + }).then(function (x) { + return result.push(x); }); + }); + return ret.then(function () { + return result; + }); } exports.anySeries = anySeries; exports.mapSeries = mapSeries; },{"any-promise":3}],20:[function(require,module,exports){ -"use strict"; +'use strict'; -var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; -var monthNamesShort = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; -var dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; -var dayNamesShort = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; +var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; +var monthNamesShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; +var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; +var dayNamesShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; var suffixes = { - 1: 'st', - 2: 'nd', - 3: 'rd', - 'default': 'th' + 1: 'st', + 2: 'nd', + 3: 'rd', + 'default': 'th' }; // prototype extensions var _date = { - daysInMonth: function daysInMonth(d) { - var feb = _date.isLeapYear(d) ? 29 : 28; - return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - }, + daysInMonth: function daysInMonth(d) { + var feb = _date.isLeapYear(d) ? 29 : 28; + return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + }, - getDayOfYear: function getDayOfYear(d) { - var num = 0; - for (var i = 0; i < d.getMonth(); ++i) { - num += _date.daysInMonth(d)[i]; - } - return num + d.getDate(); - }, - - // Startday is an integer of which day to start the week measuring from - // TODO: that comment was retarted. fix it. - getWeekOfYear: function getWeekOfYear(d, startDay) { - // Skip to startDay of this week - var now = this.getDayOfYear(d) + (startDay - d.getDay()); - // Find the first startDay of the year - var jan1 = new Date(d.getFullYear(), 0, 1); - var then = 7 - jan1.getDay() + startDay; - return _number.pad(Math.floor((now - then) / 7) + 1, 2); - }, - - isLeapYear: function isLeapYear(d) { - var year = d.getFullYear(); - return !!((year & 3) === 0 && (year % 100 || year % 400 === 0 && year)); - }, - - getSuffix: function getSuffix(d) { - var str = d.getDate().toString(); - var index = parseInt(str.slice(-1)); - return suffixes[index] || suffixes['default']; - }, - - century: function century(d) { - return parseInt(d.getFullYear().toString().substring(0, 2), 10); + getDayOfYear: function getDayOfYear(d) { + var num = 0; + for (var i = 0; i < d.getMonth(); ++i) { + num += _date.daysInMonth(d)[i]; } + return num + d.getDate(); + }, + + // Startday is an integer of which day to start the week measuring from + // TODO: that comment was retarted. fix it. + getWeekOfYear: function getWeekOfYear(d, startDay) { + // Skip to startDay of this week + var now = this.getDayOfYear(d) + (startDay - d.getDay()); + // Find the first startDay of the year + var jan1 = new Date(d.getFullYear(), 0, 1); + var then = 7 - jan1.getDay() + startDay; + return _number.pad(Math.floor((now - then) / 7) + 1, 2); + }, + + isLeapYear: function isLeapYear(d) { + var year = d.getFullYear(); + return !!((year & 3) === 0 && (year % 100 || year % 400 === 0 && year)); + }, + + getSuffix: function getSuffix(d) { + var str = d.getDate().toString(); + var index = parseInt(str.slice(-1)); + return suffixes[index] || suffixes['default']; + }, + + century: function century(d) { + return parseInt(d.getFullYear().toString().substring(0, 2), 10); + } }; var _number = { - pad: function pad(value, size, ch) { - if (!ch) ch = '0'; - var result = value.toString(); - var pad = size - result.length; + pad: function pad(value, size, ch) { + if (!ch) ch = '0'; + var result = value.toString(); + var pad = size - result.length; - while (pad-- > 0) { - result = ch + result; - } - - return result; + while (pad-- > 0) { + result = ch + result; } + + return result; + } }; -var format_codes = { - a: function a(d) { - return dayNamesShort[d.getDay()]; - }, - A: function A(d) { - return dayNames[d.getDay()]; - }, - b: function b(d) { - return monthNamesShort[d.getMonth()]; - }, - B: function B(d) { - return monthNames[d.getMonth()]; - }, - c: function c(d) { - return d.toLocaleString(); - }, - C: function C(d) { - return _date.century(d); - }, - d: function d(_d) { - return _number.pad(_d.getDate(), 2); - }, - e: function e(d) { - return _number.pad(d.getDate(), 2, ' '); - }, - H: function H(d) { - return _number.pad(d.getHours(), 2); - }, - I: function I(d) { - return _number.pad(d.getHours() % 12 || 12, 2); - }, - j: function j(d) { - return _number.pad(_date.getDayOfYear(d), 3); - }, - k: function k(d) { - return _number.pad(d.getHours(), 2, ' '); - }, - l: function l(d) { - return _number.pad(d.getHours() % 12 || 12, 2, ' '); - }, - L: function L(d) { - return _number.pad(d.getMilliseconds(), 3); - }, - m: function m(d) { - return _number.pad(d.getMonth() + 1, 2); - }, - M: function M(d) { - return _number.pad(d.getMinutes(), 2); - }, - p: function p(d) { - return d.getHours() < 12 ? 'AM' : 'PM'; - }, - P: function P(d) { - return d.getHours() < 12 ? 'am' : 'pm'; - }, - q: function q(d) { - return _date.getSuffix(d); - }, - s: function s(d) { - return Math.round(d.valueOf() / 1000); - }, - S: function S(d) { - return _number.pad(d.getSeconds(), 2); - }, - u: function u(d) { - return d.getDay() || 7; - }, - U: function U(d) { - return _date.getWeekOfYear(d, 0); - }, - w: function w(d) { - return d.getDay(); - }, - W: function W(d) { - return _date.getWeekOfYear(d, 1); - }, - x: function x(d) { - return d.toLocaleDateString(); - }, - X: function X(d) { - return d.toLocaleTimeString(); - }, - y: function y(d) { - return d.getFullYear().toString().substring(2, 4); - }, - Y: function Y(d) { - return d.getFullYear(); - }, - z: function z(d) { - var tz = d.getTimezoneOffset() / 60 * 100; - return (tz > 0 ? '-' : '+') + _number.pad(Math.abs(tz), 4); - }, - "%": function _() { - return '%'; - } +var formatCodes = { + a: function a(d) { + return dayNamesShort[d.getDay()]; + }, + A: function A(d) { + return dayNames[d.getDay()]; + }, + b: function b(d) { + return monthNamesShort[d.getMonth()]; + }, + B: function B(d) { + return monthNames[d.getMonth()]; + }, + c: function c(d) { + return d.toLocaleString(); + }, + C: function C(d) { + return _date.century(d); + }, + d: function d(_d) { + return _number.pad(_d.getDate(), 2); + }, + e: function e(d) { + return _number.pad(d.getDate(), 2, ' '); + }, + H: function H(d) { + return _number.pad(d.getHours(), 2); + }, + I: function I(d) { + return _number.pad(d.getHours() % 12 || 12, 2); + }, + j: function j(d) { + return _number.pad(_date.getDayOfYear(d), 3); + }, + k: function k(d) { + return _number.pad(d.getHours(), 2, ' '); + }, + l: function l(d) { + return _number.pad(d.getHours() % 12 || 12, 2, ' '); + }, + L: function L(d) { + return _number.pad(d.getMilliseconds(), 3); + }, + m: function m(d) { + return _number.pad(d.getMonth() + 1, 2); + }, + M: function M(d) { + return _number.pad(d.getMinutes(), 2); + }, + p: function p(d) { + return d.getHours() < 12 ? 'AM' : 'PM'; + }, + P: function P(d) { + return d.getHours() < 12 ? 'am' : 'pm'; + }, + q: function q(d) { + return _date.getSuffix(d); + }, + s: function s(d) { + return Math.round(d.valueOf() / 1000); + }, + S: function S(d) { + return _number.pad(d.getSeconds(), 2); + }, + u: function u(d) { + return d.getDay() || 7; + }, + U: function U(d) { + return _date.getWeekOfYear(d, 0); + }, + w: function w(d) { + return d.getDay(); + }, + W: function W(d) { + return _date.getWeekOfYear(d, 1); + }, + x: function x(d) { + return d.toLocaleDateString(); + }, + X: function X(d) { + return d.toLocaleTimeString(); + }, + y: function y(d) { + return d.getFullYear().toString().substring(2, 4); + }, + Y: function Y(d) { + return d.getFullYear(); + }, + z: function z(d) { + var tz = d.getTimezoneOffset() / 60 * 100; + return (tz > 0 ? '-' : '+') + _number.pad(Math.abs(tz), 4); + }, + '%': function _() { + return '%'; + } }; -format_codes.h = format_codes.b; -format_codes.N = format_codes.L; +formatCodes.h = formatCodes.b; +formatCodes.N = formatCodes.L; var strftime = function strftime(d, format) { - var output = ''; - var remaining = format; + var output = ''; + var remaining = format; - while (true) { - var r = /%./g; - var results = r.exec(remaining); + while (true) { + var r = /%./g; + var results = r.exec(remaining); - // No more format codes. Add the remaining text and return - if (!results) { - return output + remaining; - } - - // Add the preceding text - output += remaining.slice(0, r.lastIndex - 2); - remaining = remaining.slice(r.lastIndex); - - // Add the format code - var ch = results[0].charAt(1); - var func = format_codes[ch]; - output += func ? func.call(this, d) : '%' + ch; + // No more format codes. Add the remaining text and return + if (!results) { + return output + remaining; } + + // Add the preceding text + output += remaining.slice(0, r.lastIndex - 2); + remaining = remaining.slice(r.lastIndex); + + // Add the format code + var ch = results[0].charAt(1); + var func = formatCodes[ch]; + output += func ? func.call(this, d) : '%' + ch; + } }; module.exports = strftime; @@ -1711,37 +1724,37 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol * @return {Boolean} Returns true if value is a string, else false. */ function isString(value) { - return value instanceof String || typeof value === 'string'; + return value instanceof String || typeof value === 'string'; } function isError(value) { - var signature = Object.prototype.toString.call(value); - // [object XXXError] - return signature.substr(-6, 5) === 'Error' || typeof value.message == 'string' && typeof value.name == 'string'; + var signature = Object.prototype.toString.call(value); + // [object XXXError] + return signature.substr(-6, 5) === 'Error' || typeof value.message === 'string' && typeof value.name === 'string'; } /* - * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property. - * The iteratee is invoked with three arguments: (value, key, object). + * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property. + * The iteratee is invoked with three arguments: (value, key, object). * Iteratee functions may exit iteration early by explicitly returning false. * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @return {Object} Returns object. */ function forOwn(object, iteratee) { - object = object || {}; - for (var k in object) { - if (object.hasOwnProperty(k)) { - if (iteratee(object[k], k, object) === false) break; - } + object = object || {}; + for (var k in object) { + if (object.hasOwnProperty(k)) { + if (iteratee(object[k], k, object) === false) break; } - return object; + } + return object; } /* - * Assigns own enumerable string keyed properties of source objects to the destination object. - * Source objects are applied from left to right. - * Subsequent sources overwrite property assignments of previous sources. + * Assigns own enumerable string keyed properties of source objects to the destination object. + * Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. * * Note: This method mutates object and is loosely based on Object.assign. * @@ -1750,76 +1763,76 @@ function forOwn(object, iteratee) { * @return {Object} Returns object. */ function assign(object) { - object = isObject(object) ? object : {}; - var srcs = Array.prototype.slice.call(arguments, 1); - srcs.forEach(function (src) { - _assignBinary(object, src); - }); - return object; + object = isObject(object) ? object : {}; + var srcs = Array.prototype.slice.call(arguments, 1); + srcs.forEach(function (src) { + _assignBinary(object, src); + }); + return object; } function _assignBinary(dst, src) { - if (!dst) return dst; - forOwn(src, function (v, k) { - dst[k] = v; - }); - return dst; + if (!dst) return dst; + forOwn(src, function (v, k) { + dst[k] = v; + }); + return dst; } function isArray(value) { - return value instanceof Array; + return value instanceof Array; } function echo(prefix) { - return function (v) { - console.log('[' + prefix + ']', v); - return v; - }; + return function (v) { + console.log('[' + prefix + ']', v); + return v; + }; } function uniq(arr) { - var u = {}, - a = []; - for (var i = 0, l = arr.length; i < l; ++i) { - if (u.hasOwnProperty(arr[i])) { - continue; - } - a.push(arr[i]); - u[arr[i]] = 1; + var u = {}; + var a = []; + for (var i = 0, l = arr.length; i < l; ++i) { + if (u.hasOwnProperty(arr[i])) { + continue; } - return a; + a.push(arr[i]); + u[arr[i]] = 1; + } + return a; } /* - * Checks if value is the language type of Object. + * Checks if value is the language type of Object. * (e.g. arrays, functions, objects, regexes, new Number(0), and new String('')) * @param {any} value The value to check. * @return {Boolean} Returns true if value is an object, else false. */ function isObject(value) { - return value !== null && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object'; + return value !== null && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object'; } /* - * A function to create flexibly-numbered lists of integers, - * handy for each and map loops. start, if omitted, defaults to 0; step defaults to 1. - * Returns a list of integers from start (inclusive) to stop (exclusive), - * incremented (or decremented) by step, exclusive. - * Note that ranges that stop before they start are considered to be zero-length instead of + * A function to create flexibly-numbered lists of integers, + * handy for each and map loops. start, if omitted, defaults to 0; step defaults to 1. + * Returns a list of integers from start (inclusive) to stop (exclusive), + * incremented (or decremented) by step, exclusive. + * Note that ranges that stop before they start are considered to be zero-length instead of * negative — if you'd like a negative range, use a negative step. */ function range(start, stop, step) { - if (arguments.length === 1) { - stop = start; - start = 0; - } - step = step || 1; + if (arguments.length === 1) { + stop = start; + start = 0; + } + step = step || 1; - var arr = []; - for (var i = start; i < stop; i += step) { - arr.push(i); - } - return arr; + var arr = []; + for (var i = start; i < stop; i += step) { + arr.push(i); + } + return arr; } exports.isString = isString; @@ -2052,93 +2065,93 @@ var assert = require('../src/util/assert.js'); var re = new RegExp('^(' + lexical.identifier.source + ')\\s+in\\s+' + ('(' + lexical.value.source + ')') + ('(?:\\s+' + lexical.hash.source + ')*') + '(?:\\s+(reversed))?' + ('(?:\\s+' + lexical.hash.source + ')*$')); module.exports = function (liquid) { - liquid.registerTag('for', { + liquid.registerTag('for', { - 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]; - this.reversed = !!match[3]; + var match = re.exec(tagToken.args); + assert(match, 'illegal tag: ' + tagToken.raw); + this.variable = match[1]; + this.collection = match[2]; + this.reversed = !!match[3]; - this.templates = []; - this.elseTemplates = []; + this.templates = []; + this.elseTemplates = []; - var p, - stream = liquid.parser.parseStream(remainTokens).on('start', function () { - return p = _this.templates; - }).on('tag:else', function () { - return p = _this.elseTemplates; - }).on('tag:endfor', function () { - return stream.stop(); - }).on('template', function (tpl) { - return p.push(tpl); - }).on('end', function () { - 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:else', function () { + return p = _this.elseTemplates; + }).on('tag:endfor', function () { + 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); - if (!Array.isArray(collection) || Array.isArray(collection) && collection.length === 0) { - return liquid.renderer.renderTemplates(this.elseTemplates, scope); - } + if (!Array.isArray(collection) || Array.isArray(collection) && collection.length === 0) { + return liquid.renderer.renderTemplates(this.elseTemplates, scope); + } - var length = collection.length; - var offset = hash.offset || 0; - var limit = hash.limit === undefined ? collection.length : hash.limit; + var length = collection.length; + var offset = hash.offset || 0; + var limit = hash.limit === undefined ? collection.length : hash.limit; - collection = collection.slice(offset, offset + limit); - if (this.reversed) collection.reverse(); + collection = collection.slice(offset, offset + limit); + if (this.reversed) collection.reverse(); - var contexts = collection.map(function (item, i) { - var ctx = {}; - ctx[_this2.variable] = item; - ctx.forloop = { - first: i === 0, - index: i + 1, - index0: i, - last: i === length - 1, - length: length, - rindex: length - i, - rindex0: length - i - 1, - stop: false, - skip: false - }; - return ctx; - }); + var contexts = collection.map(function (item, i) { + var ctx = {}; + ctx[_this2.variable] = item; + ctx.forloop = { + first: i === 0, + index: i + 1, + index0: i, + last: i === length - 1, + length: length, + rindex: length - i, + rindex0: length - i - 1, + stop: false, + skip: false + }; + return ctx; + }); - var html = ''; - return mapSeries(contexts, function (context) { - scope.push(context); - return liquid.renderer.renderTemplates(_this2.templates, scope).then(function (partial) { - return html += partial; - }).catch(function (e) { - if (e instanceof RenderBreakError) { - html += e.resolvedHTML; - if (e.message === 'continue') return; - } - throw e; - }).then(function () { - return scope.pop(); - }); - }).catch(function (e) { - if (e instanceof RenderBreakError && e.message === 'break') { - return; - } - throw e; - }).then(function () { - return html; - }); + var html = ''; + return mapSeries(contexts, function (context) { + scope.push(context); + return liquid.renderer.renderTemplates(_this2.templates, scope).then(function (partial) { + return html += partial; + }).catch(function (e) { + if (e instanceof RenderBreakError) { + html += e.resolvedHTML; + if (e.message === 'continue') return; + } + throw e; + }).then(function () { + return scope.pop(); + }); + }).catch(function (e) { + if (e instanceof RenderBreakError && e.message === 'break') { + return; } - }); + throw e; + }).then(function () { + return html; + }); + } + }); }; },{"..":2,"../src/util/assert.js":16,"../src/util/promise.js":19}],29:[function(require,module,exports){ @@ -2368,28 +2381,27 @@ module.exports = function (liquid) { var Promise = require('any-promise'); module.exports = function (liquid) { + liquid.registerTag('raw', { + parse: function parse(tagToken, remainTokens) { + var _this = this; - liquid.registerTag('raw', { - parse: function parse(tagToken, remainTokens) { - var _this = this; + this.tokens = []; - this.tokens = []; - - var stream = liquid.parser.parseStream(remainTokens); - stream.on('token', function (token) { - if (token.name === 'endraw') stream.stop();else _this.tokens.push(token); - }).on('end', function (x) { - throw new Error('tag ' + tagToken.raw + ' not closed'); - }); - stream.start(); - }, - render: function render(scope, hash) { - var tokens = this.tokens.map(function (token) { - return token.raw; - }).join(''); - return Promise.resolve(tokens); - } - }); + var stream = liquid.parser.parseStream(remainTokens); + stream.on('token', function (token) { + if (token.name === 'endraw') stream.stop();else _this.tokens.push(token); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + stream.start(); + }, + render: function render(scope, hash) { + var tokens = this.tokens.map(function (token) { + return token.raw; + }).join(''); + return Promise.resolve(tokens); + } + }); }; },{"any-promise":3}],35:[function(require,module,exports){ diff --git a/dist/liquid.min.js b/dist/liquid.min.js index 64f196811..ade400891 100644 --- a/dist/liquid.min.js +++ b/dist/liquid.min.js @@ -1,3 +1,3 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.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?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 p[e]})}function n(e){return o(e).replace(/&(amp|lt|gt|#34|#39);/g,function(e){return h[e]})}function s(e){var r=(e+"").split(".");return r.length>1?r[1].length:0}function i(e,r){return Math.max(s(e),s(r))}function o(e){return e=e||"",e+""}function u(e){return function(r,t){var n=i(r,t);return e(r,t).toFixed(n)}}function a(e){return l.forOwn(g,function(r,t){return e.registerFilter(t,r)})}var c=e("./src/util/strftime.js"),l=e("./src/util/underscore.js"),f=e("./src/syntax.js").isTruthy,p={"&":"&","<":"<",">":">",'"':""","'":"'"},h={"&":"&","<":"<",">":">",""":'"',"'":"'"},g={abs:function(e){return Math.abs(e)},append:function(e,r){return e+r},capitalize:function(e){return o(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?c(e,r):""},"default":function(e,r){return f(e)?e:r},divided_by:function(e,r){return Math.floor(e/r)},downcase:function(e){return e.toLowerCase()},escape:t,escape_once:function(e){return t(n(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 o(e).replace(/^\s+/,"")},map:function(e,r){return e.map(function(e){return e[r]})},minus:u(function(e,r){return e-r}),modulo:u(function(e,r){return e%r}),newline_to_br:function(e){return e.replace(/\n/g,"
")},plus:u(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 o(e).split(r).join(t)},replace_first:function(e,r,t){return o(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 o(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 o(e).split(r)},strip:function(e){return o(e).trim()},strip_html:function(e){return o(e).replace(/<\/?\s*\w+\s*\/?>/g,"")},strip_newlines:function(e){return o(e).replace(/\n/g,"")},times:function(e,r){return e*r},truncate:function(e,r,t){return e=o(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)?!1:(r[e]=!0,!0)})},upcase:function(e){return o(e).toUpperCase()},url_encode:encodeURIComponent};a.filters=g,r.exports=a},{"./src/syntax.js":13,"./src/util/strftime.js":20,"./src/util/underscore.js":21}],2:[function(e,r){"use strict";function t(e){e=i.assign({root:["."],cache:!1,extname:".liquid",trim_right:!1,trim_left:!1,strict_filters:!1,strict_variables:!1},e),e.root=n(e.root);var r=Object.create(b);return r.init(h(),g(e),e),r}function n(e){return i.isArray(e)?e:i.isString(e)?[e]:[]}var s=e("./src/scope"),i=e("./src/util/underscore.js"),o=e("./src/util/assert.js"),u=e("./src/tokenizer.js"),a=e("./src/util/fs.js").statFileAsync,c=e("./src/util/fs.js").readFileAsync,l=e("path"),f=e("./src/render.js"),p=e("./src/lexical.js"),h=e("./src/tag.js"),g=e("./src/filter.js"),d=e("./src/parser"),v=e("./src/syntax.js"),m=e("./tags"),y=e("./filters"),j=e("any-promise"),w=e("./src/util/promise.js").anySeries,x=e("./src/util/error.js"),b={init:function(e,r,t){return t.cache&&(this.cache={}),this.options=t,this.tag=e,this.filter=r,this.parser=d(e,r),this.renderer=f(),m(this),y(this),this},parse:function(e,r){var t=u.parse(e,r,this.options);return this.parser.parse(t)},render:function(e,r,t){t=i.assign({},this.options,t);var n=s.factory(r,t);return this.renderer.renderTemplates(e,n)},parseAndRender:function(e,r,t){var n=this;return j.resolve().then(function(){return n.parse(e)}).then(function(e){return n.render(e,r,t)})["catch"](function(e){if(e instanceof x.RenderBreakError)return e.html;throw e})},renderFile:function(e,r,t){var n=this;return t=i.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||[]),r=i.uniq(r);var t=r.map(function(r){return l.resolve(r,e)});return w(t,function(e){return a(e).then(function(){return e})})["catch"](function(t){throw"ENOENT"===t.code&&(t.message="Failed to lookup "+e+" in: "+r),t})},getTemplate:function(e,r){var t=this;return l.extname(e)||(e+=this.options.extname),this.lookup(e,r).then(function(e){if(t.options.cache){var r=t.cache[e];return r?j.resolve(r):c(e).then(function(e){return t.parse(e)}).then(function(r){return t.cache[e]=r})}return c(e).then(function(r){return t.parse(r,e)})})},express:function(e){e=e||{};var r=this;return function(t,n,s){o(i.isArray(this.root)||i.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)})}}};t.lexical=p,t.isTruthy=v.isTruthy,t.isFalsy=v.isFalsy,t.evalExp=v.evalExp,t.evalValue=v.evalValue,t.Types={ParseError:x.ParseError,TokenizationEroor:x.TokenizationError,RenderBreakError:x.RenderBreakError,AssertionError:x.AssertionError},r.exports=t},{"./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){"use strict";r.exports=e("./register")().Promise},{"./register":5}],4:[function(e,r){"use strict";var t="@@any-promise/REGISTRATION",n=null;r.exports=function(e,r){return function(s,i){s=s||null,i=i||{};var o=i.global!==!1;if(null===n&&o&&(n=e[t]||null),null!==n&&null!==s&&n.implementation!==s)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!==s&&"undefined"!=typeof i.Promise?{Promise:i.Promise,implementation:s}:r(s),o&&(e[t]=n)),n}}},{}],5:[function(e,r){"use strict";function t(){if("undefined"==typeof 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"}}r.exports=e("./loader")(window,t)},{"./loader":4}],6:[function(){"use strict"},{}],7:[function(e,r){"use strict";var t=e("./lexical.js"),n=e("./syntax.js"),s=e("./util/assert.js"),i=e("./util/underscore.js"),o=new RegExp(""+t.value.source,"g");r.exports=function(e){function r(e){var r=Object.create(l);return r.parse(e)}function u(e,r){c[e]=r}function a(){c={}}e=i.assign({},e);var c={},l={render:function(e,r){var t=this.args.map(function(e){return n.evalValue(e,r)});return t.unshift(e),this.filter.apply(null,t)},parse:function(r){var n=t.filterLine.exec(r);s(n,"illegal filter: "+r);var i=n[1],u=n[2]||"",a=c[i];if("function"!=typeof a){if(e.strict_filters)throw new TypeError("undefined filter: "+i);return this.name=i,this.filter=function(e){return e},this.args=[],this}for(var l=[];n=o.exec(u.trim());){var f=n[0],p=new RegExp(f+"\\s*:","g");l.push(p.test(n.input)?"'"+f+"'":f)}return this.name=i,this.filter=a,this.args=l,this}};return{construct:r,register:u,clear:a}}},{"./lexical.js":8,"./syntax.js":13,"./util/assert.js":16,"./util/underscore.js":21}],8:[function(e,r){"use strict";function t(e){return q.test(e)}function n(e){return S.test(e)}function s(e){return P.test(e)}function i(e){return R.test(e)}function o(e){return b.exec(e)}function u(e){var r;return(r=e.match(O))?Number(e):(r=e.match(M))?"true"===e.toLowerCase():(r=e.match(A))?e.slice(1,-1):void 0}var a=/'[^']*'/,c=/"[^"]*"/,l=new RegExp(a.source+"|"+c.source),f=new RegExp("(?:"+l.source+"|[^'\"])*"),p=/-?\d+/,h=/-?\d+\.?\d*|\.?\d+/,g=/true|false/,d=/[\w-]+/,v=new RegExp("\\[(?:"+l.source+"|[\\w-\\.]+)\\]"),m=new RegExp("(?:"+l.source+"|"+g.source+"|"+h.source+")"),y=new RegExp(d.source+"(?:\\."+d.source+"|"+v.source+")*"),j=new RegExp("(?:"+y.source+"|"+h.source+")"),w=new RegExp("\\("+j.source+"\\.\\."+j.source+"\\)"),x=new RegExp("\\(("+j.source+")\\.\\.("+j.source+")\\)"),b=new RegExp("(?:"+y.source+"|"+m.source+"|"+w.source+")"),E=new RegExp("(?:"+d.source+")\\s*:\\s*(?:"+b.source+")"),T=new RegExp("("+d.source+")\\s*:\\s*("+b.source+")","g"),k=new RegExp("^\\s*("+d.source+")\\s*([\\s\\S]*)\\s*$"),S=new RegExp("^"+m.source+"$","i"),R=new RegExp("^"+y.source+"$"),O=new RegExp("^"+h.source+"$"),M=new RegExp("^"+g.source+"$","i"),A=new RegExp("^"+l.source+"$"),P=new RegExp("^"+x.source+"$"),q=new RegExp("^"+p.source+"$"),L=new RegExp("(?:"+d.source+"\\s*:\\s*)?"+b.source),F=new RegExp(L.source+"(\\s*,\\s*"+L.source+")*"),_=new RegExp(d.source+"(?:\\s*:\\s*"+F.source+")?","g"),D=new RegExp("("+d.source+")(?:\\s*:\\s*("+F.source+"))?"),I=new RegExp("^"+D.source+"$"),$=[/\s+or\s+/,/\s+and\s+/,/==|!=|<=|>=|<|>|\s+contains\s+/];r.exports={quoted:l,number:h,bool:g,literal:m,filter:_,integer:p,hash:E,hashCapture:T,range:w,rangeCapture:x,identifier:d,value:b,quoteBalanced:f,operators:$,quotedLine:A,numberLine:O,boolLine:M,rangeLine:P,literalLine:S,filterLine:I,tagLine:k,isLiteral:n,isVariable:i,parseLiteral:u,isRange:s,matchValue:o,isInteger:t}},{}],9:[function(e,r){"use strict";var t={"==":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&&r>e},">=":function(e,r){return null!==e&&null!==r&&e>=r},"<=":function(e,r){return null!==e&&null!==r&&r>=e},contains:function(e,r){return e?"function"!=typeof e.indexOf?!1:e.indexOf(r)>-1:!1},and:function(e,r){return e&&r},or:function(e,r){return e||r}};r.exports=t},{}],10:[function(e,r){"use strict";var t=e("./lexical.js"),n=e("./util/error.js").ParseError,s=e("./util/assert.js");r.exports=function(e,r){function i(e){for(var r,t=[];r=e.shift();)t.push(o(r,e));return t}function o(e,r){try{var t=null;return t="tag"===e.type?u(e,r):"output"===e.type?a(e.value):e,t.token=e,t}catch(s){throw new n(s,e)}}function u(r,t){return"continue"===r.name||"break"===r.name?r:e.construct(r,t)}function a(e){var n=t.matchValue(e);s(n,"illegal output string: "+e);var i=n[0];e=e.substr(n.index+n[0].length);for(var o=[];n=t.filter.exec(e);)o.push([n[0].trim()]);return{type:"output",initial:i,filters:o.map(function(e){return r.construct(e)})}}function c(e){var r=Object.create(l);return r.init(e)}var l={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];return"function"==typeof t?(t(r),!0):void 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=o(e,this.tokens);this.trigger("template",r)}return this.stopRequested||this.trigger("end"),this},stop:function(){return this.stopRequested=!0,this}};return{parse:i,parseTag:u,parseStream:c,parseOutput:a}}},{"./lexical.js":8,"./util/assert.js":16,"./util/error.js":17}],11:[function(e,r){"use strict";function t(){var e=Object.create(l);return e}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=t},{"./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){for(var t=1,n=r;n=0;r--)s.assign(e,this.scopes[r]);return e},get:function(e){for(var r=this.scopes.length-1;r>=0;r--)try{return this.getPropertyByPath(this.scopes[r],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,r){return this.setPropertyByPath(this.scopes[this.scopes.length-1],e,r),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,r,t){if(s.isString(r))for(var n=r.replace(/\[/g,".").replace(/\]/g,"").split("."),i=0;i=y;y++)m.push(y);return m}return n(e,r)}function n(e,r){return e=e&&e.trim(),e?u.isLiteral(e)?u.parseLiteral(e):u.isVariable(e)?r.get(e):void 0:void 0}function s(e){return!i(e)}function i(e){return!1===e||void 0===e||null===e}var o=e("./operators.js"),u=e("./lexical.js"),a=e("../src/util/assert.js");r.exports={evalExp:t,evalValue:n,isTruthy:s,isFalsy:i}},{"../src/util/assert.js":16,"./lexical.js":8,"./operators.js":9}],14:[function(e,r){"use strict";function t(e,r){var t,s={};for(n.hashCapture.lastIndex=0;t=n.hashCapture.exec(e);){var i=t[1],u=t[2];s[i]=o.evalValue(u,r)}return s}var n=e("./lexical.js"),s=e("./util/underscore.js"),i=e("any-promise"),o=e("./syntax.js"),u=e("./util/assert.js");r.exports=function(){function e(e,r){o[e]=r}function r(e,r){var t=Object.create(a);return t.parse(e,r),t}function n(){o={}}var o={},a={render:function(e){var r=t(this.token.args,e),n=this.tagImpl;return"function"!=typeof n.render?i.resolve(""):i.resolve().then(function(){return"function"==typeof n.render?n.render(e,r):""})["catch"](function(e){if(s.isError(e))throw e;var r="Please reject with an Error in "+n.render+", got "+e;throw new Error(r)})},parse:function(e,r){this.type="tag",this.token=e,this.name=e.name;var t=o[this.name];u(t,"tag "+this.name+" not found"),this.tagImpl=Object.create(t),this.tagImpl.parse&&this.tagImpl.parse(e,r)}};return{construct:r,register:e,clear:n}}},{"./lexical.js":8,"./syntax.js":13,"./util/assert.js":16,"./util/underscore.js":21,"any-promise":3}],15:[function(e,r,t){"use strict";function n(e,r,t){function n(t,n,s){return{type:t,raw:s[n],value:s[n+1].trim(),line:c(s),input:e,file:r}}function c(e){var r=e.input.slice(v+1,e.index).split("\n");return m+=r.length-1,v=e.index,m+1}a(u.isString(e),"illegal input type"),e=s(e,t);for(var l,f,p,h=[],g=/({%-?([\s\S]*?)-?%})|({{([\s\S]*?)}})/g,d=0,v=-1,m=0;null!==(l=g.exec(e));){if(l.index>d&&(f=e.slice(d,l.index),h.push({type:"html",raw:f,value:f})),l[1]){p=n("tag",1,l);var y=p.value.match(i.tagLine);if(!y)throw new o("illegal tag syntax",p);p.name=y[1],p.args=y[2],h.push(p)}else p=n("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}function s(e,r){r=r||{},r.trim_left&&(e=e.replace(/{%-?/g,"{%-")),r.trim_right&&(e=e.replace(/-?%}/g,"-%}"));var t=r.greedy?/\s+({%-)/g:/[\t\r ]*({%-)/g,n=r.greedy?/(-%})\s+/g:/(-%})[\t\r ]*\n?/g;return e.replace(t,"$1").replace(n,"$1")}var i=e("./lexical.js"),o=e("./util/error.js").TokenizationError,u=e("./util/underscore.js"),a=e("../src/util/assert.js");t.parse=n,t.whiteSpaceCtrl=s},{"../src/util/assert.js":16,"./lexical.js":8,"./util/error.js":17,"./util/underscore.js":21}],16:[function(e,r){"use strict";function t(e,r){if(!e){if(r instanceof Error)throw r;var r=r||"expect "+e+" to be true";throw new n(r)}}var n=e("./error.js").AssertionError;r.exports=t},{"./error.js":17}],17:[function(e,r){"use strict";function t(e,r){Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.input=r.input,this.line=r.line,this.file=r.file;var t=u(r.input,r.line);this.message=c(e,r),this.stack=t+"\n"+(this.stack||"")}function n(e,r){l.assign(this,e),this.originalError=e,this.name=this.constructor.name,this.input=r.input,this.line=r.line,this.file=r.file;var t=u(r.input,r.line);this.message=c(e.message||"Unkown Error",r),this.stack=t+"\n"+(e.stack||"")}function s(e,r){if(e instanceof s)return e;l.assign(this,e),this.originalError=e,this.name=this.constructor.name,this.input=r.token.input,this.line=r.token.line,this.file=r.token.file;var t=u(r.token.input,r.token.line);this.message=c(e.message||"Unkown Error",r.token),this.stack=t+"\n"+(e.stack||"")}function i(e){Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||""}function o(e){Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e}function u(e,r){var t=e.split("\n"),n=Math.max(r-2,1),s=Math.min(r+3,t.length),i=l.range(n,s+1).map(function(e){return[e===r?">> ":" ",a(e,s),"| ",t[e-1]].join("")}).join("\n");return i}function a(e,r){var t=(r+"").length,n=e+"",s=Array(t-n.length).join(" ");return s+n}function c(e,r){return e=e||"",r.file&&(e+=", file:"+r.file),r.line&&(e+=", line:"+r.line),e}var l=e("./underscore.js");t.prototype=Object.create(Error.prototype),t.prototype.constructor=t,n.prototype=Object.create(Error.prototype),n.prototype.constructor=n,s.prototype=Object.create(Error.prototype),s.prototype.constructor=s,i.prototype=Object.create(Error.prototype),i.prototype.constructor=i,o.prototype=Object.create(Error.prototype),o.prototype.constructor=o,r.exports={TokenizationError:t,ParseError:n,RenderBreakError:i,AssertionError:o,RenderError:s}},{"./underscore.js":21}],18:[function(e,r){"use strict";function t(e){return new Promise(function(r,t){s.readFile(e,"utf8",function(e,n){e?t(e):r(n)})})}function n(e){return new Promise(function(r,t){s.stat(e,function(e,n){return e?t(e):r(n)})})}var s=e("fs");r.exports={readFileAsync:t,statFileAsync:n}},{fs:6}],19:[function(e,r,t){"use strict";function n(e,r){var t=i.reject(new Error("init"));return e.forEach(function(n,s){t=t["catch"](function(){return r(n,s,e)})}),t}function s(e,r){var t=i.resolve("init"),n=[];return e.forEach(function(s,i){t=t.then(function(){return r(s,i,e)}).then(function(e){return n.push(e)})}),t.then(function(){return n})}var i=e("any-promise");t.anySeries=n,t.mapSeries=s},{"any-promise":3}],20:[function(e,r){"use strict";var t=["January","February","March","April","May","June","July","August","September","October","November","December"],n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],s=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],i=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],o={1:"st",2:"nd",3:"rd","default":"th"},u={daysInMonth:function(e){var r=u.isLeapYear(e)?29:28;return[31,r,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}},c={a:function(e){return i[e.getDay()]},A:function(e){return s[e.getDay()]},b:function(e){return n[e.getMonth()]},B:function(e){return t[e.getMonth()]},c:function(e){return e.toLocaleString()},C:function(e){return u.century(e)},d:function(e){return a.pad(e.getDate(),2)},e:function(e){return a.pad(e.getDate(),2," ")},H:function(e){return a.pad(e.getHours(),2)},I:function(e){return a.pad(e.getHours()%12||12,2)},j:function(e){return a.pad(u.getDayOfYear(e),3)},k:function(e){return a.pad(e.getHours(),2," ")},l:function(e){return a.pad(e.getHours()%12||12,2," ")},L:function(e){return a.pad(e.getMilliseconds(),3)},m:function(e){return a.pad(e.getMonth()+1,2)},M:function(e){return a.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 u.getSuffix(e)},s:function(e){return Math.round(e.valueOf()/1e3)},S:function(e){return a.pad(e.getSeconds(),2)},u:function(e){return e.getDay()||7},U:function(e){return u.getWeekOfYear(e,0)},w:function(e){return e.getDay()},W:function(e){return u.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(r>0?"-":"+")+a.pad(Math.abs(r),4)},"%":function(){return"%"}};c.h=c.b,c.N=c.L;var l=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=c[o];t+=u?u.call(this,e):"%"+o}};r.exports=l},{}],21:[function(e,r,t){"use strict";function n(e){return e instanceof String||"string"==typeof e}function s(e){var r=Object.prototype.toString.call(e);return"Error"===r.substr(-6,5)||"string"==typeof e.message&&"string"==typeof e.name}function i(e,r){e=e||{};for(var t in e)if(e.hasOwnProperty(t)&&r(e[t],t,e)===!1)break;return e}function o(e){e=f(e)?e:{};var r=Array.prototype.slice.call(arguments,1);return r.forEach(function(r){u(e,r)}),e}function u(e,r){return e?(i(r,function(r,t){e[t]=r}),e):e}function a(e){return e instanceof Array}function c(e){return function(r){return console.log("["+e+"]",r),r}}function l(e){for(var r={},t=[],n=0,s=e.length;s>n;++n)r.hasOwnProperty(e[n])||(t.push(e[n]),r[e[n]]=1);return t}function f(e){return null!==e&&"object"===("undefined"==typeof e?"undefined":h(e))}function p(e,r,t){1===arguments.length&&(r=e,e=0),t=t||1;for(var n=[],s=e;r>s;s+=t)n.push(s);return n}var h="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};t.isString=n,t.isArray=a,t.isObject=f,t.isError=s,t.range=p,t.forOwn=i,t.assign=o,t.uniq=l,t.echo=c},{}],22:[function(e,r){"use strict";var t=e(".."),n=t.lexical,s=e("any-promise"),i=new RegExp("("+n.identifier.source+")\\s*=(.*)"),o=e("../src/util/assert.js");r.exports=function(e){e.registerTag("assign",{parse:function(e){var r=e.args.match(i);o(r,"illegal token "+e.raw),this.key=r[1],this.value=r[2]},render:function(r){return r.set(this.key,e.evalOutput(this.value,r)),s.resolve("")}})}},{"..":2,"../src/util/assert.js":16,"any-promise":3}],23:[function(e,r){"use strict";var t=e(".."),n=t.lexical,s=new RegExp("("+n.identifier.source+")"),i=e("../src/util/assert.js");r.exports=function(e){e.registerTag("capture",{parse:function(r,t){var n=this,o=r.args.match(s);i(o,r.args+" not valid identifier"),this.variable=o[1],this.templates=[];var u=e.parser.parseStream(t);u.on("tag:endcapture",function(){return u.stop()}).on("template",function(e){return n.templates.push(e)}).on("end",function(){throw new Error("tag "+r.raw+" not closed")}),u.start()},render:function(r){var t=this;return e.renderer.renderTemplates(this.templates,r).then(function(e){r.set(t.variable,e)})}})}},{"..":2,"../src/util/assert.js":16}],24:[function(e,r){"use strict";{var t=e("..");e("../src/util/assert.js")}r.exports=function(e){e.registerTag("case",{parse:function(r,t){var n=this;this.cond=r.args,this.cases=[],this.elseTemplates=[];var s=[],i=e.parser.parseStream(t).on("tag:when",function(e){n.cases[e.args]||n.cases.push({val:e.args,templates:s=[]})}).on("tag:else",function(){return s=n.elseTemplates}).on("tag:endcase",function(){return i.stop()}).on("template",function(e){return s.push(e)}).on("end",function(){throw new Error("tag "+r.raw+" not closed")});i.start()},render:function(r){for(var n=0;n|"|'/g,function(e){return p[e]})}function n(e){return o(e).replace(/&(amp|lt|gt|#34|#39);/g,function(e){return h[e]})}function s(e){var r=(e+"").split(".");return r.length>1?r[1].length:0}function i(e,r){return Math.max(s(e),s(r))}function o(e){return e=e||"",e+""}function u(e){return function(r,t){var n=i(r,t);return e(r,t).toFixed(n)}}function a(e){return l.forOwn(g,function(r,t){return e.registerFilter(t,r)})}var c=e("./src/util/strftime.js"),l=e("./src/util/underscore.js"),f=e("./src/syntax.js").isTruthy,p={"&":"&","<":"<",">":">",'"':""","'":"'"},h={"&":"&","<":"<",">":">",""":'"',"'":"'"},g={abs:function(e){return Math.abs(e)},append:function(e,r){return e+r},capitalize:function(e){return o(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?c(e,r):""},"default":function(e,r){return f(e)?e:r},divided_by:function(e,r){return Math.floor(e/r)},downcase:function(e){return e.toLowerCase()},escape:t,escape_once:function(e){return t(n(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 o(e).replace(/^\s+/,"")},map:function(e,r){return e.map(function(e){return e[r]})},minus:u(function(e,r){return e-r}),modulo:u(function(e,r){return e%r}),newline_to_br:function(e){return e.replace(/\n/g,"
")},plus:u(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 o(e).split(r).join(t)},replace_first:function(e,r,t){return o(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 o(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 o(e).split(r)},strip:function(e){return o(e).trim()},strip_html:function(e){return o(e).replace(/<\/?\s*\w+\s*\/?>/g,"")},strip_newlines:function(e){return o(e).replace(/\n/g,"")},times:function(e,r){return e*r},truncate:function(e,r,t){return e=o(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)?!1:(r[e]=!0,!0)})},upcase:function(e){return o(e).toUpperCase()},url_encode:encodeURIComponent};a.filters=g,r.exports=a},{"./src/syntax.js":13,"./src/util/strftime.js":20,"./src/util/underscore.js":21}],2:[function(e,r){"use strict";function t(e){e=i.assign({root:["."],cache:!1,extname:".liquid",trim_right:!1,trim_left:!1,strict_filters:!1,strict_variables:!1},e),e.root=n(e.root);var r=Object.create(b);return r.init(h(),g(e),e),r}function n(e){return i.isArray(e)?e:i.isString(e)?[e]:[]}var s=e("./src/scope"),i=e("./src/util/underscore.js"),o=e("./src/util/assert.js"),u=e("./src/tokenizer.js"),a=e("./src/util/fs.js").statFileAsync,c=e("./src/util/fs.js").readFileAsync,l=e("path"),f=e("./src/render.js"),p=e("./src/lexical.js"),h=e("./src/tag.js"),g=e("./src/filter.js"),d=e("./src/parser"),v=e("./src/syntax.js"),m=e("./tags"),y=e("./filters"),j=e("any-promise"),w=e("./src/util/promise.js").anySeries,x=e("./src/util/error.js"),b={init:function(e,r,t){return t.cache&&(this.cache={}),this.options=t,this.tag=e,this.filter=r,this.parser=d(e,r),this.renderer=f(),m(this),y(this),this},parse:function(e,r){var t=u.parse(e,r,this.options);return this.parser.parse(t)},render:function(e,r,t){t=i.assign({},this.options,t);var n=s.factory(r,t);return this.renderer.renderTemplates(e,n)},parseAndRender:function(e,r,t){var n=this;return j.resolve().then(function(){return n.parse(e)}).then(function(e){return n.render(e,r,t)})["catch"](function(e){if(e instanceof x.RenderBreakError)return e.html;throw e})},renderFile:function(e,r,t){var n=this;return t=i.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||[]),r=i.uniq(r);var t=r.map(function(r){return l.resolve(r,e)});return w(t,function(e){return a(e).then(function(){return e})})["catch"](function(t){throw"ENOENT"===t.code&&(t.message="Failed to lookup "+e+" in: "+r),t})},getTemplate:function(e,r){var t=this;return l.extname(e)||(e+=this.options.extname),this.lookup(e,r).then(function(e){if(t.options.cache){var r=t.cache[e];return r?j.resolve(r):c(e).then(function(e){return t.parse(e)}).then(function(r){return t.cache[e]=r})}return c(e).then(function(r){return t.parse(r,e)})})},express:function(e){e=e||{};var r=this;return function(t,n,s){o(i.isArray(this.root)||i.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)})}}};t.lexical=p,t.isTruthy=v.isTruthy,t.isFalsy=v.isFalsy,t.evalExp=v.evalExp,t.evalValue=v.evalValue,t.Types={ParseError:x.ParseError,TokenizationEroor:x.TokenizationError,RenderBreakError:x.RenderBreakError,AssertionError:x.AssertionError},r.exports=t},{"./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){"use strict";r.exports=e("./register")().Promise},{"./register":5}],4:[function(e,r){"use strict";var t="@@any-promise/REGISTRATION",n=null;r.exports=function(e,r){return function(s,i){s=s||null,i=i||{};var o=i.global!==!1;if(null===n&&o&&(n=e[t]||null),null!==n&&null!==s&&n.implementation!==s)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!==s&&"undefined"!=typeof i.Promise?{Promise:i.Promise,implementation:s}:r(s),o&&(e[t]=n)),n}}},{}],5:[function(e,r){"use strict";function t(){if("undefined"==typeof 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"}}r.exports=e("./loader")(window,t)},{"./loader":4}],6:[function(){"use strict"},{}],7:[function(e,r){"use strict";var t=e("./lexical.js"),n=e("./syntax.js"),s=e("./util/assert.js"),i=e("./util/underscore.js"),o=new RegExp(""+t.value.source,"g");r.exports=function(e){function r(e){var r=Object.create(l);return r.parse(e)}function u(e,r){c[e]=r}function a(){c={}}e=i.assign({},e);var c={},l={render:function(e,r){var t=this.args.map(function(e){return n.evalValue(e,r)});return t.unshift(e),this.filter.apply(null,t)},parse:function(r){var n=t.filterLine.exec(r);s(n,"illegal filter: "+r);var i=n[1],u=n[2]||"",a=c[i];if("function"!=typeof a){if(e.strict_filters)throw new TypeError("undefined filter: "+i);return this.name=i,this.filter=function(e){return e},this.args=[],this}for(var l=[];n=o.exec(u.trim());){var f=n[0],p=new RegExp(f+"\\s*:","g");l.push(p.test(n.input)?"'"+f+"'":f)}return this.name=i,this.filter=a,this.args=l,this}};return{construct:r,register:u,clear:a}}},{"./lexical.js":8,"./syntax.js":13,"./util/assert.js":16,"./util/underscore.js":21}],8:[function(e,r){"use strict";function t(e){return q.test(e)}function n(e){return S.test(e)}function s(e){return P.test(e)}function i(e){return R.test(e)}function o(e){return b.exec(e)}function u(e){var r=e.match(O);return r?Number(e):(r=e.match(M))?"true"===e.toLowerCase():(r=e.match(A),r?e.slice(1,-1):void 0)}var a=/'[^']*'/,c=/"[^"]*"/,l=new RegExp(a.source+"|"+c.source),f=new RegExp("(?:"+l.source+"|[^'\"])*"),p=/-?\d+/,h=/-?\d+\.?\d*|\.?\d+/,g=/true|false/,d=/[\w-]+/,v=new RegExp("\\[(?:"+l.source+"|[\\w-\\.]+)\\]"),m=new RegExp("(?:"+l.source+"|"+g.source+"|"+h.source+")"),y=new RegExp(d.source+"(?:\\."+d.source+"|"+v.source+")*"),j=new RegExp("(?:"+y.source+"|"+h.source+")"),w=new RegExp("\\("+j.source+"\\.\\."+j.source+"\\)"),x=new RegExp("\\(("+j.source+")\\.\\.("+j.source+")\\)"),b=new RegExp("(?:"+y.source+"|"+m.source+"|"+w.source+")"),E=new RegExp("(?:"+d.source+")\\s*:\\s*(?:"+b.source+")"),T=new RegExp("("+d.source+")\\s*:\\s*("+b.source+")","g"),k=new RegExp("^\\s*("+d.source+")\\s*([\\s\\S]*)\\s*$"),S=new RegExp("^"+m.source+"$","i"),R=new RegExp("^"+y.source+"$"),O=new RegExp("^"+h.source+"$"),M=new RegExp("^"+g.source+"$","i"),A=new RegExp("^"+l.source+"$"),P=new RegExp("^"+x.source+"$"),q=new RegExp("^"+p.source+"$"),L=new RegExp("(?:"+d.source+"\\s*:\\s*)?"+b.source),F=new RegExp(L.source+"(\\s*,\\s*"+L.source+")*"),_=new RegExp(d.source+"(?:\\s*:\\s*"+F.source+")?","g"),D=new RegExp("("+d.source+")(?:\\s*:\\s*("+F.source+"))?"),I=new RegExp("^"+D.source+"$"),$=[/\s+or\s+/,/\s+and\s+/,/==|!=|<=|>=|<|>|\s+contains\s+/];r.exports={quoted:l,number:h,bool:g,literal:m,filter:_,integer:p,hash:E,hashCapture:T,range:w,rangeCapture:x,identifier:d,value:b,quoteBalanced:f,operators:$,quotedLine:A,numberLine:O,boolLine:M,rangeLine:P,literalLine:S,filterLine:I,tagLine:k,isLiteral:n,isVariable:i,parseLiteral:u,isRange:s,matchValue:o,isInteger:t}},{}],9:[function(e,r){"use strict";var t={"==":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&&r>e},">=":function(e,r){return null!==e&&null!==r&&e>=r},"<=":function(e,r){return null!==e&&null!==r&&r>=e},contains:function(e,r){return e?"function"!=typeof e.indexOf?!1:e.indexOf(r)>-1:!1},and:function(e,r){return e&&r},or:function(e,r){return e||r}};r.exports=t},{}],10:[function(e,r){"use strict";var t=e("./lexical.js"),n=e("./util/error.js").ParseError,s=e("./util/assert.js");r.exports=function(e,r){function i(e){for(var r,t=[];r=e.shift();)t.push(o(r,e));return t}function o(e,r){try{var t=null;return t="tag"===e.type?u(e,r):"output"===e.type?a(e.value):e,t.token=e,t}catch(s){throw new n(s,e)}}function u(r,t){return"continue"===r.name||"break"===r.name?r:e.construct(r,t)}function a(e){var n=t.matchValue(e);s(n,"illegal output string: "+e);var i=n[0];e=e.substr(n.index+n[0].length);for(var o=[];n=t.filter.exec(e);)o.push([n[0].trim()]);return{type:"output",initial:i,filters:o.map(function(e){return r.construct(e)})}}function c(e){var r=Object.create(l);return r.init(e)}var l={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];return"function"==typeof t?(t(r),!0):void 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=o(e,this.tokens);this.trigger("template",r)}return this.stopRequested||this.trigger("end"),this},stop:function(){return this.stopRequested=!0,this}};return{parse:i,parseTag:u,parseStream:c,parseOutput:a}}},{"./lexical.js":8,"./util/assert.js":16,"./util/error.js":17}],11:[function(e,r){"use strict";function t(){var e=Object.create(l);return e}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=t},{"./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){for(var t=1,n=r;n=0;r--)s.assign(e,this.scopes[r]);return e},get:function(e){for(var r=this.scopes.length-1;r>=0;r--)try{return this.getPropertyByPath(this.scopes[r],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,r){return this.setPropertyByPath(this.scopes[this.scopes.length-1],e,r),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,r,t){if(s.isString(r))for(var n=r.replace(/\[/g,".").replace(/\]/g,"").split("."),i=0;i=y;y++)m.push(y);return m}return n(e,r)}function n(e,r){return e=e&&e.trim(),e?u.isLiteral(e)?u.parseLiteral(e):u.isVariable(e)?r.get(e):void 0:void 0}function s(e){return!i(e)}function i(e){return e===!1||void 0===e||null===e}var o=e("./operators.js"),u=e("./lexical.js"),a=e("../src/util/assert.js");r.exports={evalExp:t,evalValue:n,isTruthy:s,isFalsy:i}},{"../src/util/assert.js":16,"./lexical.js":8,"./operators.js":9}],14:[function(e,r){"use strict";function t(e,r){var t,s={};for(n.hashCapture.lastIndex=0;t=n.hashCapture.exec(e);){var i=t[1],u=t[2];s[i]=o.evalValue(u,r)}return s}var n=e("./lexical.js"),s=e("./util/underscore.js"),i=e("any-promise"),o=e("./syntax.js"),u=e("./util/assert.js");r.exports=function(){function e(e,r){o[e]=r}function r(e,r){var t=Object.create(a);return t.parse(e,r),t}function n(){o={}}var o={},a={render:function(e){var r=t(this.token.args,e),n=this.tagImpl;return"function"!=typeof n.render?i.resolve(""):i.resolve().then(function(){return"function"==typeof n.render?n.render(e,r):""})["catch"](function(e){if(s.isError(e))throw e;var r="Please reject with an Error in "+n.render+", got "+e;throw new Error(r)})},parse:function(e,r){this.type="tag",this.token=e,this.name=e.name;var t=o[this.name];u(t,"tag "+this.name+" not found"),this.tagImpl=Object.create(t),this.tagImpl.parse&&this.tagImpl.parse(e,r)}};return{construct:r,register:e,clear:n}}},{"./lexical.js":8,"./syntax.js":13,"./util/assert.js":16,"./util/underscore.js":21,"any-promise":3}],15:[function(e,r,t){"use strict";function n(e,r,t){function n(t,n,s){return{type:t,raw:s[n],value:s[n+1].trim(),line:c(s),input:e,file:r}}function c(e){var r=e.input.slice(v+1,e.index).split("\n");return m+=r.length-1,v=e.index,m+1}a(u.isString(e),"illegal input type"),e=s(e,t);for(var l,f,p,h=[],g=/({%-?([\s\S]*?)-?%})|({{([\s\S]*?)}})/g,d=0,v=-1,m=0;null!==(l=g.exec(e));){if(l.index>d&&(f=e.slice(d,l.index),h.push({type:"html",raw:f,value:f})),l[1]){p=n("tag",1,l);var y=p.value.match(i.tagLine);if(!y)throw new o("illegal tag syntax",p);p.name=y[1],p.args=y[2],h.push(p)}else p=n("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}function s(e,r){r=r||{},r.trim_left&&(e=e.replace(/{%-?/g,"{%-")),r.trim_right&&(e=e.replace(/-?%}/g,"-%}"));var t=r.greedy?/\s+({%-)/g:/[\t\r ]*({%-)/g,n=r.greedy?/(-%})\s+/g:/(-%})[\t\r ]*\n?/g;return e.replace(t,"$1").replace(n,"$1")}var i=e("./lexical.js"),o=e("./util/error.js").TokenizationError,u=e("./util/underscore.js"),a=e("../src/util/assert.js");t.parse=n,t.whiteSpaceCtrl=s},{"../src/util/assert.js":16,"./lexical.js":8,"./util/error.js":17,"./util/underscore.js":21}],16:[function(e,r){"use strict";function t(e,r){if(!e){if(r instanceof Error)throw r;throw r=r||"expect "+e+" to be true",new n(r)}}var n=e("./error.js").AssertionError;r.exports=t},{"./error.js":17}],17:[function(e,r){"use strict";function t(e,r){Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.input=r.input,this.line=r.line,this.file=r.file;var t=u(r.input,r.line);this.message=c(e,r),this.stack=t+"\n"+(this.stack||"")}function n(e,r){l.assign(this,e),this.originalError=e,this.name=this.constructor.name,this.input=r.input,this.line=r.line,this.file=r.file;var t=u(r.input,r.line);this.message=c(e.message||"Unkown Error",r),this.stack=t+"\n"+(e.stack||"")}function s(e,r){if(e instanceof s)return e;l.assign(this,e),this.originalError=e,this.name=this.constructor.name,this.input=r.token.input,this.line=r.token.line,this.file=r.token.file;var t=u(r.token.input,r.token.line);this.message=c(e.message||"Unkown Error",r.token),this.stack=t+"\n"+(e.stack||"")}function i(e){Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e||""}function o(e){Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.message=e}function u(e,r){var t=e.split("\n"),n=Math.max(r-2,1),s=Math.min(r+3,t.length),i=l.range(n,s+1).map(function(e){return[e===r?">> ":" ",a(e,s),"| ",t[e-1]].join("")}).join("\n");return i}function a(e,r){var t=(r+"").length,n=e+"",s=Array(t-n.length).join(" ");return s+n}function c(e,r){return e=e||"",r.file&&(e+=", file:"+r.file),r.line&&(e+=", line:"+r.line),e}var l=e("./underscore.js");t.prototype=Object.create(Error.prototype),t.prototype.constructor=t,n.prototype=Object.create(Error.prototype),n.prototype.constructor=n,s.prototype=Object.create(Error.prototype),s.prototype.constructor=s,i.prototype=Object.create(Error.prototype),i.prototype.constructor=i,o.prototype=Object.create(Error.prototype),o.prototype.constructor=o,r.exports={TokenizationError:t,ParseError:n,RenderBreakError:i,AssertionError:o,RenderError:s}},{"./underscore.js":21}],18:[function(e,r){"use strict";function t(e){return new Promise(function(r,t){s.readFile(e,"utf8",function(e,n){e?t(e):r(n)})})}function n(e){return new Promise(function(r,t){s.stat(e,function(e,n){return e?t(e):r(n)})})}var s=e("fs");r.exports={readFileAsync:t,statFileAsync:n}},{fs:6}],19:[function(e,r,t){"use strict";function n(e,r){var t=i.reject(new Error("init"));return e.forEach(function(n,s){t=t["catch"](function(){return r(n,s,e)})}),t}function s(e,r){var t=i.resolve("init"),n=[];return e.forEach(function(s,i){t=t.then(function(){return r(s,i,e)}).then(function(e){return n.push(e)})}),t.then(function(){return n})}var i=e("any-promise");t.anySeries=n,t.mapSeries=s},{"any-promise":3}],20:[function(e,r){"use strict";var t=["January","February","March","April","May","June","July","August","September","October","November","December"],n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],s=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],i=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],o={1:"st",2:"nd",3:"rd","default":"th"},u={daysInMonth:function(e){var r=u.isLeapYear(e)?29:28;return[31,r,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}},c={a:function(e){return i[e.getDay()]},A:function(e){return s[e.getDay()]},b:function(e){return n[e.getMonth()]},B:function(e){return t[e.getMonth()]},c:function(e){return e.toLocaleString()},C:function(e){return u.century(e)},d:function(e){return a.pad(e.getDate(),2)},e:function(e){return a.pad(e.getDate(),2," ")},H:function(e){return a.pad(e.getHours(),2)},I:function(e){return a.pad(e.getHours()%12||12,2)},j:function(e){return a.pad(u.getDayOfYear(e),3)},k:function(e){return a.pad(e.getHours(),2," ")},l:function(e){return a.pad(e.getHours()%12||12,2," ")},L:function(e){return a.pad(e.getMilliseconds(),3)},m:function(e){return a.pad(e.getMonth()+1,2)},M:function(e){return a.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 u.getSuffix(e)},s:function(e){return Math.round(e.valueOf()/1e3)},S:function(e){return a.pad(e.getSeconds(),2)},u:function(e){return e.getDay()||7},U:function(e){return u.getWeekOfYear(e,0)},w:function(e){return e.getDay()},W:function(e){return u.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(r>0?"-":"+")+a.pad(Math.abs(r),4)},"%":function(){return"%"}};c.h=c.b,c.N=c.L;var l=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=c[o];t+=u?u.call(this,e):"%"+o}};r.exports=l},{}],21:[function(e,r,t){"use strict";function n(e){return e instanceof String||"string"==typeof e}function s(e){var r=Object.prototype.toString.call(e);return"Error"===r.substr(-6,5)||"string"==typeof e.message&&"string"==typeof e.name}function i(e,r){e=e||{};for(var t in e)if(e.hasOwnProperty(t)&&r(e[t],t,e)===!1)break;return e}function o(e){e=f(e)?e:{};var r=Array.prototype.slice.call(arguments,1);return r.forEach(function(r){u(e,r)}),e}function u(e,r){return e?(i(r,function(r,t){e[t]=r}),e):e}function a(e){return e instanceof Array}function c(e){return function(r){return console.log("["+e+"]",r),r}}function l(e){for(var r={},t=[],n=0,s=e.length;s>n;++n)r.hasOwnProperty(e[n])||(t.push(e[n]),r[e[n]]=1);return t}function f(e){return null!==e&&"object"===("undefined"==typeof e?"undefined":h(e))}function p(e,r,t){1===arguments.length&&(r=e,e=0),t=t||1;for(var n=[],s=e;r>s;s+=t)n.push(s);return n}var h="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};t.isString=n,t.isArray=a,t.isObject=f,t.isError=s,t.range=p,t.forOwn=i,t.assign=o,t.uniq=l,t.echo=c},{}],22:[function(e,r){"use strict";var t=e(".."),n=t.lexical,s=e("any-promise"),i=new RegExp("("+n.identifier.source+")\\s*=(.*)"),o=e("../src/util/assert.js");r.exports=function(e){e.registerTag("assign",{parse:function(e){var r=e.args.match(i);o(r,"illegal token "+e.raw),this.key=r[1],this.value=r[2]},render:function(r){return r.set(this.key,e.evalOutput(this.value,r)),s.resolve("")}})}},{"..":2,"../src/util/assert.js":16,"any-promise":3}],23:[function(e,r){"use strict";var t=e(".."),n=t.lexical,s=new RegExp("("+n.identifier.source+")"),i=e("../src/util/assert.js");r.exports=function(e){e.registerTag("capture",{parse:function(r,t){var n=this,o=r.args.match(s);i(o,r.args+" not valid identifier"),this.variable=o[1],this.templates=[];var u=e.parser.parseStream(t);u.on("tag:endcapture",function(){return u.stop()}).on("template",function(e){return n.templates.push(e)}).on("end",function(){throw new Error("tag "+r.raw+" not closed")}),u.start()},render:function(r){var t=this;return e.renderer.renderTemplates(this.templates,r).then(function(e){r.set(t.variable,e)})}})}},{"..":2,"../src/util/assert.js":16}],24:[function(e,r){"use strict";{var t=e("..");e("../src/util/assert.js")}r.exports=function(e){e.registerTag("case",{parse:function(r,t){var n=this;this.cond=r.args,this.cases=[],this.elseTemplates=[];var s=[],i=e.parser.parseStream(t).on("tag:when",function(e){n.cases[e.args]||n.cases.push({val:e.args,templates:s=[]})}).on("tag:else",function(){return s=n.elseTemplates}).on("tag:endcase",function(){return i.stop()}).on("template",function(e){return s.push(e)}).on("end",function(){throw new Error("tag "+r.raw+" not closed")});i.start()},render:function(r){for(var n=0;n",l=s.offset||0,f=void 0===s.limit?a.length:s.limit,p=s.cols;if(!p)throw new Error("illegal cols: "+p);a=a.slice(l,l+f);var h=[];a.some(function(e){var r={};r[u.variable]=e,h.push(r)});var g=h.reduce(function(t,n,s){return t.then(function(){return i=Math.floor(s/p)+1,o=s%p+1,1===o&&(1!==i&&(c+=""),c+=''),c+=''}).then(function(){return r.push(n),e.renderer.renderTemplates(u.templates,r)}).then(function(e){return r.pop(n),c+=e,c+=""})},n.resolve(""));return g.then(function(){return i>0&&(c+=""),c+=""})["catch"](function(e){throw e})}})}},{"..":2,"../src/util/assert.js":16,"any-promise":3}],36:[function(e,r){"use strict";var t=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(){s=n.templates,n.cond=r.args}).on("tag:else",function(){return s=n.elseTemplates}).on("tag:endunless",function(){return i.stop()}).on("template",function(e){return s.push(e)}).on("end",function(){throw new Error("tag "+r.raw+" not closed")});i.start()},render:function(r){var n=t.evalExp(this.cond,r);return t.isFalsy(n)?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 b926907fb..50a39aad0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "shopify-liquid", - "version": "1.7.9", + "version": "1.8.0", "description": "A feature-rich Liquid template engine for Node.js and browsers, with compliance with the Ruby version.", "main": "index.js", "scripts": {