From bc9d8f92afe859fd2e7ecd2f65be483de47a121b Mon Sep 17 00:00:00 2001 From: harttle Date: Mon, 20 Aug 2018 23:58:41 +0800 Subject: [PATCH] refactor: import rollup --- .babelrc | 10 +- .eslintrc.json | 3 +- .npmignore | 1 - demo/browser/index.html | 5 +- demo/nodejs/index.js | 7 +- dist/liquid.common.js | 3738 ++++++++++++++++++++++ dist/liquid.common.js.map | 1 + dist/liquid.js | 6130 +++++++++++++++++++++---------------- dist/liquid.js.map | 1 + dist/liquid.min.js | 3 +- dist/liquid.min.js.map | 1 + package.json | 32 +- rollup.config.js | 71 + src/filter.js | 36 +- src/filters.js | 32 +- src/index.js | 163 +- src/lexical.js | 104 +- src/operators.js | 2 +- src/parser.js | 22 +- src/render.js | 77 +- src/scope.js | 36 +- src/syntax.js | 38 +- src/tag.js | 37 +- src/tags/assign.js | 12 +- src/tags/capture.js | 29 +- src/tags/case.js | 12 +- src/tags/comment.js | 4 +- src/tags/cycle.js | 24 +- src/tags/decrement.js | 19 +- src/tags/for.js | 167 +- src/tags/if.js | 11 +- src/tags/include.js | 63 +- src/tags/increment.js | 20 +- src/tags/index.js | 45 +- src/tags/layout.js | 73 +- src/tags/raw.js | 4 +- src/tags/tablerow.js | 81 +- src/tags/unless.js | 8 +- src/tokenizer.js | 31 +- src/util/assert.js | 6 +- src/util/error.js | 18 +- src/util/fs.js | 11 +- src/util/http.js | 17 + src/util/promise.js | 9 +- src/util/strftime.js | 44 +- src/util/underscore.js | 55 +- src/util/url.js | 24 +- src/whitespace-ctrl.js | 12 +- test/express.js | 21 +- test/filter.js | 32 +- test/filters.js | 16 +- test/index.js | 22 +- test/lexical.js | 12 +- test/options/cache.js | 10 +- test/options/strict.js | 10 +- test/options/trimming.js | 40 +- test/parser.js | 24 +- test/render.js | 64 +- test/scope.js | 16 +- test/syntax.js | 12 +- test/tag.js | 81 +- test/tags/assign.js | 39 +- test/tags/capture.js | 12 +- test/tags/case.js | 16 +- test/tags/comment.js | 12 +- test/tags/cycle.js | 12 +- test/tags/decrement.js | 22 +- test/tags/for.js | 56 +- test/tags/if.js | 40 +- test/tags/include.js | 10 +- test/tags/increment.js | 16 +- test/tags/layout.js | 16 +- test/tags/raw.js | 24 +- test/tags/tablerow.js | 38 +- test/tags/unless.js | 12 +- test/tokenizer.js | 28 +- test/util/assert.js | 11 +- test/util/error.js | 386 +-- test/util/promise.js | 22 +- test/util/strftime.js | 26 +- test/util/underscore.js | 23 +- test/util/url.js | 22 +- 82 files changed, 8589 insertions(+), 3963 deletions(-) create mode 100644 dist/liquid.common.js create mode 100644 dist/liquid.common.js.map create mode 100644 dist/liquid.js.map create mode 100644 dist/liquid.min.js.map create mode 100644 rollup.config.js create mode 100644 src/util/http.js diff --git a/.babelrc b/.babelrc index c13c5f627..90a03a341 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,11 @@ { - "presets": ["es2015"] + "presets": ["es2015"], + "plugins": [ + ["transform-runtime", { + "helpers": false, + "polyfill": false, + "regenerator": true, + "moduleName": "babel-runtime" + }] + ] } diff --git a/.eslintrc.json b/.eslintrc.json index 07c1083b6..4815abce6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -10,6 +10,7 @@ "promise" ], "rules": { - "no-var": 2 + "no-var": 2, + "prefer-const": 2 } } diff --git a/.npmignore b/.npmignore index 9f46a954f..a91116abd 100644 --- a/.npmignore +++ b/.npmignore @@ -1,4 +1,3 @@ /coverage -/src /test .* diff --git a/demo/browser/index.html b/demo/browser/index.html index d13b55f8b..d0976a1c2 100644 --- a/demo/browser/index.html +++ b/demo/browser/index.html @@ -1,9 +1,8 @@ - + - - + liquidjs for the browser diff --git a/demo/nodejs/index.js b/demo/nodejs/index.js index 602db7323..13e1acfcc 100644 --- a/demo/nodejs/index.js +++ b/demo/nodejs/index.js @@ -1,10 +1,11 @@ -const Liquid = require('../..') +// const Liquid = require('../..') +const Liquid = require('../../dist/liquid.common.js') -let engine = new Liquid({ +const engine = new Liquid({ root: __dirname, extname: '.liquid' }) -let ctx = { +const ctx = { todos: ['fork and clone', 'make it better', 'make a pull request'], title: 'Welcome to liquidjs!' } diff --git a/dist/liquid.common.js b/dist/liquid.common.js new file mode 100644 index 000000000..ef12b21c5 --- /dev/null +++ b/dist/liquid.common.js @@ -0,0 +1,3738 @@ +/* + * liquidjs@5.3.0-0, https://github.com/liquidjs + * (c) 2016-2018 harttle + * Released under the MIT License. + */ +'use strict'; + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var fs = _interopDefault(require('fs')); +var path = _interopDefault(require('path')); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + +var asyncToGenerator = function (fn) { + return function () { + var gen = fn.apply(this, arguments); + return new Promise(function (resolve, reject) { + function step(key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + + if (info.done) { + resolve(value); + } else { + return Promise.resolve(value).then(function (value) { + step("next", value); + }, function (err) { + step("throw", err); + }); + } + } + + return step("next"); + }); + }; +}; + +/** + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +!function (global) { + + var Op = Object.prototype; + var hasOwn = Op.hasOwnProperty; + var undefined; // More compressible than void 0. + var $Symbol = typeof Symbol === "function" ? Symbol : {}; + var iteratorSymbol = $Symbol.iterator || "@@iterator"; + var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; + var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; + + var inModule = (typeof module === "undefined" ? "undefined" : _typeof(module)) === "object"; + var runtime = global.regeneratorRuntime; + if (runtime) { + if (inModule) { + // If regeneratorRuntime is defined globally and we're in a module, + // make the exports object identical to regeneratorRuntime. + module.exports = runtime; + } + // Don't bother evaluating the rest of this file if the runtime was + // already defined globally. + return; + } + + // Define the runtime globally (as expected by generated code) as either + // module.exports (if we're in a module) or a new, empty object. + runtime = global.regeneratorRuntime = inModule ? module.exports : {}; + + function wrap(innerFn, outerFn, self, tryLocsList) { + // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. + var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; + var generator = Object.create(protoGenerator.prototype); + var context = new Context(tryLocsList || []); + + // The ._invoke method unifies the implementations of the .next, + // .throw, and .return methods. + generator._invoke = makeInvokeMethod(innerFn, self, context); + + return generator; + } + runtime.wrap = wrap; + + // Try/catch helper to minimize deoptimizations. Returns a completion + // record like context.tryEntries[i].completion. This interface could + // have been (and was previously) designed to take a closure to be + // invoked without arguments, but in all the cases we care about we + // already have an existing method we want to call, so there's no need + // to create a new function object. We can even get away with assuming + // the method takes exactly one argument, since that happens to be true + // in every case, so we don't have to touch the arguments object. The + // only additional allocation required is the completion record, which + // has a stable shape and so hopefully should be cheap to allocate. + function tryCatch(fn, obj, arg) { + try { + return { type: "normal", arg: fn.call(obj, arg) }; + } catch (err) { + return { type: "throw", arg: err }; + } + } + + var GenStateSuspendedStart = "suspendedStart"; + var GenStateSuspendedYield = "suspendedYield"; + var GenStateExecuting = "executing"; + var GenStateCompleted = "completed"; + + // Returning this object from the innerFn has the same effect as + // breaking out of the dispatch switch statement. + var ContinueSentinel = {}; + + // Dummy constructor functions that we use as the .constructor and + // .constructor.prototype properties for functions that return Generator + // objects. For full spec compliance, you may wish to configure your + // minifier not to mangle the names of these two functions. + function Generator() {} + function GeneratorFunction() {} + function GeneratorFunctionPrototype() {} + + // This is a polyfill for %IteratorPrototype% for environments that + // don't natively support it. + var IteratorPrototype = {}; + IteratorPrototype[iteratorSymbol] = function () { + return this; + }; + + var getProto = Object.getPrototypeOf; + var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); + if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { + // This environment has a native %IteratorPrototype%; use it instead + // of the polyfill. + IteratorPrototype = NativeIteratorPrototype; + } + + var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); + GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; + GeneratorFunctionPrototype.constructor = GeneratorFunction; + GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; + + // Helper for defining the .next, .throw, and .return methods of the + // Iterator interface in terms of a single ._invoke method. + function defineIteratorMethods(prototype) { + ["next", "throw", "return"].forEach(function (method) { + prototype[method] = function (arg) { + return this._invoke(method, arg); + }; + }); + } + + runtime.isGeneratorFunction = function (genFun) { + var ctor = typeof genFun === "function" && genFun.constructor; + return ctor ? ctor === GeneratorFunction || + // For the native GeneratorFunction constructor, the best we can + // do is to check its .name property. + (ctor.displayName || ctor.name) === "GeneratorFunction" : false; + }; + + runtime.mark = function (genFun) { + if (Object.setPrototypeOf) { + Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); + } else { + genFun.__proto__ = GeneratorFunctionPrototype; + if (!(toStringTagSymbol in genFun)) { + genFun[toStringTagSymbol] = "GeneratorFunction"; + } + } + genFun.prototype = Object.create(Gp); + return genFun; + }; + + // Within the body of any async function, `await x` is transformed to + // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test + // `hasOwn.call(value, "__await")` to determine if the yielded value is + // meant to be awaited. + runtime.awrap = function (arg) { + return { __await: arg }; + }; + + function AsyncIterator(generator) { + function invoke(method, arg, resolve, reject) { + var record = tryCatch(generator[method], generator, arg); + if (record.type === "throw") { + reject(record.arg); + } else { + var result = record.arg; + var value = result.value; + if (value && (typeof value === "undefined" ? "undefined" : _typeof(value)) === "object" && hasOwn.call(value, "__await")) { + return Promise.resolve(value.__await).then(function (value) { + invoke("next", value, resolve, reject); + }, function (err) { + invoke("throw", err, resolve, reject); + }); + } + + return Promise.resolve(value).then(function (unwrapped) { + // When a yielded Promise is resolved, its final value becomes + // the .value of the Promise<{value,done}> result for the + // current iteration. + result.value = unwrapped; + resolve(result); + }, function (error) { + // If a rejected Promise was yielded, throw the rejection back + // into the async generator function so it can be handled there. + return invoke("throw", error, resolve, reject); + }); + } + } + + var previousPromise; + + function enqueue(method, arg) { + function callInvokeWithMethodAndArg() { + return new Promise(function (resolve, reject) { + invoke(method, arg, resolve, reject); + }); + } + + return previousPromise = + // If enqueue has been called before, then we want to wait until + // all previous Promises have been resolved before calling invoke, + // so that results are always delivered in the correct order. If + // enqueue has not been called before, then it is important to + // call invoke immediately, without waiting on a callback to fire, + // so that the async generator function has the opportunity to do + // any necessary setup in a predictable way. This predictability + // is why the Promise constructor synchronously invokes its + // executor callback, and why async functions synchronously + // execute code before the first await. Since we implement simple + // async functions in terms of async generators, it is especially + // important to get this right, even though it requires care. + previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, + // Avoid propagating failures to Promises returned by later + // invocations of the iterator. + callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); + } + + // Define the unified helper method that is used to implement .next, + // .throw, and .return (see defineIteratorMethods). + this._invoke = enqueue; + } + + defineIteratorMethods(AsyncIterator.prototype); + AsyncIterator.prototype[asyncIteratorSymbol] = function () { + return this; + }; + runtime.AsyncIterator = AsyncIterator; + + // Note that simple async functions are implemented on top of + // AsyncIterator objects; they just return a Promise for the value of + // the final result produced by the iterator. + runtime.async = function (innerFn, outerFn, self, tryLocsList) { + var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList)); + + return runtime.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator. + : iter.next().then(function (result) { + return result.done ? result.value : iter.next(); + }); + }; + + function makeInvokeMethod(innerFn, self, context) { + var state = GenStateSuspendedStart; + + return function invoke(method, arg) { + if (state === GenStateExecuting) { + throw new Error("Generator is already running"); + } + + if (state === GenStateCompleted) { + if (method === "throw") { + throw arg; + } + + // Be forgiving, per 25.3.3.3.3 of the spec: + // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume + return doneResult(); + } + + context.method = method; + context.arg = arg; + + while (true) { + var delegate = context.delegate; + if (delegate) { + var delegateResult = maybeInvokeDelegate(delegate, context); + if (delegateResult) { + if (delegateResult === ContinueSentinel) continue; + return delegateResult; + } + } + + if (context.method === "next") { + // Setting context._sent for legacy support of Babel's + // function.sent implementation. + context.sent = context._sent = context.arg; + } else if (context.method === "throw") { + if (state === GenStateSuspendedStart) { + state = GenStateCompleted; + throw context.arg; + } + + context.dispatchException(context.arg); + } else if (context.method === "return") { + context.abrupt("return", context.arg); + } + + state = GenStateExecuting; + + var record = tryCatch(innerFn, self, context); + if (record.type === "normal") { + // If an exception is thrown from innerFn, we leave state === + // GenStateExecuting and loop back for another invocation. + state = context.done ? GenStateCompleted : GenStateSuspendedYield; + + if (record.arg === ContinueSentinel) { + continue; + } + + return { + value: record.arg, + done: context.done + }; + } else if (record.type === "throw") { + state = GenStateCompleted; + // Dispatch the exception by looping back around to the + // context.dispatchException(context.arg) call above. + context.method = "throw"; + context.arg = record.arg; + } + } + }; + } + + // Call delegate.iterator[context.method](context.arg) and handle the + // result, either by returning a { value, done } result from the + // delegate iterator, or by modifying context.method and context.arg, + // setting context.delegate to null, and returning the ContinueSentinel. + function maybeInvokeDelegate(delegate, context) { + var method = delegate.iterator[context.method]; + if (method === undefined) { + // A .throw or .return when the delegate iterator has no .throw + // method always terminates the yield* loop. + context.delegate = null; + + if (context.method === "throw") { + if (delegate.iterator.return) { + // If the delegate iterator has a return method, give it a + // chance to clean up. + context.method = "return"; + context.arg = undefined; + maybeInvokeDelegate(delegate, context); + + if (context.method === "throw") { + // If maybeInvokeDelegate(context) changed context.method from + // "return" to "throw", let that override the TypeError below. + return ContinueSentinel; + } + } + + context.method = "throw"; + context.arg = new TypeError("The iterator does not provide a 'throw' method"); + } + + return ContinueSentinel; + } + + var record = tryCatch(method, delegate.iterator, context.arg); + + if (record.type === "throw") { + context.method = "throw"; + context.arg = record.arg; + context.delegate = null; + return ContinueSentinel; + } + + var info = record.arg; + + if (!info) { + context.method = "throw"; + context.arg = new TypeError("iterator result is not an object"); + context.delegate = null; + return ContinueSentinel; + } + + if (info.done) { + // Assign the result of the finished delegate to the temporary + // variable specified by delegate.resultName (see delegateYield). + context[delegate.resultName] = info.value; + + // Resume execution at the desired location (see delegateYield). + context.next = delegate.nextLoc; + + // If context.method was "throw" but the delegate handled the + // exception, let the outer generator proceed normally. If + // context.method was "next", forget context.arg since it has been + // "consumed" by the delegate iterator. If context.method was + // "return", allow the original .return call to continue in the + // outer generator. + if (context.method !== "return") { + context.method = "next"; + context.arg = undefined; + } + } else { + // Re-yield the result returned by the delegate method. + return info; + } + + // The delegate iterator is finished, so forget it and continue with + // the outer generator. + context.delegate = null; + return ContinueSentinel; + } + + // Define Generator.prototype.{next,throw,return} in terms of the + // unified ._invoke helper method. + defineIteratorMethods(Gp); + + Gp[toStringTagSymbol] = "Generator"; + + // A Generator should always return itself as the iterator object when the + // @@iterator function is called on it. Some browsers' implementations of the + // iterator prototype chain incorrectly implement this, causing the Generator + // object to not be returned from this call. This ensures that doesn't happen. + // See https://github.com/facebook/regenerator/issues/274 for more details. + Gp[iteratorSymbol] = function () { + return this; + }; + + Gp.toString = function () { + return "[object Generator]"; + }; + + function pushTryEntry(locs) { + var entry = { tryLoc: locs[0] }; + + if (1 in locs) { + entry.catchLoc = locs[1]; + } + + if (2 in locs) { + entry.finallyLoc = locs[2]; + entry.afterLoc = locs[3]; + } + + this.tryEntries.push(entry); + } + + function resetTryEntry(entry) { + var record = entry.completion || {}; + record.type = "normal"; + delete record.arg; + entry.completion = record; + } + + function Context(tryLocsList) { + // The root entry object (effectively a try statement without a catch + // or a finally block) gives us a place to store values thrown from + // locations where there is no enclosing try statement. + this.tryEntries = [{ tryLoc: "root" }]; + tryLocsList.forEach(pushTryEntry, this); + this.reset(true); + } + + runtime.keys = function (object) { + var keys = []; + for (var key in object) { + keys.push(key); + } + keys.reverse(); + + // Rather than returning an object with a next method, we keep + // things simple and return the next function itself. + return function next() { + while (keys.length) { + var key = keys.pop(); + if (key in object) { + next.value = key; + next.done = false; + return next; + } + } + + // To avoid creating an additional object, we just hang the .value + // and .done properties off the next function object itself. This + // also ensures that the minifier will not anonymize the function. + next.done = true; + return next; + }; + }; + + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) { + return iteratorMethod.call(iterable); + } + + if (typeof iterable.next === "function") { + return iterable; + } + + if (!isNaN(iterable.length)) { + var i = -1, + next = function next() { + while (++i < iterable.length) { + if (hasOwn.call(iterable, i)) { + next.value = iterable[i]; + next.done = false; + return next; + } + } + + next.value = undefined; + next.done = true; + + return next; + }; + + return next.next = next; + } + } + + // Return an iterator with no values. + return { next: doneResult }; + } + runtime.values = values; + + function doneResult() { + return { value: undefined, done: true }; + } + + Context.prototype = { + constructor: Context, + + reset: function reset(skipTempReset) { + this.prev = 0; + this.next = 0; + // Resetting context._sent for legacy support of Babel's + // function.sent implementation. + this.sent = this._sent = undefined; + this.done = false; + this.delegate = null; + + this.method = "next"; + this.arg = undefined; + + this.tryEntries.forEach(resetTryEntry); + + if (!skipTempReset) { + for (var name in this) { + // Not sure about the optimal order of these conditions: + if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { + this[name] = undefined; + } + } + } + }, + + stop: function stop() { + this.done = true; + + var rootEntry = this.tryEntries[0]; + var rootRecord = rootEntry.completion; + if (rootRecord.type === "throw") { + throw rootRecord.arg; + } + + return this.rval; + }, + + dispatchException: function dispatchException(exception) { + if (this.done) { + throw exception; + } + + var context = this; + function handle(loc, caught) { + record.type = "throw"; + record.arg = exception; + context.next = loc; + + if (caught) { + // If the dispatched exception was caught by a catch block, + // then let that catch block handle the exception normally. + context.method = "next"; + context.arg = undefined; + } + + return !!caught; + } + + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + var record = entry.completion; + + if (entry.tryLoc === "root") { + // Exception thrown outside of any try block that could handle + // it, so set the completion value of the entire function to + // throw the exception. + return handle("end"); + } + + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"); + var hasFinally = hasOwn.call(entry, "finallyLoc"); + + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } else if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else if (hasCatch) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } + } else if (hasFinally) { + if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else { + throw new Error("try statement without catch or finally"); + } + } + } + }, + + abrupt: function abrupt(type, arg) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { + var finallyEntry = entry; + break; + } + } + + if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { + // Ignore the finally entry if control is not jumping to a + // location outside the try/catch block. + finallyEntry = null; + } + + var record = finallyEntry ? finallyEntry.completion : {}; + record.type = type; + record.arg = arg; + + if (finallyEntry) { + this.method = "next"; + this.next = finallyEntry.finallyLoc; + return ContinueSentinel; + } + + return this.complete(record); + }, + + complete: function complete(record, afterLoc) { + if (record.type === "throw") { + throw record.arg; + } + + if (record.type === "break" || record.type === "continue") { + this.next = record.arg; + } else if (record.type === "return") { + this.rval = this.arg = record.arg; + this.method = "return"; + this.next = "end"; + } else if (record.type === "normal" && afterLoc) { + this.next = afterLoc; + } + + return ContinueSentinel; + }, + + finish: function finish(finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.finallyLoc === finallyLoc) { + this.complete(entry.completion, entry.afterLoc); + resetTryEntry(entry); + return ContinueSentinel; + } + } + }, + + "catch": function _catch(tryLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc === tryLoc) { + var record = entry.completion; + if (record.type === "throw") { + var thrown = record.arg; + resetTryEntry(entry); + } + return thrown; + } + } + + // The context.catch method must only be called with a location + // argument that corresponds to a known catch block. + throw new Error("illegal catch attempt"); + }, + + delegateYield: function delegateYield(iterable, resultName, nextLoc) { + this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }; + + if (this.method === "next") { + // Deliberately forget the last sent value so that we don't + // accidentally pass it on to the delegate. + this.arg = undefined; + } + + return ContinueSentinel; + } + }; +}( +// In sloppy mode, unbound `this` refers to the global object, fallback to +// Function constructor if we're in global strict mode. That is sadly a form +// of indirect eval which violates Content Security Policy. +function () { + return this || (typeof self === "undefined" ? "undefined" : _typeof(self)) === "object" && self; +}() || Function("return this")()); + +var toStr = Object.prototype.toString; + +/* + * Checks if value is classified as a String primitive or object. + * @param {any} value The value to check. + * @return {Boolean} Returns true if value is a string, else false. + */ +function isString(value) { + return toStr.call(value) === '[object String]'; +} + +function stringify(value) { + if (isNil(value)) { + return String(value); + } + if (typeof value.to_liquid === 'function') { + return stringify(value.to_liquid()); + } + if (typeof value.toLiquid === 'function') { + return stringify(value.toLiquid()); + } + if (isString(value)) { + return value; + } + + var cache = []; + return JSON.stringify(value, function (key, value) { + if (isObject(value)) { + if (cache.indexOf(value) !== -1) { + return; + } + cache.push(value); + } + return value; + }); +} + +function isNil(value) { + return value === null || value === undefined; +} + +function isArray(value) { + // be compatible with IE 8 + return toStr.call(value) === '[object Array]'; +} + +/* + * 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; + } + } + 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. + * + * Note: This method mutates object and is loosely based on Object.assign. + * + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @return {Object} Returns object. + */ +function assign(object) { + object = isObject(object) ? object : {}; + var srcs = Array.prototype.slice.call(arguments, 1); + srcs.forEach(function (src) { + return Object.assign(object, src); + }); + return object; +} + +function last(arr) { + return arr[arr.length - 1]; +} + +function uniq(arr) { + var u = {}; + var 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; + } + return a; +} + +/* + * 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) { + var type = typeof value === 'undefined' ? 'undefined' : _typeof(value); + return value != null && (type === 'object' || type === 'function'); +} + +/* + * 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; + + var arr = []; + for (var i = start; i < stop; i += step) { + arr.push(i); + } + return arr; +} + +// quote related +var singleQuoted = /'[^']*'/; +var doubleQuoted = /"[^"]*"/; +var quoted = new RegExp(singleQuoted.source + '|' + doubleQuoted.source); +var quoteBalanced = new RegExp('(?:' + quoted.source + '|[^\'"])*'); + +// basic types +var integer = /-?\d+/; +var number = /-?\d+\.?\d*|\.?\d+/; +var bool = /true|false/; + +// peoperty access +var identifier = /[\w-]+[?]?/; +var subscript = new RegExp('\\[(?:' + quoted.source + '|[\\w-\\.]+)\\]'); +var literal = new RegExp('(?:' + quoted.source + '|' + bool.source + '|' + number.source + ')'); +var variable = new RegExp(identifier.source + '(?:\\.' + identifier.source + '|' + subscript.source + ')*'); + +// range related +var rangeLimit = new RegExp('(?:' + variable.source + '|' + number.source + ')'); +var range$1 = new RegExp('\\(' + rangeLimit.source + '\\.\\.' + rangeLimit.source + '\\)'); +var rangeCapture = new RegExp('\\((' + rangeLimit.source + ')\\.\\.(' + rangeLimit.source + ')\\)'); + +var value = new RegExp('(?:' + variable.source + '|' + literal.source + '|' + range$1.source + ')'); + +// hash related +var hash = new RegExp('(?:' + identifier.source + ')\\s*:\\s*(?:' + value.source + ')'); +var hashCapture = new RegExp('(' + identifier.source + ')\\s*:\\s*(' + value.source + ')', 'g'); + +// full match +var tagLine = new RegExp('^\\s*(' + identifier.source + ')\\s*([\\s\\S]*)\\s*$'); +var literalLine = new RegExp('^' + literal.source + '$', 'i'); +var variableLine = new RegExp('^' + variable.source + '$'); +var numberLine = new RegExp('^' + number.source + '$'); +var boolLine = new RegExp('^' + bool.source + '$', 'i'); +var quotedLine = new RegExp('^' + quoted.source + '$'); +var rangeLine = new RegExp('^' + rangeCapture.source + '$'); +var integerLine = new RegExp('^' + integer.source + '$'); + +// filter related +var valueDeclaration = new RegExp('(?:' + identifier.source + '\\s*:\\s*)?' + value.source); +var valueList = new RegExp(valueDeclaration.source + '(\\s*,\\s*' + valueDeclaration.source + ')*'); +var filter = new RegExp(identifier.source + '(?:\\s*:\\s*' + valueList.source + ')?', 'g'); +var filterCapture = new RegExp('(' + identifier.source + ')(?:\\s*:\\s*(' + valueList.source + '))?'); +var filterLine = new RegExp('^' + filterCapture.source + '$'); + +var operators = [/\s+or\s+/, /\s+and\s+/, /==|!=|<=|>=|<|>|\s+contains\s+/]; + +function isInteger(str) { + return integerLine.test(str); +} + +function isLiteral(str) { + return literalLine.test(str); +} + +function isRange(str) { + return rangeLine.test(str); +} + +function isVariable(str) { + return variableLine.test(str); +} + +function matchValue(str) { + return value.exec(str); +} + +function parseLiteral(str) { + 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); + } + throw new TypeError('cannot parse \'' + str + '\' as literal'); +} + +var lexical = /*#__PURE__*/Object.freeze({ + quoted: quoted, + quoteBalanced: quoteBalanced, + integer: integer, + number: number, + bool: bool, + identifier: identifier, + subscript: subscript, + literal: literal, + variable: variable, + rangeLimit: rangeLimit, + range: range$1, + rangeCapture: rangeCapture, + value: value, + hash: hash, + hashCapture: hashCapture, + tagLine: tagLine, + literalLine: literalLine, + variableLine: variableLine, + numberLine: numberLine, + boolLine: boolLine, + quotedLine: quotedLine, + rangeLine: rangeLine, + integerLine: integerLine, + valueDeclaration: valueDeclaration, + valueList: valueList, + filter: filter, + filterCapture: filterCapture, + filterLine: filterLine, + operators: operators, + isInteger: isInteger, + isLiteral: isLiteral, + isRange: isRange, + isVariable: isVariable, + matchValue: matchValue, + parseLiteral: parseLiteral +}); + +function initError() { + this.name = this.constructor.name; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } +} + +function initLiquidError(err, token) { + initError.call(this); + + this.input = token.input; + this.line = token.line; + this.file = token.file; + + var context = mkContext(token.input, token.line); + this.message = mkMessage(err.message, token); + this.stack = context + '\n' + (this.stack || this.message) + (err.stack ? '\nFrom ' + err.stack : ''); +} + +function TokenizationError(message, token) { + initLiquidError.call(this, { message: message }, token); +} +TokenizationError.prototype = Object.create(Error.prototype); +TokenizationError.prototype.constructor = TokenizationError; + +function ParseError(e, token) { + assign(this, e); + this.originalError = e; + + initLiquidError.call(this, e, token); +} +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; + + initLiquidError.call(this, e, tpl.token); +} +RenderError.prototype = Object.create(Error.prototype); +RenderError.prototype.constructor = RenderError; + +function RenderBreakError(message) { + initError.call(this); + this.message = message + ''; +} +RenderBreakError.prototype = Object.create(Error.prototype); +RenderBreakError.prototype.constructor = RenderBreakError; + +function AssertionError(message) { + initError.call(this); + 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 context = range(begin, end + 1).map(function (l) { + return [l === line ? '>> ' : ' ', align(l, end), '| ', lines[l - 1]].join(''); + }).join('\n'); + + return context; +} + +function align(n, max) { + 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; +} + +function assert (predicate, message) { + if (!predicate) { + message = message || 'expect ' + predicate + ' to be true'; + throw new AssertionError(message); + } +} + +var Scope = { + getAll: function getAll() { + return this.contexts.reduce(function (ctx, val) { + return Object.assign(ctx, val); + }, Object.create(null)); + }, + get: function get(path$$1) { + var _this = this; + + var paths = this.propertyAccessSeq(path$$1); + var scope = this.findContextFor(paths[0]) || last(this.contexts); + return paths.reduce(function (value$$1, key) { + return _this.readProperty(value$$1, key); + }, scope); + }, + set: function set(path$$1, v) { + var paths = this.propertyAccessSeq(path$$1); + var scope = this.findContextFor(paths[0]) || last(this.contexts); + paths.some(function (key, i) { + if (!isObject(scope)) { + return true; + } + if (i === paths.length - 1) { + scope[key] = v; + return true; + } + if (undefined === scope[key]) { + scope[key] = {}; + } + scope = scope[key]; + }); + }, + unshift: function unshift(ctx) { + return this.contexts.unshift(ctx); + }, + push: function push(ctx) { + return this.contexts.push(ctx); + }, + pop: function pop(ctx) { + if (!arguments.length) { + return this.contexts.pop(); + } + var i = this.contexts.findIndex(function (scope) { + return scope === ctx; + }); + if (i === -1) { + throw new TypeError('scope not found, cannot pop'); + } + return this.contexts.splice(i, 1)[0]; + }, + findContextFor: function findContextFor(key, filter$$1) { + filter$$1 = filter$$1 || function () { + return true; + }; + for (var i = this.contexts.length - 1; i >= 0; i--) { + var candidate = this.contexts[i]; + if (!filter$$1(candidate)) continue; + if (key in candidate) { + return candidate; + } + } + return null; + }, + readProperty: function readProperty(obj, key) { + var val = void 0; + if (isNil(obj)) { + val = undefined; + } else { + if (typeof obj.to_liquid === 'function') { + obj = obj.to_liquid(); + } else if (typeof obj.toLiquid === 'function') { + obj = obj.toLiquid(); + } + + if (key === 'size' && (isArray(obj) || isString(obj))) { + val = obj.length; + } else { + val = obj[key]; + } + } + if (isNil(val) && this.opts.strict_variables) { + throw new TypeError('undefined variable: ' + key); + } + return val; + }, + + /* + * 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) { + str = String(str); + var seq = []; + var name = ''; + var j = void 0; + var i = 0; + while (i < str.length) { + switch (str[i]) { + case '[': + push(); + + var delemiter = str[i + 1]; + if (/['"]/.test(delemiter)) { + // foo["bar"] + j = str.indexOf(delemiter, i + 2); + assert(j !== -1, 'unbalanced ' + delemiter + ': ' + str); + name = str.slice(i + 2, j); + push(); + i = j + 2; + } else { + // foo[bar.coo] + j = matchRightBracket(str, i + 1); + assert(j !== -1, 'unbalanced []: ' + str); + name = str.slice(i + 1, j); + if (!isInteger(name)) { + // foo[bar] vs. foo[1] + name = this.get(name); + } + push(); + i = j + 1; + } + break; + case '.': + // foo.bar, foo[0].bar + push(); + i++; + break; + default: + // foo.bar + name += str[i]; + i++; + } + } + push(); + + if (!seq.length) { + throw new TypeError('invalid path:"' + str + '"'); + } + return seq; + + function push() { + if (name.length) seq.push(name); + name = ''; + } + } +}; + +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; + } + } + } + return -1; +} + +function factory(ctx, opts) { + var defaultOptions = { + dynamicPartials: true, + strict_variables: false, + strict_filters: false, + blocks: {}, + root: [] + }; + var scope = Object.create(Scope); + scope.opts = assign(defaultOptions, opts); + scope.contexts = [ctx || {}]; + return scope; +} + +function get$1(url) { + return new Promise(function (resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.onload = function () { + if (xhr.status >= 200 && xhr.status < 300) { + resolve(xhr.responseText); + } else { + reject(new Error(xhr.statusText)); + } + }; + xhr.onerror = function () { + reject(new Error('An error occurred whilst sending the response.')); + }; + xhr.open('GET', url); + xhr.send(); + }); +} + +function whiteSpaceCtrl(tokens, options) { + options = assign({ greedy: true }, options); + var inRaw = false; + + tokens.forEach(function (token, i) { + if (shouldTrimLeft(token, inRaw, options)) { + trimLeft(tokens[i - 1], options.greedy); + } + + if (token.type === 'tag' && token.name === 'raw') inRaw = true; + if (token.type === 'tag' && token.name === 'endraw') inRaw = false; + + if (shouldTrimRight(token, inRaw, options)) { + trimRight(tokens[i + 1], options.greedy); + } + }); +} + +function shouldTrimLeft(token, inRaw, options) { + if (inRaw) return false; + if (token.type === 'tag') return token.trim_left || options.trim_tag_left; + if (token.type === 'value') return token.trim_left || options.trim_value_left; +} + +function shouldTrimRight(token, inRaw, options) { + if (inRaw) return false; + if (token.type === 'tag') return token.trim_right || options.trim_tag_right; + if (token.type === 'value') return token.trim_right || options.trim_value_right; +} + +function trimLeft(token, greedy) { + if (!token || token.type !== 'html') return; + + var rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g; + token.value = token.value.replace(rLeft, ''); +} + +function trimRight(token, greedy) { + if (!token || token.type !== 'html') return; + + var rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g; + token.value = token.value.replace(rRight, ''); +} + +function parse(input, file, options) { + assert(isString(input), 'illegal input'); + + var rLiquid = /({%-?([\s\S]*?)-?%})|({{-?([\s\S]*?)-?}})/g; + var currIndent = 0; + var lineNumber = LineNumber(input); + var lastMatchEnd = 0; + var tokens = []; + + for (var match; match = rLiquid.exec(input); lastMatchEnd = rLiquid.lastIndex) { + if (match.index > lastMatchEnd) { + tokens.push(parseHTMLToken(lastMatchEnd, match.index)); + } + tokens.push(match[1] ? parseTagToken(match[1], match[2].trim(), match.index) : parseValueToken(match[3], match[4].trim(), match.index)); + } + if (input.length > lastMatchEnd) { + tokens.push(parseHTMLToken(lastMatchEnd, input.length)); + } + whiteSpaceCtrl(tokens, options); + return tokens; + + function parseTagToken(raw, value$$1, pos) { + var match = value$$1.match(tagLine); + var token = { + type: 'tag', + indent: currIndent, + line: lineNumber.get(pos), + trim_left: raw.slice(0, 3) === '{%-', + trim_right: raw.slice(-3) === '-%}', + raw: raw, + value: value$$1, + input: input, + file: file + }; + if (!match) { + throw new TokenizationError('illegal tag syntax', token); + } + token.name = match[1]; + token.args = match[2]; + return token; + } + + function parseValueToken(raw, value$$1, pos) { + return { + type: 'value', + line: lineNumber.get(pos), + trim_left: raw.slice(0, 3) === '{{-', + trim_right: raw.slice(-3) === '-}}', + raw: raw, + value: value$$1, + input: input, + file: file + }; + } + + function parseHTMLToken(begin, end) { + var htmlFragment = input.slice(begin, end); + currIndent = last(htmlFragment.split('\n')).length; + + return { + type: 'html', + raw: htmlFragment, + value: htmlFragment + }; + } +} + +function LineNumber(html) { + var parsedLinesCount = 0; + var lastMatchBegin = -1; + + return { + get: function get(pos) { + var lines = html.slice(lastMatchBegin + 1, pos).split('\n'); + parsedLinesCount += lines.length - 1; + lastMatchBegin = pos; + return parsedLinesCount + 1; + } + }; +} + +function readFileAsync(filepath) { + return new Promise(function (resolve, reject) { + fs.readFile(filepath, 'utf8', function (err, content) { + err ? reject(err) : resolve(content); + }); + }); +} +function statFileAsync(path$$1) { + return new Promise(function (resolve, reject) { + fs.stat(path$$1, function (err, stat) { + return err ? reject(err) : resolve(stat); + }); + }); +} + +var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/; +var urlRe = /^(?:\w+:)?\/\/([^\s.]+\.\S{2}|localhost[:?\d]*)\S*$/; + +// https://github.com/jinder/path/blob/master/path.js#L567 +function extname(path$$1) { + return splitPathRe.exec(path$$1).slice(1)[3]; +} + +// https://www.npmjs.com/package/is-url +function valid(path$$1) { + return urlRe.test(path$$1); +} + +function resolve(root, path$$1) { + if (isArray(root)) { + root = root[0]; + } + if (root && last(root) !== '/') { + root += '/'; + } + return resolveUrl(root, path$$1); +} + +function resolveUrl(root, path$$1) { + var base = document.createElement('base'); + base.href = arguments[0]; + + var head = document.getElementsByTagName('head')[0]; + head.insertBefore(base, head.firstChild); + + var a = document.createElement('a'); + a.href = path$$1; + var resolved = a.href; + base.href = resolved; + + head.removeChild(base); + + return resolved; +} + +function Operators (isTruthy) { + return { + '==': 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 isTruthy(l) && isTruthy(r); + }, + 'or': function or(l, r) { + return isTruthy(l) || isTruthy(r); + } + }; +} + +var operators$1 = Operators(isTruthy); + +function evalExp(exp, scope) { + assert(scope, 'unable to evalExp: scope undefined'); + var operatorREs = operators; + var match = void 0; + for (var i = 0; i < operatorREs.length; i++) { + var operatorRE = operatorREs[i]; + var expRE = new RegExp('^(' + quoteBalanced.source + ')(' + operatorRE.source + ')(' + quoteBalanced.source + ')$'); + if (match = exp.match(expRE)) { + var l = evalExp(match[1], scope); + var op = operators$1[match[2].trim()]; + var r = evalExp(match[3], scope); + return op(l, r); + } + } + + if (match = exp.match(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); +} + +function evalValue(str, scope) { + str = str && str.trim(); + if (!str) return undefined; + + if (isLiteral(str)) { + return parseLiteral(str); + } + if (isVariable(str)) { + return scope.get(str); + } + throw new TypeError('cannot eval \'' + str + '\' as value'); +} + +function isTruthy(val) { + return !isFalsy(val); +} + +function isFalsy(val) { + return val === false || undefined === val || val === null; +} + +var render = { + renderTemplates: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(templates, scope) { + var renderTemplate = function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(template) { + var partial; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!(template.type === 'tag')) { + _context.next = 5; + break; + } + + _context.next = 3; + return this.renderTag(template, scope); + + case 3: + partial = _context.sent; + return _context.abrupt('return', partial === undefined ? '' : partial); + + case 5: + if (!(template.type === 'value')) { + _context.next = 7; + break; + } + + return _context.abrupt('return', this.renderValue(template, scope)); + + case 7: + return _context.abrupt('return', template.value); + + case 8: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + return function renderTemplate(_x3) { + return _ref2.apply(this, arguments); + }; + }(); + + var html, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, tpl; + + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + assert(scope, 'unable to evalTemplates: scope undefined'); + + html = ''; + _iteratorNormalCompletion = true; + _didIteratorError = false; + _iteratorError = undefined; + _context2.prev = 5; + _iterator = templates[Symbol.iterator](); + + case 7: + if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { + _context2.next = 24; + break; + } + + tpl = _step.value; + _context2.prev = 9; + _context2.next = 12; + return renderTemplate.call(this, tpl); + + case 12: + html += _context2.sent; + _context2.next = 21; + break; + + case 15: + _context2.prev = 15; + _context2.t0 = _context2['catch'](9); + + if (!(_context2.t0 instanceof RenderBreakError)) { + _context2.next = 20; + break; + } + + _context2.t0.resolvedHTML = html; + throw _context2.t0; + + case 20: + throw new RenderError(_context2.t0, tpl); + + case 21: + _iteratorNormalCompletion = true; + _context2.next = 7; + break; + + case 24: + _context2.next = 30; + break; + + case 26: + _context2.prev = 26; + _context2.t1 = _context2['catch'](5); + _didIteratorError = true; + _iteratorError = _context2.t1; + + case 30: + _context2.prev = 30; + _context2.prev = 31; + + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + + case 33: + _context2.prev = 33; + + if (!_didIteratorError) { + _context2.next = 36; + break; + } + + throw _iteratorError; + + case 36: + return _context2.finish(33); + + case 37: + return _context2.finish(30); + + case 38: + return _context2.abrupt('return', html); + + case 39: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this, [[5, 26, 30, 38], [9, 15], [31,, 33, 37]]); + })); + + function renderTemplates(_x, _x2) { + return _ref.apply(this, arguments); + } + + return renderTemplates; + }(), + + renderTag: function () { + var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(template, scope) { + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + if (!(template.name === 'continue')) { + _context3.next = 2; + break; + } + + throw new RenderBreakError('continue'); + + case 2: + if (!(template.name === 'break')) { + _context3.next = 4; + break; + } + + throw new RenderBreakError('break'); + + case 4: + return _context3.abrupt('return', template.render(scope)); + + case 5: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + })); + + function renderTag(_x4, _x5) { + return _ref3.apply(this, arguments); + } + + return renderTag; + }(), + + renderValue: function () { + var _ref4 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(template, scope) { + var partial; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + partial = this.evalValue(template, scope); + return _context4.abrupt('return', partial === undefined ? '' : stringify(partial)); + + case 2: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + })); + + function renderValue(_x6, _x7) { + return _ref4.apply(this, arguments); + } + + return renderValue; + }(), + + evalValue: function evalValue$$1(template, scope) { + assert(scope, 'unable to evalValue: scope undefined'); + return template.filters.reduce(function (prev, filter) { + return filter.render(prev, scope); + }, evalExp(template.initial, scope)); + } +}; + +function Render () { + var instance = Object.create(render); + return instance; +} + +function hash$1(markup, scope) { + var obj = {}; + var match = void 0; + hashCapture.lastIndex = 0; + while (match = hashCapture.exec(markup)) { + var k = match[1]; + var v = match[2]; + obj[k] = evalValue(v, scope); + } + return obj; +} + +function Tag () { + var tagImpls = {}; + + var _tagInstance = { + render: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(scope) { + var obj, impl; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + obj = hash$1(this.token.args, scope); + impl = this.tagImpl; + + if (!(typeof impl.render !== 'function')) { + _context.next = 4; + break; + } + + return _context.abrupt('return', ''); + + case 4: + return _context.abrupt('return', impl.render(scope, obj)); + + case 5: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + function render(_x) { + return _ref.apply(this, arguments); + } + + return render; + }(), + 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); + } + } + }; + + function register(name, tag) { + tagImpls[name] = tag; + } + + function construct(token, tokens) { + var instance = Object.create(_tagInstance); + instance.parse(token, tokens); + return instance; + } + + function clear() { + tagImpls = {}; + } + + return { + construct: construct, + register: register, + clear: clear + }; +} + +var valueRE = new RegExp('' + value.source, 'g'); + +function Filter (options) { + options = assign({}, options); + var filters = {}; + + var _filterInstance = { + render: function render(output, scope) { + var args = this.args.map(function (arg) { + return evalValue(arg, scope); + }); + args.unshift(output); + return this.filter.apply(null, args); + }, + parse: function parse(str) { + var match = filterLine.exec(str); + assert(match, 'illegal filter: ' + str); + + var name = match[1]; + var argList = match[2] || ''; + var filter$$1 = filters[name]; + if (typeof filter$$1 !== 'function') { + if (options.strict_filters) { + throw new TypeError('undefined filter: ' + name); + } + this.name = name; + this.filter = function (x) { + return x; + }; + this.args = []; + return this; + } + + var args = []; + while (match = valueRE.exec(argList.trim())) { + var v = match[0]; + var re = new RegExp(v + '\\s*:', 'g'); + var keyMatch = re.exec(match.input); + var currentMatchIsKey = keyMatch && keyMatch.index === match.index; + currentMatchIsKey ? args.push('\'' + v + '\'') : args.push(v); + } + + this.name = name; + this.filter = filter$$1; + this.args = args; + + return this; + } + }; + + function construct(str) { + var instance = Object.create(_filterInstance); + return instance.parse(str); + } + + function register(name, filter$$1) { + filters[name] = filter$$1; + } + + function clear() { + filters = {}; + } + + return { + construct: construct, register: register, clear: clear + }; +} + +function Parser (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 = void 0; + 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; + } + }; + + function parse(tokens) { + var token = void 0; + var templates = []; + while (token = tokens.shift()) { + templates.push(parseToken(token, tokens)); + } + return templates; + } + + function parseToken(token, tokens) { + try { + var tpl = null; + if (token.type === 'tag') { + tpl = parseTag(token, tokens); + } else if (token.type === 'value') { + tpl = parseValue(token.value); + } else { + // token.type === 'html' + tpl = token; + } + tpl.token = token; + return tpl; + } catch (e) { + throw new ParseError(e, token); + } + } + + function parseTag(token, tokens) { + if (token.name === 'continue' || token.name === 'break') return token; + return Tag.construct(token, tokens); + } + + function parseValue(str) { + var match = matchValue(str); + assert(match, 'illegal value string: ' + str); + + var initial = match[0]; + str = str.substr(match.index + match[0].length); + + var filters = []; + while (match = filter.exec(str)) { + filters.push([match[0].trim()]); + } + + return { + type: 'value', + 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, + parseValue: parseValue + }; +} + +/* + * 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). + */ +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); + }); + }); + 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). + */ +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; + }); +} + +function For (liquid, Liquid) { + var render = function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(scope, hash) { + var _this2 = this; + + var collection, offset, limit, contexts, html, finished; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + collection = Liquid.evalExp(this.collection, scope); + + + if (!Array.isArray(collection)) { + if (isString(collection) && collection.length > 0) { + collection = [collection]; + } else if (isObject(collection)) { + collection = Object.keys(collection).map(function (key) { + return [key, collection[key]]; + }); + } + } + + if (!(!Array.isArray(collection) || !collection.length)) { + _context2.next = 4; + break; + } + + return _context2.abrupt('return', liquid.renderer.renderTemplates(this.elseTemplates, scope)); + + case 4: + offset = hash.offset || 0; + limit = hash.limit === undefined ? collection.length : hash.limit; + + + collection = collection.slice(offset, offset + limit); + if (this.reversed) collection.reverse(); + + contexts = collection.map(function (item, i) { + var ctx = {}; + ctx[_this2.variable] = item; + ctx.forloop = { + first: i === 0, + index: i + 1, + index0: i, + last: i === collection.length - 1, + length: collection.length, + rindex: collection.length - i, + rindex0: collection.length - i - 1 + }; + return ctx; + }); + html = ''; + finished = false; + _context2.next = 13; + return mapSeries(contexts, function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(context) { + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!finished) { + _context.next = 2; + break; + } + + return _context.abrupt('return'); + + case 2: + + scope.push(context); + _context.prev = 3; + _context.next = 6; + return liquid.renderer.renderTemplates(_this2.templates, scope); + + case 6: + html += _context.sent; + _context.next = 17; + break; + + case 9: + _context.prev = 9; + _context.t0 = _context['catch'](3); + + if (!(_context.t0 instanceof RenderBreakError)) { + _context.next = 16; + break; + } + + html += _context.t0.resolvedHTML; + if (_context.t0.message === 'break') { + finished = true; + } + _context.next = 17; + break; + + case 16: + throw _context.t0; + + case 17: + scope.pop(context); + + case 18: + case 'end': + return _context.stop(); + } + } + }, _callee, _this2, [[3, 9]]); + })); + + return function (_x3) { + return _ref2.apply(this, arguments); + }; + }()); + + case 13: + return _context2.abrupt('return', html); + + case 14: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); + + return function render(_x, _x2) { + return _ref.apply(this, arguments); + }; + }(); + + var RenderBreakError = Liquid.Types.RenderBreakError; + var lexical = Liquid.lexical; + var re = new RegExp('^(' + lexical.identifier.source + ')\\s+in\\s+' + ('(' + lexical.value.source + ')') + ('(?:\\s+' + lexical.hash.source + ')*') + '(?:\\s+(reversed))?' + ('(?:\\s+' + lexical.hash.source + ')*$')); + + liquid.registerTag('for', { parse: parse, render: render }); + + 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]; + + this.templates = []; + this.elseTemplates = []; + + var p = void 0; + 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(); + } +} + +function Assign (liquid, Liquid) { + var rIdentifier = Liquid.lexical.identifier; + var re = new RegExp('(' + rIdentifier.source + ')\\s*=(.*)'); + var AssignScope = Liquid.Types.AssignScope; + + + liquid.registerTag('assign', { + parse: function parse(token) { + var match = token.args.match(re); + assert(match, 'illegal token ' + token.raw); + this.key = match[1]; + this.value = match[2]; + }, + render: function render(scope) { + var ctx = Object.create(AssignScope); + ctx[this.key] = liquid.evalValue(this.value, scope); + scope.push(ctx); + return Promise.resolve(''); + } + }); +} + +function Capture (liquid, Liquid) { + var rIdentifier = Liquid.lexical.identifier; + var re = new RegExp('(' + rIdentifier.source + ')'); + var CaptureScope = Liquid.Types.CaptureScope; + + + liquid.registerTag('capture', { + parse: function parse(tagToken, remainTokens) { + var _this = this; + + var match = tagToken.args.match(re); + assert(match, tagToken.args + ' not valid identifier'); + + this.variable = match[1]; + this.templates = []; + + var stream = liquid.parser.parseStream(remainTokens); + stream.on('tag:endcapture', function (token) { + return stream.stop(); + }).on('template', function (tpl) { + return _this.templates.push(tpl); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + stream.start(); + }, + render: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(scope, hash) { + var html, ctx; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return liquid.renderer.renderTemplates(this.templates, scope); + + case 2: + html = _context.sent; + ctx = Object.create(CaptureScope); + + ctx[this.variable] = html; + scope.push(ctx); + + case 6: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + function render(_x, _x2) { + return _ref.apply(this, arguments); + } + + return render; + }() + }); +} + +function Case (liquid, Liquid) { + liquid.registerTag('case', { + + parse: function parse(tagToken, remainTokens) { + var _this = this; + + this.cond = tagToken.args; + this.cases = []; + this.elseTemplates = []; + + var p = []; + var stream = liquid.parser.parseStream(remainTokens).on('tag:when', function (token) { + _this.cases.push({ + val: token.args, + templates: p = [] + }); + }).on('tag:else', function () { + return p = _this.elseTemplates; + }).on('tag:endcase', function (token) { + return stream.stop(); + }).on('template', function (tpl) { + return p.push(tpl); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + + stream.start(); + }, + + render: function render(scope, hash) { + for (var i = 0; i < this.cases.length; i++) { + var branch = this.cases[i]; + var val = Liquid.evalExp(branch.val, scope); + var cond = Liquid.evalExp(this.cond, scope); + if (val === cond) { + return liquid.renderer.renderTemplates(branch.templates, scope); + } + } + return liquid.renderer.renderTemplates(this.elseTemplates, scope); + } + }); +} + +function Comment (liquid) { + liquid.registerTag('comment', { + parse: function parse(tagToken, remainTokens) { + var stream = liquid.parser.parseStream(remainTokens); + stream.on('token', function (token) { + if (token.name === 'endcomment') stream.stop(); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + stream.start(); + } + }); +} + +var staticFileRE = /[^\s,]+/; + +function Include (liquid, Liquid) { + var lexical = Liquid.lexical; + var withRE = new RegExp('with\\s+(' + lexical.value.source + ')'); + + liquid.registerTag('include', { + parse: function parse(token) { + var match = staticFileRE.exec(token.args); + if (match) { + this.staticValue = match[0]; + } + + match = lexical.value.exec(token.args); + if (match) { + this.value = match[0]; + } + + match = withRE.exec(token.args); + if (match) { + this.with = match[1]; + } + }, + render: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(scope, hash) { + var filepath, template, originBlocks, originBlockMode, templates, html; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + filepath = void 0; + + if (!scope.opts.dynamicPartials) { + _context.next = 12; + break; + } + + if (!lexical.quotedLine.exec(this.value)) { + _context.next = 9; + break; + } + + template = this.value.slice(1, -1); + _context.next = 6; + return liquid.parseAndRender(template, scope.getAll(), scope.opts); + + case 6: + filepath = _context.sent; + _context.next = 10; + break; + + case 9: + filepath = Liquid.evalValue(this.value, scope); + + case 10: + _context.next = 13; + break; + + case 12: + filepath = this.staticValue; + + case 13: + assert(filepath, 'cannot include with empty filename'); + + originBlocks = scope.opts.blocks; + originBlockMode = scope.opts.blockMode; + + + scope.opts.blocks = {}; + scope.opts.blockMode = 'output'; + if (this.with) { + hash[filepath] = Liquid.evalValue(this.with, scope); + } + _context.next = 21; + return liquid.getTemplate(filepath, scope.opts.root); + + case 21: + templates = _context.sent; + + scope.push(hash); + _context.next = 25; + return liquid.renderer.renderTemplates(templates, scope); + + case 25: + html = _context.sent; + + scope.pop(hash); + scope.opts.blocks = originBlocks; + scope.opts.blockMode = originBlockMode; + return _context.abrupt('return', html); + + case 30: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + function render(_x, _x2) { + return _ref.apply(this, arguments); + } + + return render; + }() + }); +} + +function Decrement (liquid, Liquid) { + var lexical = Liquid.lexical; + var _Liquid$Types = Liquid.Types, + CaptureScope = _Liquid$Types.CaptureScope, + AssignScope = _Liquid$Types.AssignScope, + DecrementScope = _Liquid$Types.DecrementScope; + + + liquid.registerTag('decrement', { + parse: function parse(token) { + var match = token.args.match(lexical.identifier); + assert(match, 'illegal identifier ' + token.args); + this.variable = match[0]; + }, + render: function render(scope, hash) { + var context = scope.findContextFor(this.variable, function (ctx) { + return Object.getPrototypeOf(ctx) !== CaptureScope && Object.getPrototypeOf(ctx) !== AssignScope; + }); + if (!context) { + context = Object.create(DecrementScope); + scope.unshift(context); + } + if (typeof context[this.variable] !== 'number') { + context[this.variable] = 0; + } + return --context[this.variable]; + } + }); +} + +function Cycle (liquid, Liquid) { + var rValue = Liquid.lexical.value; + var groupRE = new RegExp('^(?:(' + rValue.source + ')\\s*:\\s*)?(.*)$'); + var candidatesRE = new RegExp(rValue.source, 'g'); + + liquid.registerTag('cycle', { + + parse: function parse(tagToken, remainTokens) { + var match = groupRE.exec(tagToken.args); + assert(match, 'illegal tag: ' + tagToken.raw); + + this.group = match[1] || ''; + var candidates = match[2]; + + this.candidates = []; + + while (match = candidatesRE.exec(candidates)) { + this.candidates.push(match[0]); + } + assert(this.candidates.length, 'empty candidates: ' + tagToken.raw); + }, + + render: function render(scope, hash) { + var group = Liquid.evalValue(this.group, scope); + var fingerprint = 'cycle:' + group + ':' + this.candidates.join(','); + + var groups = scope.opts.groups = scope.opts.groups || {}; + var idx = groups[fingerprint]; + + if (idx === undefined) { + idx = groups[fingerprint] = 0; + } + + var candidate = this.candidates[idx]; + idx = (idx + 1) % this.candidates.length; + groups[fingerprint] = idx; + + return Liquid.evalValue(candidate, scope); + } + }); +} + +function If (liquid, Liquid) { + liquid.registerTag('if', { + + parse: function parse(tagToken, remainTokens) { + var _this = this; + + this.branches = []; + this.elseTemplates = []; + + var p = void 0; + var stream = liquid.parser.parseStream(remainTokens).on('start', function () { + return _this.branches.push({ + cond: tagToken.args, + templates: p = [] + }); + }).on('tag:elsif', function (token) { + _this.branches.push({ + cond: token.args, + templates: p = [] + }); + }).on('tag:else', function () { + return p = _this.elseTemplates; + }).on('tag:endif', function (token) { + return stream.stop(); + }).on('template', function (tpl) { + return p.push(tpl); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + + stream.start(); + }, + + render: function render(scope, hash) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.branches[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var branch = _step.value; + + var cond = Liquid.evalExp(branch.cond, scope); + if (Liquid.isTruthy(cond)) { + return liquid.renderer.renderTemplates(branch.templates, scope); + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return liquid.renderer.renderTemplates(this.elseTemplates, scope); + } + }); +} + +function Increment (liquid, Liquid) { + var lexical = Liquid.lexical; + var _Liquid$Types = Liquid.Types, + CaptureScope = _Liquid$Types.CaptureScope, + AssignScope = _Liquid$Types.AssignScope, + IncrementScope = _Liquid$Types.IncrementScope; + + + liquid.registerTag('increment', { + parse: function parse(token) { + var match = token.args.match(lexical.identifier); + assert(match, 'illegal identifier ' + token.args); + this.variable = match[0]; + }, + render: function render(scope, hash) { + var context = scope.findContextFor(this.variable, function (ctx) { + return Object.getPrototypeOf(ctx) !== CaptureScope && Object.getPrototypeOf(ctx) !== AssignScope; + }); + if (!context) { + context = Object.create(IncrementScope); + scope.unshift(context); + } + if (typeof context[this.variable] !== 'number') { + context[this.variable] = 0; + } + var val = context[this.variable]; + context[this.variable]++; + return val; + } + }); +} + +/* + * blockMode: + * * "store": store rendered html into blocks + * * "output": output rendered html + */ + +function Layout (liquid, Liquid) { + var rValue = Liquid.lexical.value; + var staticFileRE = /\S+/; + + liquid.registerTag('layout', { + parse: function parse(token, remainTokens) { + var match = staticFileRE.exec(token.args); + if (match) { + this.staticLayout = match[0]; + } + + match = rValue.exec(token.args); + if (match) { + this.layout = match[0]; + } + + this.tpls = liquid.parser.parse(remainTokens); + }, + render: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(scope, hash) { + var layout, html, templates, partial; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + layout = scope.opts.dynamicPartials ? Liquid.evalValue(this.layout, scope) : this.staticLayout; + + assert(layout, 'cannot apply layout with empty filename'); + + // render the remaining tokens immediately + scope.opts.blockMode = 'store'; + _context.next = 5; + return liquid.renderer.renderTemplates(this.tpls, scope); + + case 5: + html = _context.sent; + + if (scope.opts.blocks[''] === undefined) { + scope.opts.blocks[''] = html; + } + _context.next = 9; + return liquid.getTemplate(layout, scope.opts.root); + + case 9: + templates = _context.sent; + + scope.push(hash); + scope.opts.blockMode = 'output'; + _context.next = 14; + return liquid.renderer.renderTemplates(templates, scope); + + case 14: + partial = _context.sent; + + scope.pop(hash); + return _context.abrupt('return', partial); + + case 17: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + function render(_x, _x2) { + return _ref.apply(this, arguments); + } + + return render; + }() + }); + + liquid.registerTag('block', { + parse: function parse(token, remainTokens) { + var _this = this; + + var match = /\w+/.exec(token.args); + this.block = match ? match[0] : ''; + + this.tpls = []; + var stream = liquid.parser.parseStream(remainTokens).on('tag:endblock', function () { + return stream.stop(); + }).on('template', function (tpl) { + return _this.tpls.push(tpl); + }).on('end', function () { + throw new Error('tag ' + token.raw + ' not closed'); + }); + stream.start(); + }, + render: function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(scope) { + var childDefined, html; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + childDefined = scope.opts.blocks[this.block]; + + if (!(childDefined !== undefined)) { + _context2.next = 5; + break; + } + + _context2.t0 = childDefined; + _context2.next = 8; + break; + + case 5: + _context2.next = 7; + return liquid.renderer.renderTemplates(this.tpls, scope); + + case 7: + _context2.t0 = _context2.sent; + + case 8: + html = _context2.t0; + + if (!(scope.opts.blockMode === 'store')) { + _context2.next = 12; + break; + } + + scope.opts.blocks[this.block] = html; + return _context2.abrupt('return', ''); + + case 12: + return _context2.abrupt('return', html); + + case 13: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function render(_x3) { + return _ref2.apply(this, arguments); + } + + return render; + }() + }); +} + +function Raw (liquid) { + liquid.registerTag('raw', { + parse: function parse(tagToken, remainTokens) { + var _this = this; + + 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 () { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + stream.start(); + }, + render: function render(scope, hash) { + return this.tokens.map(function (token) { + return token.raw; + }).join(''); + } + }); +} + +function Tablerow (liquid, Liquid) { + var lexical = Liquid.lexical; + var re = new RegExp('^(' + lexical.identifier.source + ')\\s+in\\s+' + ('(' + lexical.value.source + ')') + ('(?:\\s+' + lexical.hash.source + ')*$')); + + liquid.registerTag('tablerow', { + + 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.templates = []; + + var p = void 0; + var stream = liquid.parser.parseStream(remainTokens).on('start', function () { + return p = _this.templates; + }).on('tag:endtablerow', function (token) { + return stream.stop(); + }).on('template', function (tpl) { + return p.push(tpl); + }).on('end', function () { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + + stream.start(); + }, + + render: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(scope, hash) { + var _this2 = this; + + var collection, offset, limit, cols, contexts, row, html; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + collection = Liquid.evalExp(this.collection, scope) || []; + offset = hash.offset || 0; + limit = hash.limit === undefined ? collection.length : hash.limit; + + + collection = collection.slice(offset, offset + limit); + cols = hash.cols || collection.length; + contexts = collection.map(function (item, i) { + var ctx = {}; + ctx[_this2.variable] = item; + return ctx; + }); + row = void 0; + html = ''; + _context2.next = 10; + return mapSeries(contexts, function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(context, idx) { + var col; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + row = Math.floor(idx / cols) + 1; + col = idx % cols + 1; + + if (col === 1) { + if (row !== 1) { + html += ''; + } + html += ''; + } + + html += ''; + scope.push(context); + _context.next = 7; + return liquid.renderer.renderTemplates(_this2.templates, scope); + + case 7: + html += _context.sent; + + html += ''; + scope.pop(context); + return _context.abrupt('return', html); + + case 11: + case 'end': + return _context.stop(); + } + } + }, _callee, _this2); + })); + + return function (_x3, _x4) { + return _ref2.apply(this, arguments); + }; + }()); + + case 10: + if (row > 0) { + html += ''; + } + return _context2.abrupt('return', html); + + case 12: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function render(_x, _x2) { + return _ref.apply(this, arguments); + } + + return render; + }() + }); +} + +function Unless (liquid, Liquid) { + liquid.registerTag('unless', { + parse: function parse(tagToken, remainTokens) { + var _this = this; + + this.templates = []; + this.elseTemplates = []; + var p = void 0; + var stream = liquid.parser.parseStream(remainTokens).on('start', function (x) { + p = _this.templates; + _this.cond = tagToken.args; + }).on('tag:else', function () { + return p = _this.elseTemplates; + }).on('tag:endunless', function (token) { + return stream.stop(); + }).on('template', function (tpl) { + return p.push(tpl); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + + stream.start(); + }, + + render: function render(scope, hash) { + var cond = Liquid.evalExp(this.cond, scope); + return Liquid.isFalsy(cond) ? liquid.renderer.renderTemplates(this.templates, scope) : liquid.renderer.renderTemplates(this.elseTemplates, scope); + } + }); +} + +function tags (engine, Liquid) { + Assign(engine, Liquid); + Capture(engine, Liquid); + Case(engine, Liquid); + Comment(engine, Liquid); + Cycle(engine, Liquid); + Decrement(engine, Liquid); + For(engine, Liquid); + If(engine, Liquid); + Include(engine, Liquid); + Increment(engine, Liquid); + Layout(engine, Liquid); + Raw(engine, Liquid); + Tablerow(engine, Liquid); + Unless(engine, Liquid); +} + +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' + + // 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]; + }, + + 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; + + while (pad-- > 0) { + result = ch + result; + } + + return result; + } +}; + +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 '%'; + } +}; +formatCodes.h = formatCodes.b; +formatCodes.N = formatCodes.L; + +function strftime (d, format) { + var output = ''; + var remaining = format; + + 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 = formatCodes[ch]; + output += func ? func.call(this, d) : '%' + ch; + } +} + +var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' +}; +var unescapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'" +}; + +var filters = { + 'abs': function abs(v) { + return Math.abs(v); + }, + 'append': function append(v, arg) { + return v + arg; + }, + 'capitalize': function capitalize(str) { + return stringify$1(str).charAt(0).toUpperCase() + str.slice(1); + }, + 'ceil': function ceil(v) { + return Math.ceil(v); + }, + 'concat': function concat(v, arg) { + return Array.prototype.concat.call(v, arg); + }, + 'date': function date(v, arg) { + var date = v; + if (v === 'now') { + date = new Date(); + } else if (isString(v)) { + date = new Date(v); + } + return isValidDate(date) ? strftime(date, arg) : v; + }, + 'default': function _default(v, arg) { + return isTruthy(v) ? v : arg; + }, + 'divided_by': function divided_by(v, arg) { + return v / arg; + }, + 'downcase': function downcase(v) { + return v.toLowerCase(); + }, + 'escape': escape, + + 'escape_once': function escape_once(str) { + return escape(unescape(str)); + }, + 'first': function first(v) { + return v[0]; + }, + 'floor': function floor(v) { + return Math.floor(v); + }, + 'join': function join(v, arg) { + return v.join(arg); + }, + 'last': function last$$1(v) { + return last(v); + }, + 'lstrip': function lstrip(v) { + return stringify$1(v).replace(/^\s+/, ''); + }, + 'map': function map(arr, arg) { + return arr.map(function (v) { + return v[arg]; + }); + }, + 'minus': bindFixed(function (v, arg) { + return v - arg; + }), + 'modulo': bindFixed(function (v, arg) { + return v % arg; + }), + 'newline_to_br': function newline_to_br(v) { + return v.replace(/\n/g, '
'); + }, + 'plus': bindFixed(function (v, arg) { + return Number(v) + Number(arg); + }), + 'prepend': function prepend(v, arg) { + return arg + v; + }, + 'remove': function remove(v, arg) { + return v.split(arg).join(''); + }, + 'remove_first': function remove_first(v, l) { + return v.replace(l, ''); + }, + 'replace': function replace(v, pattern, replacement) { + return stringify$1(v).split(pattern).join(replacement); + }, + 'replace_first': function replace_first(v, arg1, arg2) { + return stringify$1(v).replace(arg1, arg2); + }, + 'reverse': function reverse(v) { + return v.reverse(); + }, + 'round': function round(v, arg) { + var amp = Math.pow(10, arg || 0); + return Math.round(v * amp, arg) / amp; + }, + 'rstrip': function rstrip(str) { + return stringify$1(str).replace(/\s+$/, ''); + }, + 'size': function size(v) { + return v.length; + }, + 'slice': function slice(v, begin, length) { + return v.substr(begin, length === undefined ? 1 : length); + }, + 'sort': function sort(v, arg) { + return v.sort(arg); + }, + 'split': function split(v, arg) { + return stringify$1(v).split(arg); + }, + 'strip': function strip(v) { + return stringify$1(v).trim(); + }, + 'strip_html': function strip_html(v) { + return stringify$1(v).replace(/|||<.*?>/g, ''); + }, + 'strip_newlines': function strip_newlines(v) { + return stringify$1(v).replace(/\n/g, ''); + }, + 'times': function times(v, arg) { + return v * arg; + }, + 'truncate': function truncate(v, l, o) { + v = stringify$1(v); + o = o === undefined ? '...' : o; + l = l || 16; + if (v.length <= l) return v; + return v.substr(0, l - o.length) + o; + }, + 'truncatewords': function truncatewords(v, l, o) { + if (o === undefined) o = '...'; + var arr = v.split(' '); + var ret = arr.slice(0, l).join(' '); + if (arr.length > l) ret += o; + return ret; + }, + 'uniq': function uniq$$1(arr) { + var u = {}; + return (arr || []).filter(function (val) { + if (u.hasOwnProperty(val)) { + return false; + } + u[val] = true; + return true; + }); + }, + 'upcase': function upcase(str) { + return stringify$1(str).toUpperCase(); + }, + 'url_encode': encodeURIComponent +}; + +function escape(str) { + return stringify$1(str).replace(/&|<|>|"|'/g, function (m) { + return escapeMap[m]; + }); +} + +function unescape(str) { + return stringify$1(str).replace(/&(amp|lt|gt|#34|#39);/g, function (m) { + return unescapeMap[m]; + }); +} + +function getFixed(v) { + var p = (v + '').split('.'); + return p.length > 1 ? p[1].length : 0; +} + +function getMaxFixed(l, r) { + return Math.max(getFixed(l), getFixed(r)); +} + +function stringify$1(obj) { + return obj + ''; +} + +function bindFixed(cb) { + return function (l, r) { + var f = getMaxFixed(l, r); + return cb(l, r).toFixed(f); + }; +} + +function isValidDate(date) { + return date instanceof Date && !isNaN(date.getTime()); +} + +function registerAll(liquid) { + return forOwn(filters, function (func, name) { + return liquid.registerFilter(name, func); + }); +} + +registerAll.filters = filters; + +var _engine = { + init: function init(tag, filter$$1, options) { + if (options.cache) { + this.cache = {}; + } + this.options = options; + this.tag = tag; + this.filter = filter$$1; + this.parser = Parser(tag, filter$$1); + this.renderer = Render(); + + tags(this, Liquid); + registerAll(this, Liquid); + + return this; + }, + parse: function parse$$1(html, filepath) { + var tokens = parse(html, filepath, this.options); + return this.parser.parse(tokens); + }, + render: function render(tpl, ctx, opts) { + opts = assign({}, this.options, opts); + var scope = factory(ctx, opts); + return this.renderer.renderTemplates(tpl, scope); + }, + parseAndRender: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(html, ctx, opts) { + var tpl; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return this.parse(html); + + case 2: + tpl = _context.sent; + return _context.abrupt('return', this.render(tpl, ctx, opts)); + + case 4: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + function parseAndRender(_x, _x2, _x3) { + return _ref.apply(this, arguments); + } + + return parseAndRender; + }(), + renderFile: function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(filepath, ctx, opts) { + var templates; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + opts = assign({}, opts); + _context2.next = 3; + return this.getTemplate(filepath, opts.root); + + case 3: + templates = _context2.sent; + return _context2.abrupt('return', this.render(templates, ctx, opts)); + + case 5: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function renderFile(_x4, _x5, _x6) { + return _ref2.apply(this, arguments); + } + + return renderFile; + }(), + evalValue: function evalValue$$1(str, scope) { + var tpl = this.parser.parseValue(str.trim()); + return this.renderer.evalValue(tpl, scope); + }, + registerFilter: function registerFilter(name, filter$$1) { + return this.filter.register(name, filter$$1); + }, + registerTag: function registerTag(name, tag) { + return this.tag.register(name, tag); + }, + lookup: function lookup(filepath, root) { + var _this = this; + + root = this.options.root.concat(root || []); + root = uniq(root); + var paths = root.map(function (root) { + return path.resolve(root, filepath); + }); + return anySeries(paths, function () { + var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(path$$1) { + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _context3.prev = 0; + _context3.next = 3; + return statFileAsync(path$$1); + + case 3: + return _context3.abrupt('return', path$$1); + + case 6: + _context3.prev = 6; + _context3.t0 = _context3['catch'](0); + + _context3.t0.message = _context3.t0.code + ': Failed to lookup ' + filepath + ' in: ' + root; + throw _context3.t0; + + case 10: + case 'end': + return _context3.stop(); + } + } + }, _callee3, _this, [[0, 6]]); + })); + + return function (_x7) { + return _ref3.apply(this, arguments); + }; + }()); + }, + getTemplate: function getTemplate(filepath, root) { + return typeof XMLHttpRequest === 'undefined' ? this.getTemplateFromFile(filepath, root) : this.getTemplateFromUrl(filepath, root); + }, + getTemplateFromFile: function () { + var _ref4 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(filepath, root) { + var _this2 = this; + + return regeneratorRuntime.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + if (!path.extname(filepath)) { + filepath += this.options.extname; + } + _context5.next = 3; + return this.lookup(filepath, root); + + case 3: + filepath = _context5.sent; + return _context5.abrupt('return', this.respectCache(filepath, asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() { + var str; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return readFileAsync(filepath); + + case 2: + str = _context4.sent; + return _context4.abrupt('return', _this2.parse(str, filepath)); + + case 4: + case 'end': + return _context4.stop(); + } + } + }, _callee4, _this2); + })))); + + case 5: + case 'end': + return _context5.stop(); + } + } + }, _callee5, this); + })); + + function getTemplateFromFile(_x8, _x9) { + return _ref4.apply(this, arguments); + } + + return getTemplateFromFile; + }(), + getTemplateFromUrl: function () { + var _ref6 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7(filepath, root) { + var _this3 = this; + + var fullUrl; + return regeneratorRuntime.wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + fullUrl = void 0; + + if (valid(filepath)) { + fullUrl = filepath; + } else { + if (!extname(filepath)) { + filepath += this.options.extname; + } + fullUrl = resolve(root || this.options.root, filepath); + } + return _context7.abrupt('return', this.respectCache(filepath, asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() { + return regeneratorRuntime.wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + _context6.t0 = _this3; + _context6.next = 3; + return get$1(fullUrl); + + case 3: + _context6.t1 = _context6.sent; + return _context6.abrupt('return', _context6.t0.parse.call(_context6.t0, _context6.t1)); + + case 5: + case 'end': + return _context6.stop(); + } + } + }, _callee6, _this3); + })))); + + case 3: + case 'end': + return _context7.stop(); + } + } + }, _callee7, this); + })); + + function getTemplateFromUrl(_x10, _x11) { + return _ref6.apply(this, arguments); + } + + return getTemplateFromUrl; + }(), + respectCache: function () { + var _ref8 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8(key, getter) { + var cacheEnabled, value$$1; + return regeneratorRuntime.wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + cacheEnabled = this.options.cache; + + if (!(cacheEnabled && this.cache[key])) { + _context8.next = 3; + break; + } + + return _context8.abrupt('return', this.cache[key]); + + case 3: + _context8.next = 5; + return getter(); + + case 5: + value$$1 = _context8.sent; + + if (cacheEnabled) { + this.cache[key] = value$$1; + } + return _context8.abrupt('return', value$$1); + + case 8: + case 'end': + return _context8.stop(); + } + } + }, _callee8, this); + })); + + function respectCache(_x12, _x13) { + return _ref8.apply(this, arguments); + } + + return respectCache; + }(), + express: function express(opts) { + opts = opts || {}; + var self = this; + return function (filePath, ctx, cb) { + assert(Array.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 cb(null, html); + }, cb); + }; + } +}; + +function normalizeStringArray(value$$1) { + if (Array.isArray(value$$1)) return value$$1; + if (isString(value$$1)) return [value$$1]; + return []; +} + +function Liquid(options) { + options = assign({ + root: ['.'], + cache: false, + extname: '', + dynamicPartials: true, + trim_tag_right: false, + trim_tag_left: false, + trim_value_right: false, + trim_value_left: false, + greedy: true, + 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; +} + +Liquid.isTruthy = isTruthy; +Liquid.isFalsy = isFalsy; +Liquid.evalExp = evalExp; +Liquid.evalValue = evalValue; +Liquid.Types = { + ParseError: ParseError, + TokenizationError: TokenizationError, + RenderBreakError: RenderBreakError, + AssertionError: AssertionError, + AssignScope: Object.create(null), + CaptureScope: Object.create(null), + IncrementScope: Object.create(null), + DecrementScope: Object.create(null) +}; +Liquid.lexical = lexical; + +module.exports = Liquid; +//# sourceMappingURL=liquid.common.js.map diff --git a/dist/liquid.common.js.map b/dist/liquid.common.js.map new file mode 100644 index 000000000..8ce102f5b --- /dev/null +++ b/dist/liquid.common.js.map @@ -0,0 +1 @@ +{"version":3,"file":"liquid.common.js","sources":["../node_modules/regenerator-runtime/runtime.js","../src/util/underscore.js","../src/lexical.js","../src/util/error.js","../src/util/assert.js","../src/scope.js","../src/util/http.js","../src/whitespace-ctrl.js","../src/tokenizer.js","../src/util/fs.js","../src/util/url.js","../src/operators.js","../src/syntax.js","../src/render.js","../src/tag.js","../src/filter.js","../src/parser.js","../src/util/promise.js","../src/tags/for.js","../src/tags/assign.js","../src/tags/capture.js","../src/tags/case.js","../src/tags/comment.js","../src/tags/include.js","../src/tags/decrement.js","../src/tags/cycle.js","../src/tags/if.js","../src/tags/increment.js","../src/tags/layout.js","../src/tags/raw.js","../src/tags/tablerow.js","../src/tags/unless.js","../src/tags/index.js","../src/util/strftime.js","../src/filters.js","../src/index.js"],"sourcesContent":["/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n!(function(global) {\n \"use strict\";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n var inModule = typeof module === \"object\";\n var runtime = global.regeneratorRuntime;\n if (runtime) {\n if (inModule) {\n // If regeneratorRuntime is defined globally and we're in a module,\n // make the exports object identical to regeneratorRuntime.\n module.exports = runtime;\n }\n // Don't bother evaluating the rest of this file if the runtime was\n // already defined globally.\n return;\n }\n\n // Define the runtime globally (as expected by generated code) as either\n // module.exports (if we're in a module) or a new, empty object.\n runtime = global.regeneratorRuntime = inModule ? module.exports : {};\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n runtime.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don't natively support it.\n var IteratorPrototype = {};\n IteratorPrototype[iteratorSymbol] = function () {\n return this;\n };\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n GeneratorFunctionPrototype.constructor = GeneratorFunction;\n GeneratorFunctionPrototype[toStringTagSymbol] =\n GeneratorFunction.displayName = \"GeneratorFunction\";\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n prototype[method] = function(arg) {\n return this._invoke(method, arg);\n };\n });\n }\n\n runtime.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n runtime.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n if (!(toStringTagSymbol in genFun)) {\n genFun[toStringTagSymbol] = \"GeneratorFunction\";\n }\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n // meant to be awaited.\n runtime.awrap = function(arg) {\n return { __await: arg };\n };\n\n function AsyncIterator(generator) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value &&\n typeof value === \"object\" &&\n hasOwn.call(value, \"__await\")) {\n return Promise.resolve(value.__await).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return Promise.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new Promise(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n AsyncIterator.prototype[asyncIteratorSymbol] = function () {\n return this;\n };\n runtime.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n runtime.async = function(innerFn, outerFn, self, tryLocsList) {\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList)\n );\n\n return runtime.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === \"throw\") {\n if (delegate.iterator.return) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n Gp[toStringTagSymbol] = \"Generator\";\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n Gp[iteratorSymbol] = function() {\n return this;\n };\n\n Gp.toString = function() {\n return \"[object Generator]\";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n runtime.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n runtime.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n})(\n // In sloppy mode, unbound `this` refers to the global object, fallback to\n // Function constructor if we're in global strict mode. That is sadly a form\n // of indirect eval which violates Content Security Policy.\n (function() {\n return this || (typeof self === \"object\" && self);\n })() || Function(\"return this\")()\n);\n","const toStr = Object.prototype.toString\n\n/*\n * Checks if value is classified as a String primitive or object.\n * @param {any} value The value to check.\n * @return {Boolean} Returns true if value is a string, else false.\n */\nexport function isString (value) {\n return toStr.call(value) === '[object String]'\n}\n\nexport function stringify (value) {\n if (isNil(value)) {\n return String(value)\n }\n if (typeof value.to_liquid === 'function') {\n return stringify(value.to_liquid())\n }\n if (typeof value.toLiquid === 'function') {\n return stringify(value.toLiquid())\n }\n if (isString(value)) {\n return value\n }\n\n const cache = []\n return JSON.stringify(value, (key, value) => {\n if (isObject(value)) {\n if (cache.indexOf(value) !== -1) {\n return\n }\n cache.push(value)\n }\n return value\n })\n}\n\nexport function isNil (value) {\n return value === null || value === undefined\n}\n\nexport function isArray (value) {\n // be compatible with IE 8\n return toStr.call(value) === '[object Array]'\n}\n\nexport function isError (value) {\n const signature = Object.prototype.toString.call(value)\n // [object XXXError]\n return signature.substr(-6, 5) === 'Error' ||\n (typeof value.message === 'string' && typeof value.name === 'string')\n}\n\n/*\n * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property.\n * The iteratee is invoked with three arguments: (value, key, object).\n * Iteratee functions may exit iteration early by explicitly returning false.\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @return {Object} Returns object.\n */\nexport function forOwn (object, iteratee) {\n object = object || {}\n for (const k in object) {\n if (object.hasOwnProperty(k)) {\n if (iteratee(object[k], k, object) === false) break\n }\n }\n return object\n}\n\n/*\n * Assigns own enumerable string keyed properties of source objects to the destination object.\n * Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * Note: This method mutates object and is loosely based on Object.assign.\n *\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @return {Object} Returns object.\n */\nexport function assign (object) {\n object = isObject(object) ? object : {}\n const srcs = Array.prototype.slice.call(arguments, 1)\n srcs.forEach((src) => Object.assign(object, src))\n return object\n}\n\nexport function last (arr) {\n return arr[arr.length - 1]\n}\n\nexport function uniq (arr) {\n const u = {}\n const a = []\n for (let i = 0, l = arr.length; i < l; ++i) {\n if (u.hasOwnProperty(arr[i])) {\n continue\n }\n a.push(arr[i])\n u[arr[i]] = 1\n }\n return a\n}\n\n/*\n * Checks if value is the language type of Object.\n * (e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))\n * @param {any} value The value to check.\n * @return {Boolean} Returns true if value is an object, else false.\n */\nexport function isObject (value) {\n const type = typeof value\n return value != null && (type === 'object' || type === 'function')\n}\n\n/*\n * A function to create flexibly-numbered lists of integers,\n * handy for each and map loops. start, if omitted, defaults to 0; step defaults to 1.\n * Returns a list of integers from start (inclusive) to stop (exclusive),\n * incremented (or decremented) by step, exclusive.\n * Note that ranges that stop before they start are considered to be zero-length instead of\n * negative — if you'd like a negative range, use a negative step.\n */\nexport function range (start, stop, step) {\n if (arguments.length === 1) {\n stop = start\n start = 0\n }\n step = step || 1\n\n const arr = []\n for (let i = start; i < stop; i += step) {\n arr.push(i)\n }\n return arr\n}\n","// quote related\nconst singleQuoted = /'[^']*'/\nconst doubleQuoted = /\"[^\"]*\"/\nexport const quoted = new RegExp(`${singleQuoted.source}|${doubleQuoted.source}`)\nexport const quoteBalanced = new RegExp(`(?:${quoted.source}|[^'\"])*`)\n\n// basic types\nexport const integer = /-?\\d+/\nexport const number = /-?\\d+\\.?\\d*|\\.?\\d+/\nexport const bool = /true|false/\n\n// peoperty access\nexport const identifier = /[\\w-]+[?]?/\nexport const subscript = new RegExp(`\\\\[(?:${quoted.source}|[\\\\w-\\\\.]+)\\\\]`)\nexport const literal = new RegExp(`(?:${quoted.source}|${bool.source}|${number.source})`)\nexport const variable = new RegExp(`${identifier.source}(?:\\\\.${identifier.source}|${subscript.source})*`)\n\n// range related\nexport const rangeLimit = new RegExp(`(?:${variable.source}|${number.source})`)\nexport const range = new RegExp(`\\\\(${rangeLimit.source}\\\\.\\\\.${rangeLimit.source}\\\\)`)\nexport const rangeCapture = new RegExp(`\\\\((${rangeLimit.source})\\\\.\\\\.(${rangeLimit.source})\\\\)`)\n\nexport const value = new RegExp(`(?:${variable.source}|${literal.source}|${range.source})`)\n\n// hash related\nexport const hash = new RegExp(`(?:${identifier.source})\\\\s*:\\\\s*(?:${value.source})`)\nexport const hashCapture = new RegExp(`(${identifier.source})\\\\s*:\\\\s*(${value.source})`, 'g')\n\n// full match\nexport const tagLine = new RegExp(`^\\\\s*(${identifier.source})\\\\s*([\\\\s\\\\S]*)\\\\s*$`)\nexport const literalLine = new RegExp(`^${literal.source}$`, 'i')\nexport const variableLine = new RegExp(`^${variable.source}$`)\nexport const numberLine = new RegExp(`^${number.source}$`)\nexport const boolLine = new RegExp(`^${bool.source}$`, 'i')\nexport const quotedLine = new RegExp(`^${quoted.source}$`)\nexport const rangeLine = new RegExp(`^${rangeCapture.source}$`)\nexport const integerLine = new RegExp(`^${integer.source}$`)\n\n// filter related\nexport const valueDeclaration = new RegExp(`(?:${identifier.source}\\\\s*:\\\\s*)?${value.source}`)\nexport const valueList = new RegExp(`${valueDeclaration.source}(\\\\s*,\\\\s*${valueDeclaration.source})*`)\nexport const filter = new RegExp(`${identifier.source}(?:\\\\s*:\\\\s*${valueList.source})?`, 'g')\nexport const filterCapture = new RegExp(`(${identifier.source})(?:\\\\s*:\\\\s*(${valueList.source}))?`)\nexport const filterLine = new RegExp(`^${filterCapture.source}$`)\n\nexport const operators = [\n /\\s+or\\s+/,\n /\\s+and\\s+/,\n /==|!=|<=|>=|<|>|\\s+contains\\s+/\n]\n\nexport function isInteger (str) {\n return integerLine.test(str)\n}\n\nexport function isLiteral (str) {\n return literalLine.test(str)\n}\n\nexport function isRange (str) {\n return rangeLine.test(str)\n}\n\nexport function isVariable (str) {\n return variableLine.test(str)\n}\n\nexport function matchValue (str) {\n return value.exec(str)\n}\n\nexport function parseLiteral (str) {\n let res = str.match(numberLine)\n if (res) {\n return Number(str)\n }\n res = str.match(boolLine)\n if (res) {\n return str.toLowerCase() === 'true'\n }\n res = str.match(quotedLine)\n if (res) {\n return str.slice(1, -1)\n }\n throw new TypeError(`cannot parse '${str}' as literal`)\n}\n","import * as _ from './underscore.js'\n\nfunction initError () {\n this.name = this.constructor.name\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor)\n }\n}\n\nfunction initLiquidError (err, token) {\n initError.call(this)\n\n this.input = token.input\n this.line = token.line\n this.file = token.file\n\n const context = mkContext(token.input, token.line)\n this.message = mkMessage(err.message, token)\n this.stack = context +\n '\\n' + (this.stack || this.message) +\n (err.stack ? '\\nFrom ' + err.stack : '')\n}\n\nexport function TokenizationError (message, token) {\n initLiquidError.call(this, {message: message}, token)\n}\nTokenizationError.prototype = Object.create(Error.prototype)\nTokenizationError.prototype.constructor = TokenizationError\n\nexport function ParseError (e, token) {\n _.assign(this, e)\n this.originalError = e\n\n initLiquidError.call(this, e, token)\n}\nParseError.prototype = Object.create(Error.prototype)\nParseError.prototype.constructor = ParseError\n\nexport function RenderError (e, tpl) {\n // return the original render error\n if (e instanceof RenderError) {\n return e\n }\n _.assign(this, e)\n this.originalError = e\n\n initLiquidError.call(this, e, tpl.token)\n}\nRenderError.prototype = Object.create(Error.prototype)\nRenderError.prototype.constructor = RenderError\n\nexport function RenderBreakError (message) {\n initError.call(this)\n this.message = message + ''\n}\nRenderBreakError.prototype = Object.create(Error.prototype)\nRenderBreakError.prototype.constructor = RenderBreakError\n\nexport function AssertionError (message) {\n initError.call(this)\n this.message = message + ''\n}\nAssertionError.prototype = Object.create(Error.prototype)\nAssertionError.prototype.constructor = AssertionError\n\nfunction mkContext (input, line) {\n const lines = input.split('\\n')\n const begin = Math.max(line - 2, 1)\n const end = Math.min(line + 3, lines.length)\n\n const context = _\n .range(begin, end + 1)\n .map(l => [\n (l === line) ? '>> ' : ' ',\n align(l, end),\n '| ',\n lines[l - 1]\n ].join(''))\n .join('\\n')\n\n return context\n}\n\nfunction align (n, max) {\n const length = (max + '').length\n const str = n + ''\n const blank = Array(length - str.length).join(' ')\n return blank + str\n}\n\nfunction mkMessage (msg, token) {\n msg = msg || ''\n if (token.file) {\n msg += ', file:' + token.file\n }\n if (token.line) {\n msg += ', line:' + token.line\n }\n return msg\n}\n","import {AssertionError} from './error.js'\n\nexport default function (predicate, message) {\n if (!predicate) {\n message = message || `expect ${predicate} to be true`\n throw new AssertionError(message)\n }\n}\n","import * as _ from './util/underscore.js'\nimport * as lexical from './lexical.js'\nimport assert from './util/assert.js'\n\nconst Scope = {\n getAll: function () {\n return this.contexts.reduce((ctx, val) => Object.assign(ctx, val), Object.create(null))\n },\n get: function (path) {\n const paths = this.propertyAccessSeq(path)\n const scope = this.findContextFor(paths[0]) || _.last(this.contexts)\n return paths.reduce((value, key) => this.readProperty(value, key), scope)\n },\n set: function (path, v) {\n const paths = this.propertyAccessSeq(path)\n let scope = this.findContextFor(paths[0]) || _.last(this.contexts)\n paths.some((key, i) => {\n if (!_.isObject(scope)) {\n return true\n }\n if (i === paths.length - 1) {\n scope[key] = v\n return true\n }\n if (undefined === scope[key]) {\n scope[key] = {}\n }\n scope = scope[key]\n })\n },\n unshift: function (ctx) {\n return this.contexts.unshift(ctx)\n },\n push: function (ctx) {\n return this.contexts.push(ctx)\n },\n pop: function (ctx) {\n if (!arguments.length) {\n return this.contexts.pop()\n }\n const i = this.contexts.findIndex(scope => scope === ctx)\n if (i === -1) {\n throw new TypeError('scope not found, cannot pop')\n }\n return this.contexts.splice(i, 1)[0]\n },\n findContextFor: function (key, filter) {\n filter = filter || (() => true)\n for (let i = this.contexts.length - 1; i >= 0; i--) {\n const candidate = this.contexts[i]\n if (!filter(candidate)) continue\n if (key in candidate) {\n return candidate\n }\n }\n return null\n },\n readProperty: function (obj, key) {\n let val\n if (_.isNil(obj)) {\n val = undefined\n } else {\n if (typeof obj.to_liquid === 'function') {\n obj = obj.to_liquid()\n } else if (typeof obj.toLiquid === 'function') {\n obj = obj.toLiquid()\n }\n\n if (key === 'size' && (_.isArray(obj) || _.isString(obj))) {\n val = obj.length\n } else {\n val = obj[key]\n }\n }\n if (_.isNil(val) && this.opts.strict_variables) {\n throw new TypeError(`undefined variable: ${key}`)\n }\n return val\n },\n\n /*\n * Parse property access sequence from access string\n * @example\n * accessSeq(\"foo.bar\") // ['foo', 'bar']\n * accessSeq(\"foo['bar']\") // ['foo', 'bar']\n * accessSeq(\"foo['b]r']\") // ['foo', 'b]r']\n * accessSeq(\"foo[bar.coo]\") // ['foo', 'bar'], for bar.coo == 'bar'\n */\n propertyAccessSeq: function (str) {\n str = String(str)\n const seq = []\n let name = ''\n let j\n let i = 0\n while (i < str.length) {\n switch (str[i]) {\n case '[':\n push()\n\n const delemiter = str[i + 1]\n if (/['\"]/.test(delemiter)) { // foo[\"bar\"]\n j = str.indexOf(delemiter, i + 2)\n assert(j !== -1, `unbalanced ${delemiter}: ${str}`)\n name = str.slice(i + 2, j)\n push()\n i = j + 2\n } else { // foo[bar.coo]\n j = matchRightBracket(str, i + 1)\n assert(j !== -1, `unbalanced []: ${str}`)\n name = str.slice(i + 1, j)\n if (!lexical.isInteger(name)) { // foo[bar] vs. foo[1]\n name = this.get(name)\n }\n push()\n i = j + 1\n }\n break\n case '.':// foo.bar, foo[0].bar\n push()\n i++\n break\n default:// foo.bar\n name += str[i]\n i++\n }\n }\n push()\n\n if (!seq.length) {\n throw new TypeError(`invalid path:\"${str}\"`)\n }\n return seq\n\n function push () {\n if (name.length) seq.push(name)\n name = ''\n }\n }\n}\n\nfunction matchRightBracket (str, begin) {\n let stack = 1 // count of '[' - count of ']'\n for (let i = begin; i < str.length; i++) {\n if (str[i] === '[') {\n stack++\n }\n if (str[i] === ']') {\n stack--\n if (stack === 0) {\n return i\n }\n }\n }\n return -1\n}\n\nexport function factory (ctx, opts) {\n const defaultOptions = {\n dynamicPartials: true,\n strict_variables: false,\n strict_filters: false,\n blocks: {},\n root: []\n }\n const scope = Object.create(Scope)\n scope.opts = _.assign(defaultOptions, opts)\n scope.contexts = [ctx || {}]\n return scope\n}\n","export function get (url) {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest()\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve(xhr.responseText)\n } else {\n reject(new Error(xhr.statusText))\n }\n }\n xhr.onerror = () => {\n reject(new Error('An error occurred whilst sending the response.'))\n }\n xhr.open('GET', url)\n xhr.send()\n })\n}\n","import {assign} from './util/underscore.js'\n\nexport default function whiteSpaceCtrl (tokens, options) {\n options = assign({ greedy: true }, options)\n let inRaw = false\n\n tokens.forEach((token, i) => {\n if (shouldTrimLeft(token, inRaw, options)) {\n trimLeft(tokens[i - 1], options.greedy)\n }\n\n if (token.type === 'tag' && token.name === 'raw') inRaw = true\n if (token.type === 'tag' && token.name === 'endraw') inRaw = false\n\n if (shouldTrimRight(token, inRaw, options)) {\n trimRight(tokens[i + 1], options.greedy)\n }\n })\n}\n\nfunction shouldTrimLeft (token, inRaw, options) {\n if (inRaw) return false\n if (token.type === 'tag') return token.trim_left || options.trim_tag_left\n if (token.type === 'value') return token.trim_left || options.trim_value_left\n}\n\nfunction shouldTrimRight (token, inRaw, options) {\n if (inRaw) return false\n if (token.type === 'tag') return token.trim_right || options.trim_tag_right\n if (token.type === 'value') return token.trim_right || options.trim_value_right\n}\n\nfunction trimLeft (token, greedy) {\n if (!token || token.type !== 'html') return\n\n const rLeft = greedy ? /\\s+$/g : /[\\t\\r ]*$/g\n token.value = token.value.replace(rLeft, '')\n}\n\nfunction trimRight (token, greedy) {\n if (!token || token.type !== 'html') return\n\n const rRight = greedy ? /^\\s+/g : /^[\\t\\r ]*\\n?/g\n token.value = token.value.replace(rRight, '')\n}\n","import * as lexical from './lexical.js'\nimport {TokenizationError} from './util/error.js'\nimport * as _ from './util/underscore.js'\nimport assert from './util/assert.js'\nimport whiteSpaceCtrl from './whitespace-ctrl.js'\n\nexport {default as whiteSpaceCtrl} from './whitespace-ctrl.js'\n\nexport function parse (input, file, options) {\n assert(_.isString(input), 'illegal input')\n\n const rLiquid = /({%-?([\\s\\S]*?)-?%})|({{-?([\\s\\S]*?)-?}})/g\n let currIndent = 0\n const lineNumber = LineNumber(input)\n let lastMatchEnd = 0\n const tokens = []\n\n for (let match; (match = rLiquid.exec(input)); lastMatchEnd = rLiquid.lastIndex) {\n if (match.index > lastMatchEnd) {\n tokens.push(parseHTMLToken(lastMatchEnd, match.index))\n }\n tokens.push(match[1]\n ? parseTagToken(match[1], match[2].trim(), match.index)\n : parseValueToken(match[3], match[4].trim(), match.index))\n }\n if (input.length > lastMatchEnd) {\n tokens.push(parseHTMLToken(lastMatchEnd, input.length))\n }\n whiteSpaceCtrl(tokens, options)\n return tokens\n\n function parseTagToken (raw, value, pos) {\n const match = value.match(lexical.tagLine)\n const token = {\n type: 'tag',\n indent: currIndent,\n line: lineNumber.get(pos),\n trim_left: raw.slice(0, 3) === '{%-',\n trim_right: raw.slice(-3) === '-%}',\n raw,\n value,\n input,\n file\n }\n if (!match) {\n throw new TokenizationError(`illegal tag syntax`, token)\n }\n token.name = match[1]\n token.args = match[2]\n return token\n }\n\n function parseValueToken (raw, value, pos) {\n return {\n type: 'value',\n line: lineNumber.get(pos),\n trim_left: raw.slice(0, 3) === '{{-',\n trim_right: raw.slice(-3) === '-}}',\n raw,\n value,\n input,\n file\n }\n }\n\n function parseHTMLToken (begin, end) {\n const htmlFragment = input.slice(begin, end)\n currIndent = _.last((htmlFragment).split('\\n')).length\n\n return {\n type: 'html',\n raw: htmlFragment,\n value: htmlFragment\n }\n }\n}\n\nfunction LineNumber (html) {\n let parsedLinesCount = 0\n let lastMatchBegin = -1\n\n return {\n get: function (pos) {\n const lines = html.slice(lastMatchBegin + 1, pos).split('\\n')\n parsedLinesCount += lines.length - 1\n lastMatchBegin = pos\n return parsedLinesCount + 1\n }\n }\n}\n","import fs from 'fs'\n\nexport function readFileAsync (filepath) {\n return new Promise(function (resolve, reject) {\n fs.readFile(filepath, 'utf8', function (err, content) {\n err ? reject(err) : resolve(content)\n })\n })\n};\n\nexport function statFileAsync (path) {\n return new Promise(function (resolve, reject) {\n fs.stat(path, (err, stat) => err ? reject(err) : resolve(stat))\n })\n};\n","import {last, isArray} from './underscore'\n\nconst splitPathRe = /^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^/]+?|)(\\.[^./]*|))(?:[/]*)$/\nconst urlRe = /^(?:\\w+:)?\\/\\/([^\\s.]+\\.\\S{2}|localhost[:?\\d]*)\\S*$/\n\n// https://github.com/jinder/path/blob/master/path.js#L567\nexport function extname (path) {\n return splitPathRe.exec(path).slice(1)[3]\n}\n\n// https://www.npmjs.com/package/is-url\nexport function valid (path) {\n return urlRe.test(path)\n}\n\nexport function resolve (root, path) {\n if (isArray(root)) {\n root = root[0]\n }\n if (root && last(root) !== '/') {\n root += '/'\n }\n return resolveUrl(root, path)\n}\n\nfunction resolveUrl (root, path) {\n const base = document.createElement('base')\n base.href = arguments[0]\n\n const head = document.getElementsByTagName('head')[0]\n head.insertBefore(base, head.firstChild)\n\n const a = document.createElement('a')\n a.href = path\n const resolved = a.href\n base.href = resolved\n\n head.removeChild(base)\n\n return resolved\n}\n","export default function (isTruthy) {\n return {\n '==': (l, r) => l === r,\n '!=': (l, r) => l !== r,\n '>': (l, r) => l !== null && r !== null && l > r,\n '<': (l, r) => l !== null && r !== null && l < r,\n '>=': (l, r) => l !== null && r !== null && l >= r,\n '<=': (l, r) => l !== null && r !== null && l <= r,\n 'contains': (l, r) => {\n if (!l) return false\n if (typeof l.indexOf !== 'function') return false\n return l.indexOf(r) > -1\n },\n 'and': (l, r) => isTruthy(l) && isTruthy(r),\n 'or': (l, r) => isTruthy(l) || isTruthy(r)\n }\n}\n","import Operators from './operators.js'\nimport * as lexical from './lexical.js'\nimport assert from './util/assert.js'\n\nconst operators = Operators(isTruthy)\n\nexport function evalExp (exp, scope) {\n assert(scope, 'unable to evalExp: scope undefined')\n const operatorREs = lexical.operators\n let match\n for (let i = 0; i < operatorREs.length; i++) {\n const operatorRE = operatorREs[i]\n const expRE = new RegExp(`^(${lexical.quoteBalanced.source})(${operatorRE.source})(${lexical.quoteBalanced.source})$`)\n if ((match = exp.match(expRE))) {\n const l = evalExp(match[1], scope)\n const op = operators[match[2].trim()]\n const r = evalExp(match[3], scope)\n return op(l, r)\n }\n }\n\n if ((match = exp.match(lexical.rangeLine))) {\n const low = evalValue(match[1], scope)\n const high = evalValue(match[2], scope)\n const range = []\n for (let j = low; j <= high; j++) {\n range.push(j)\n }\n return range\n }\n\n return evalValue(exp, scope)\n}\n\nexport function evalValue (str, scope) {\n str = str && str.trim()\n if (!str) return undefined\n\n if (lexical.isLiteral(str)) {\n return lexical.parseLiteral(str)\n }\n if (lexical.isVariable(str)) {\n return scope.get(str)\n }\n throw new TypeError(`cannot eval '${str}' as value`)\n}\n\nexport function isTruthy (val) {\n return !isFalsy(val)\n}\n\nexport function isFalsy (val) {\n return val === false || undefined === val || val === null\n}\n","import {evalExp} from './syntax.js'\nimport {RenderBreakError, RenderError} from './util/error.js'\nimport {stringify} from './util/underscore.js'\nimport assert from './util/assert.js'\n\nconst render = {\n renderTemplates: async function (templates, scope) {\n assert(scope, 'unable to evalTemplates: scope undefined')\n\n let html = ''\n for (const tpl of templates) {\n try {\n html += await renderTemplate.call(this, tpl)\n } catch (e) {\n if (e instanceof RenderBreakError) {\n e.resolvedHTML = html\n throw e\n }\n throw new RenderError(e, tpl)\n }\n }\n return html\n\n async function renderTemplate (template) {\n if (template.type === 'tag') {\n const partial = await this.renderTag(template, scope)\n return partial === undefined ? '' : partial\n }\n if (template.type === 'value') {\n return this.renderValue(template, scope)\n }\n return template.value\n }\n },\n\n renderTag: async function (template, scope) {\n if (template.name === 'continue') {\n throw new RenderBreakError('continue')\n }\n if (template.name === 'break') {\n throw new RenderBreakError('break')\n }\n return template.render(scope)\n },\n\n renderValue: async function (template, scope) {\n const partial = this.evalValue(template, scope)\n return partial === undefined ? '' : stringify(partial)\n },\n\n evalValue: function (template, scope) {\n assert(scope, 'unable to evalValue: scope undefined')\n return template.filters.reduce(\n (prev, filter) => filter.render(prev, scope),\n evalExp(template.initial, scope))\n }\n}\n\nexport default function () {\n const instance = Object.create(render)\n return instance\n}\n","import {hashCapture} from './lexical.js'\nimport {evalValue} from './syntax.js'\nimport assert from './util/assert.js'\n\nfunction hash (markup, scope) {\n const obj = {}\n let match\n hashCapture.lastIndex = 0\n while ((match = hashCapture.exec(markup))) {\n const k = match[1]\n const v = match[2]\n obj[k] = evalValue(v, scope)\n }\n return obj\n}\n\nexport default function () {\n let tagImpls = {}\n\n const _tagInstance = {\n render: async function (scope) {\n const obj = hash(this.token.args, scope)\n const impl = this.tagImpl\n if (typeof impl.render !== 'function') {\n return ''\n }\n return impl.render(scope, obj)\n },\n parse: function (token, tokens) {\n this.type = 'tag'\n this.token = token\n this.name = token.name\n\n const tagImpl = tagImpls[this.name]\n assert(tagImpl, `tag ${this.name} not found`)\n this.tagImpl = Object.create(tagImpl)\n if (this.tagImpl.parse) {\n this.tagImpl.parse(token, tokens)\n }\n }\n }\n\n function register (name, tag) {\n tagImpls[name] = tag\n }\n\n function construct (token, tokens) {\n const instance = Object.create(_tagInstance)\n instance.parse(token, tokens)\n return instance\n }\n\n function clear () {\n tagImpls = {}\n }\n\n return {\n construct,\n register,\n clear\n }\n}\n","import * as lexical from './lexical.js'\nimport {evalValue} from './syntax.js'\nimport assert from './util/assert.js'\nimport {assign} from './util/underscore.js'\n\nconst valueRE = new RegExp(`${lexical.value.source}`, 'g')\n\nexport default function (options) {\n options = assign({}, options)\n let filters = {}\n\n const _filterInstance = {\n render: function (output, scope) {\n const args = this.args.map(arg => evalValue(arg, scope))\n args.unshift(output)\n return this.filter.apply(null, args)\n },\n parse: function (str) {\n let match = lexical.filterLine.exec(str)\n assert(match, 'illegal filter: ' + str)\n\n const name = match[1]\n const argList = match[2] || ''\n const filter = filters[name]\n if (typeof filter !== 'function') {\n if (options.strict_filters) {\n throw new TypeError(`undefined filter: ${name}`)\n }\n this.name = name\n this.filter = x => x\n this.args = []\n return this\n }\n\n const args = []\n while ((match = valueRE.exec(argList.trim()))) {\n const v = match[0]\n const re = new RegExp(`${v}\\\\s*:`, 'g')\n const keyMatch = re.exec(match.input)\n const currentMatchIsKey = keyMatch && keyMatch.index === match.index\n currentMatchIsKey ? args.push(`'${v}'`) : args.push(v)\n }\n\n this.name = name\n this.filter = filter\n this.args = args\n\n return this\n }\n }\n\n function construct (str) {\n const instance = Object.create(_filterInstance)\n return instance.parse(str)\n }\n\n function register (name, filter) {\n filters[name] = filter\n }\n\n function clear () {\n filters = {}\n }\n\n return {\n construct, register, clear\n }\n}\n","import * as lexical from './lexical.js'\nimport {ParseError} from './util/error.js'\nimport assert from './util/assert.js'\n\nexport default function (Tag, Filter) {\n const stream = {\n init: function (tokens) {\n this.tokens = tokens\n this.handlers = {}\n return this\n },\n on: function (name, cb) {\n this.handlers[name] = cb\n return this\n },\n trigger: function (event, arg) {\n const h = this.handlers[event]\n if (typeof h === 'function') {\n h(arg)\n return true\n }\n },\n start: function () {\n this.trigger('start')\n let token\n while (!this.stopRequested && (token = this.tokens.shift())) {\n if (this.trigger('token', token)) continue\n if (token.type === 'tag' &&\n this.trigger(`tag:${token.name}`, token)) {\n continue\n }\n const template = parseToken(token, this.tokens)\n this.trigger('template', template)\n }\n if (!this.stopRequested) this.trigger('end')\n return this\n },\n stop: function () {\n this.stopRequested = true\n return this\n }\n }\n\n function parse (tokens) {\n let token\n const templates = []\n while ((token = tokens.shift())) {\n templates.push(parseToken(token, tokens))\n }\n return templates\n }\n\n function parseToken (token, tokens) {\n try {\n let tpl = null\n if (token.type === 'tag') {\n tpl = parseTag(token, tokens)\n } else if (token.type === 'value') {\n tpl = parseValue(token.value)\n } else { // token.type === 'html'\n tpl = token\n }\n tpl.token = token\n return tpl\n } catch (e) {\n throw new ParseError(e, token)\n }\n }\n\n function parseTag (token, tokens) {\n if (token.name === 'continue' || token.name === 'break') return token\n return Tag.construct(token, tokens)\n }\n\n function parseValue (str) {\n let match = lexical.matchValue(str)\n assert(match, `illegal value string: ${str}`)\n\n const initial = match[0]\n str = str.substr(match.index + match[0].length)\n\n const filters = []\n while ((match = lexical.filter.exec(str))) {\n filters.push([match[0].trim()])\n }\n\n return {\n type: 'value',\n initial: initial,\n filters: filters.map(str => Filter.construct(str))\n }\n }\n\n function parseStream (tokens) {\n const s = Object.create(stream)\n return s.init(tokens)\n }\n\n return {\n parse,\n parseTag,\n parseStream,\n parseValue\n }\n}\n","/*\n * Call functions in serial until someone resolved.\n * @param {Array} iterable the array to iterate with.\n * @param {Array} iteratee returns a new promise.\n * The iteratee is invoked with three arguments: (value, index, iterable).\n */\nexport function anySeries (iterable, iteratee) {\n let ret = Promise.reject(new Error('init'))\n iterable.forEach(function (item, idx) {\n ret = ret.catch(e => iteratee(item, idx, iterable))\n })\n return ret\n}\n\n/*\n * Call functions in serial until someone rejected.\n * @param {Array} iterable the array to iterate with.\n * @param {Array} iteratee returns a new promise.\n * The iteratee is invoked with three arguments: (value, index, iterable).\n */\nexport function mapSeries (iterable, iteratee) {\n let ret = Promise.resolve('init')\n const result = []\n iterable.forEach(function (item, idx) {\n ret = ret\n .then(() => iteratee(item, idx, iterable))\n .then(x => result.push(x))\n })\n return ret.then(() => result)\n}\n","import {mapSeries} from '../util/promise.js'\nimport {isString, isObject} from '../util/underscore.js'\nimport assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const RenderBreakError = Liquid.Types.RenderBreakError\n const lexical = Liquid.lexical\n const re = new RegExp(`^(${lexical.identifier.source})\\\\s+in\\\\s+` +\n `(${lexical.value.source})` +\n `(?:\\\\s+${lexical.hash.source})*` +\n `(?:\\\\s+(reversed))?` +\n `(?:\\\\s+${lexical.hash.source})*$`)\n\n liquid.registerTag('for', {parse, render})\n\n function parse (tagToken, remainTokens) {\n const match = re.exec(tagToken.args)\n assert(match, `illegal tag: ${tagToken.raw}`)\n this.variable = match[1]\n this.collection = match[2]\n this.reversed = !!match[3]\n\n this.templates = []\n this.elseTemplates = []\n\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', () => (p = this.templates))\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endfor', () => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', () => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n }\n async function render (scope, hash) {\n let collection = Liquid.evalExp(this.collection, scope)\n\n if (!Array.isArray(collection)) {\n if (isString(collection) && collection.length > 0) {\n collection = [collection]\n } else if (isObject(collection)) {\n collection = Object.keys(collection).map((key) => [key, collection[key]])\n }\n }\n if (!Array.isArray(collection) || !collection.length) {\n return liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n\n const offset = hash.offset || 0\n const limit = (hash.limit === undefined) ? collection.length : hash.limit\n\n collection = collection.slice(offset, offset + limit)\n if (this.reversed) collection.reverse()\n\n const contexts = collection.map((item, i) => {\n const ctx = {}\n ctx[this.variable] = item\n ctx.forloop = {\n first: i === 0,\n index: i + 1,\n index0: i,\n last: i === collection.length - 1,\n length: collection.length,\n rindex: collection.length - i,\n rindex0: collection.length - i - 1\n }\n return ctx\n })\n\n let html = ''\n let finished = false\n await mapSeries(contexts, async context => {\n if (finished) return\n\n scope.push(context)\n try {\n html += await liquid.renderer.renderTemplates(this.templates, scope)\n } catch (e) {\n if (e instanceof RenderBreakError) {\n html += e.resolvedHTML\n if (e.message === 'break') {\n finished = true\n }\n } else throw e\n }\n scope.pop(context)\n })\n return html\n }\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const rIdentifier = Liquid.lexical.identifier\n const re = new RegExp(`(${rIdentifier.source})\\\\s*=(.*)`)\n const {AssignScope} = Liquid.Types\n\n liquid.registerTag('assign', {\n parse: function (token) {\n const match = token.args.match(re)\n assert(match, `illegal token ${token.raw}`)\n this.key = match[1]\n this.value = match[2]\n },\n render: function (scope) {\n const ctx = Object.create(AssignScope)\n ctx[this.key] = liquid.evalValue(this.value, scope)\n scope.push(ctx)\n return Promise.resolve('')\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const rIdentifier = Liquid.lexical.identifier\n const re = new RegExp(`(${rIdentifier.source})`)\n const {CaptureScope} = Liquid.Types\n\n liquid.registerTag('capture', {\n parse: function (tagToken, remainTokens) {\n const match = tagToken.args.match(re)\n assert(match, `${tagToken.args} not valid identifier`)\n\n this.variable = match[1]\n this.templates = []\n\n const stream = liquid.parser.parseStream(remainTokens)\n stream.on('tag:endcapture', token => stream.stop())\n .on('template', tpl => this.templates.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n stream.start()\n },\n render: async function (scope, hash) {\n const html = await liquid.renderer.renderTemplates(this.templates, scope)\n const ctx = Object.create(CaptureScope)\n ctx[this.variable] = html\n scope.push(ctx)\n }\n })\n}\n","export default function (liquid, Liquid) {\n liquid.registerTag('case', {\n\n parse: function (tagToken, remainTokens) {\n this.cond = tagToken.args\n this.cases = []\n this.elseTemplates = []\n\n let p = []\n const stream = liquid.parser.parseStream(remainTokens)\n .on('tag:when', token => {\n this.cases.push({\n val: token.args,\n templates: p = []\n })\n })\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endcase', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: function (scope, hash) {\n for (let i = 0; i < this.cases.length; i++) {\n const branch = this.cases[i]\n const val = Liquid.evalExp(branch.val, scope)\n const cond = Liquid.evalExp(this.cond, scope)\n if (val === cond) {\n return liquid.renderer.renderTemplates(branch.templates, scope)\n }\n }\n return liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n })\n}\n","export default function (liquid) {\n liquid.registerTag('comment', {\n parse: function (tagToken, remainTokens) {\n const stream = liquid.parser.parseStream(remainTokens)\n stream\n .on('token', token => {\n if (token.name === 'endcomment') stream.stop()\n })\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n stream.start()\n }\n })\n}\n","import assert from '../util/assert.js'\n\nconst staticFileRE = /[^\\s,]+/\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const withRE = new RegExp(`with\\\\s+(${lexical.value.source})`)\n\n liquid.registerTag('include', {\n parse: function (token) {\n let match = staticFileRE.exec(token.args)\n if (match) {\n this.staticValue = match[0]\n }\n\n match = lexical.value.exec(token.args)\n if (match) {\n this.value = match[0]\n }\n\n match = withRE.exec(token.args)\n if (match) {\n this.with = match[1]\n }\n },\n render: async function (scope, hash) {\n let filepath\n if (scope.opts.dynamicPartials) {\n if (lexical.quotedLine.exec(this.value)) {\n const template = this.value.slice(1, -1)\n filepath = await liquid.parseAndRender(template, scope.getAll(), scope.opts)\n } else {\n filepath = Liquid.evalValue(this.value, scope)\n }\n } else {\n filepath = this.staticValue\n }\n assert(filepath, `cannot include with empty filename`)\n\n const originBlocks = scope.opts.blocks\n const originBlockMode = scope.opts.blockMode\n\n scope.opts.blocks = {}\n scope.opts.blockMode = 'output'\n if (this.with) {\n hash[filepath] = Liquid.evalValue(this.with, scope)\n }\n const templates = await liquid.getTemplate(filepath, scope.opts.root)\n scope.push(hash)\n const html = await liquid.renderer.renderTemplates(templates, scope)\n scope.pop(hash)\n scope.opts.blocks = originBlocks\n scope.opts.blockMode = originBlockMode\n return html\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const {CaptureScope, AssignScope, DecrementScope} = Liquid.Types\n\n liquid.registerTag('decrement', {\n parse: function (token) {\n const match = token.args.match(lexical.identifier)\n assert(match, `illegal identifier ${token.args}`)\n this.variable = match[0]\n },\n render: function (scope, hash) {\n let context = scope.findContextFor(\n this.variable,\n ctx => {\n return Object.getPrototypeOf(ctx) !== CaptureScope &&\n Object.getPrototypeOf(ctx) !== AssignScope\n }\n )\n if (!context) {\n context = Object.create(DecrementScope)\n scope.unshift(context)\n }\n if (typeof context[this.variable] !== 'number') {\n context[this.variable] = 0\n }\n return --context[this.variable]\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const rValue = Liquid.lexical.value\n const groupRE = new RegExp(`^(?:(${rValue.source})\\\\s*:\\\\s*)?(.*)$`)\n const candidatesRE = new RegExp(rValue.source, 'g')\n\n liquid.registerTag('cycle', {\n\n parse: function (tagToken, remainTokens) {\n let match = groupRE.exec(tagToken.args)\n assert(match, `illegal tag: ${tagToken.raw}`)\n\n this.group = match[1] || ''\n const candidates = match[2]\n\n this.candidates = []\n\n while ((match = candidatesRE.exec(candidates))) {\n this.candidates.push(match[0])\n }\n assert(this.candidates.length, `empty candidates: ${tagToken.raw}`)\n },\n\n render: function (scope, hash) {\n const group = Liquid.evalValue(this.group, scope)\n const fingerprint = `cycle:${group}:` + this.candidates.join(',')\n\n const groups = scope.opts.groups = scope.opts.groups || {}\n let idx = groups[fingerprint]\n\n if (idx === undefined) {\n idx = groups[fingerprint] = 0\n }\n\n const candidate = this.candidates[idx]\n idx = (idx + 1) % this.candidates.length\n groups[fingerprint] = idx\n\n return Liquid.evalValue(candidate, scope)\n }\n })\n}\n","export default function (liquid, Liquid) {\n liquid.registerTag('if', {\n\n parse: function (tagToken, remainTokens) {\n this.branches = []\n this.elseTemplates = []\n\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', () => this.branches.push({\n cond: tagToken.args,\n templates: (p = [])\n }))\n .on('tag:elsif', token => {\n this.branches.push({\n cond: token.args,\n templates: p = []\n })\n })\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endif', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: function (scope, hash) {\n for (const branch of this.branches) {\n const cond = Liquid.evalExp(branch.cond, scope)\n if (Liquid.isTruthy(cond)) {\n return liquid.renderer.renderTemplates(branch.templates, scope)\n }\n }\n return liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const {CaptureScope, AssignScope, IncrementScope} = Liquid.Types\n\n liquid.registerTag('increment', {\n parse: function (token) {\n const match = token.args.match(lexical.identifier)\n assert(match, `illegal identifier ${token.args}`)\n this.variable = match[0]\n },\n render: function (scope, hash) {\n let context = scope.findContextFor(\n this.variable,\n ctx => {\n return Object.getPrototypeOf(ctx) !== CaptureScope &&\n Object.getPrototypeOf(ctx) !== AssignScope\n }\n )\n if (!context) {\n context = Object.create(IncrementScope)\n scope.unshift(context)\n }\n if (typeof context[this.variable] !== 'number') {\n context[this.variable] = 0\n }\n const val = context[this.variable]\n context[this.variable]++\n return val\n }\n })\n}\n","import assert from '../util/assert.js'\n\n/*\n * blockMode:\n * * \"store\": store rendered html into blocks\n * * \"output\": output rendered html\n */\n\nexport default function (liquid, Liquid) {\n const rValue = Liquid.lexical.value\n const staticFileRE = /\\S+/\n\n liquid.registerTag('layout', {\n parse: function (token, remainTokens) {\n let match = staticFileRE.exec(token.args)\n if (match) {\n this.staticLayout = match[0]\n }\n\n match = rValue.exec(token.args)\n if (match) {\n this.layout = match[0]\n }\n\n this.tpls = liquid.parser.parse(remainTokens)\n },\n render: async function (scope, hash) {\n const layout = scope.opts.dynamicPartials\n ? Liquid.evalValue(this.layout, scope)\n : this.staticLayout\n assert(layout, `cannot apply layout with empty filename`)\n\n // render the remaining tokens immediately\n scope.opts.blockMode = 'store'\n const html = await liquid.renderer.renderTemplates(this.tpls, scope)\n if (scope.opts.blocks[''] === undefined) {\n scope.opts.blocks[''] = html\n }\n const templates = await liquid.getTemplate(layout, scope.opts.root)\n scope.push(hash)\n scope.opts.blockMode = 'output'\n const partial = await liquid.renderer.renderTemplates(templates, scope)\n scope.pop(hash)\n return partial\n }\n })\n\n liquid.registerTag('block', {\n parse: function (token, remainTokens) {\n const match = /\\w+/.exec(token.args)\n this.block = match ? match[0] : ''\n\n this.tpls = []\n const stream = liquid.parser.parseStream(remainTokens)\n .on('tag:endblock', () => stream.stop())\n .on('template', tpl => this.tpls.push(tpl))\n .on('end', () => {\n throw new Error(`tag ${token.raw} not closed`)\n })\n stream.start()\n },\n render: async function (scope) {\n const childDefined = scope.opts.blocks[this.block]\n const html = childDefined !== undefined\n ? childDefined\n : await liquid.renderer.renderTemplates(this.tpls, scope)\n\n if (scope.opts.blockMode === 'store') {\n scope.opts.blocks[this.block] = html\n return ''\n }\n return html\n }\n })\n}\n","export default function (liquid) {\n liquid.registerTag('raw', {\n parse: function (tagToken, remainTokens) {\n this.tokens = []\n\n const stream = liquid.parser.parseStream(remainTokens)\n stream\n .on('token', token => {\n if (token.name === 'endraw') stream.stop()\n else this.tokens.push(token)\n })\n .on('end', () => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n stream.start()\n },\n render: function (scope, hash) {\n return this.tokens.map(token => token.raw).join('')\n }\n })\n}\n","import {mapSeries} from '../util/promise.js'\nimport assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const re = new RegExp(`^(${lexical.identifier.source})\\\\s+in\\\\s+` +\n `(${lexical.value.source})` +\n `(?:\\\\s+${lexical.hash.source})*$`)\n\n liquid.registerTag('tablerow', {\n\n parse: function (tagToken, remainTokens) {\n const match = re.exec(tagToken.args)\n assert(match, `illegal tag: ${tagToken.raw}`)\n\n this.variable = match[1]\n this.collection = match[2]\n this.templates = []\n\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', () => (p = this.templates))\n .on('tag:endtablerow', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', () => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: async function (scope, hash) {\n let collection = Liquid.evalExp(this.collection, scope) || []\n const offset = hash.offset || 0\n const limit = (hash.limit === undefined) ? collection.length : hash.limit\n\n collection = collection.slice(offset, offset + limit)\n const cols = hash.cols || collection.length\n const contexts = collection.map((item, i) => {\n const ctx = {}\n ctx[this.variable] = item\n return ctx\n })\n\n let row\n let html = ''\n await mapSeries(contexts, async (context, idx) => {\n row = Math.floor(idx / cols) + 1\n const col = (idx % cols) + 1\n if (col === 1) {\n if (row !== 1) {\n html += ''\n }\n html += ``\n }\n\n html += ``\n scope.push(context)\n html += await liquid.renderer.renderTemplates(this.templates, scope)\n html += ''\n scope.pop(context)\n return html\n })\n if (row > 0) {\n html += ''\n }\n return html\n }\n })\n}\n","export default function (liquid, Liquid) {\n liquid.registerTag('unless', {\n parse: function (tagToken, remainTokens) {\n this.templates = []\n this.elseTemplates = []\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', x => {\n p = this.templates\n this.cond = tagToken.args\n })\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endunless', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: function (scope, hash) {\n const cond = Liquid.evalExp(this.cond, scope)\n return Liquid.isFalsy(cond)\n ? liquid.renderer.renderTemplates(this.templates, scope)\n : liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n })\n}\n","import For from './for.js'\nimport Assign from './assign.js'\nimport Capture from './capture.js'\nimport Case from './case.js'\nimport Comment from './comment.js'\nimport Include from './include.js'\nimport Decrement from './decrement.js'\nimport Cycle from './cycle.js'\nimport If from './if.js'\nimport Increment from './increment.js'\nimport Layout from './layout.js'\nimport Raw from './raw.js'\nimport Tablerow from './tablerow.js'\nimport Unless from './unless.js'\n\nexport default function (engine, Liquid) {\n Assign(engine, Liquid)\n Capture(engine, Liquid)\n Case(engine, Liquid)\n Comment(engine, Liquid)\n Cycle(engine, Liquid)\n Decrement(engine, Liquid)\n For(engine, Liquid)\n If(engine, Liquid)\n Include(engine, Liquid)\n Increment(engine, Liquid)\n Layout(engine, Liquid)\n Raw(engine, Liquid)\n Tablerow(engine, Liquid)\n Unless(engine, Liquid)\n}\n","const monthNames = [\n 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',\n 'September', 'October', 'November', 'December'\n]\nconst monthNamesShort = [\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',\n 'Nov', 'Dec'\n]\nconst dayNames = [\n 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'\n]\nconst dayNamesShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']\nconst suffixes = {\n 1: 'st',\n 2: 'nd',\n 3: 'rd',\n 'default': 'th'\n}\n\n// prototype extensions\nconst _date = {\n daysInMonth: function (d) {\n const feb = _date.isLeapYear(d) ? 29 : 28\n return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\n },\n\n getDayOfYear: function (d) {\n let num = 0\n for (let i = 0; i < d.getMonth(); ++i) {\n num += _date.daysInMonth(d)[i]\n }\n return num + d.getDate()\n },\n\n // Startday is an integer of which day to start the week measuring from\n // TODO: that comment was retarted. fix it.\n getWeekOfYear: function (d, startDay) {\n // Skip to startDay of this week\n const now = this.getDayOfYear(d) + (startDay - d.getDay())\n // Find the first startDay of the year\n const jan1 = new Date(d.getFullYear(), 0, 1)\n const then = (7 - jan1.getDay() + startDay)\n return _number.pad(Math.floor((now - then) / 7) + 1, 2)\n },\n\n isLeapYear: function (d) {\n const year = d.getFullYear()\n return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)))\n },\n\n getSuffix: function (d) {\n const str = d.getDate().toString()\n const index = parseInt(str.slice(-1))\n return suffixes[index] || suffixes['default']\n },\n\n century: function (d) {\n return parseInt(d.getFullYear().toString().substring(0, 2), 10)\n }\n}\n\nconst _number = {\n pad: function (value, size, ch) {\n if (!ch) ch = '0'\n let result = value.toString()\n let pad = size - result.length\n\n while (pad-- > 0) {\n result = ch + result\n }\n\n return result\n }\n}\n\nconst formatCodes = {\n a: function (d) {\n return dayNamesShort[d.getDay()]\n },\n A: function (d) {\n return dayNames[d.getDay()]\n },\n b: function (d) {\n return monthNamesShort[d.getMonth()]\n },\n B: function (d) {\n return monthNames[d.getMonth()]\n },\n c: function (d) {\n return d.toLocaleString()\n },\n C: function (d) {\n return _date.century(d)\n },\n d: function (d) {\n return _number.pad(d.getDate(), 2)\n },\n e: function (d) {\n return _number.pad(d.getDate(), 2, ' ')\n },\n H: function (d) {\n return _number.pad(d.getHours(), 2)\n },\n I: function (d) {\n return _number.pad(d.getHours() % 12 || 12, 2)\n },\n j: function (d) {\n return _number.pad(_date.getDayOfYear(d), 3)\n },\n k: function (d) {\n return _number.pad(d.getHours(), 2, ' ')\n },\n l: function (d) {\n return _number.pad(d.getHours() % 12 || 12, 2, ' ')\n },\n L: function (d) {\n return _number.pad(d.getMilliseconds(), 3)\n },\n m: function (d) {\n return _number.pad(d.getMonth() + 1, 2)\n },\n M: function (d) {\n return _number.pad(d.getMinutes(), 2)\n },\n p: function (d) {\n return (d.getHours() < 12 ? 'AM' : 'PM')\n },\n P: function (d) {\n return (d.getHours() < 12 ? 'am' : 'pm')\n },\n q: function (d) {\n return _date.getSuffix(d)\n },\n s: function (d) {\n return Math.round(d.valueOf() / 1000)\n },\n S: function (d) {\n return _number.pad(d.getSeconds(), 2)\n },\n u: function (d) {\n return d.getDay() || 7\n },\n U: function (d) {\n return _date.getWeekOfYear(d, 0)\n },\n w: function (d) {\n return d.getDay()\n },\n W: function (d) {\n return _date.getWeekOfYear(d, 1)\n },\n x: function (d) {\n return d.toLocaleDateString()\n },\n X: function (d) {\n return d.toLocaleTimeString()\n },\n y: function (d) {\n return d.getFullYear().toString().substring(2, 4)\n },\n Y: function (d) {\n return d.getFullYear()\n },\n z: function (d) {\n const tz = d.getTimezoneOffset() / 60 * 100\n return (tz > 0 ? '-' : '+') + _number.pad(Math.abs(tz), 4)\n },\n '%': function () {\n return '%'\n }\n}\nformatCodes.h = formatCodes.b\nformatCodes.N = formatCodes.L\n\nexport default function (d, format) {\n let output = ''\n let remaining = format\n\n while (true) {\n const r = /%./g\n const results = r.exec(remaining)\n\n // No more format codes. Add the remaining text and return\n if (!results) {\n return output + remaining\n }\n\n // Add the preceding text\n output += remaining.slice(0, r.lastIndex - 2)\n remaining = remaining.slice(r.lastIndex)\n\n // Add the format code\n const ch = results[0].charAt(1)\n const func = formatCodes[ch]\n output += func ? func.call(this, d) : '%' + ch\n }\n}\n","import strftime from './util/strftime.js'\nimport * as _ from './util/underscore.js'\nimport {isTruthy} from './syntax.js'\n\nconst escapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n}\nconst unescapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\"\n}\n\nconst filters = {\n 'abs': v => Math.abs(v),\n 'append': (v, arg) => v + arg,\n 'capitalize': str => stringify(str).charAt(0).toUpperCase() + str.slice(1),\n 'ceil': v => Math.ceil(v),\n 'concat': (v, arg) => Array.prototype.concat.call(v, arg),\n 'date': (v, arg) => {\n let date = v\n if (v === 'now') {\n date = new Date()\n } else if (_.isString(v)) {\n date = new Date(v)\n }\n return isValidDate(date) ? strftime(date, arg) : v\n },\n 'default': (v, arg) => isTruthy(v) ? v : arg,\n 'divided_by': (v, arg) => v / arg,\n 'downcase': v => v.toLowerCase(),\n 'escape': escape,\n\n 'escape_once': str => escape(unescape(str)),\n 'first': v => v[0],\n 'floor': v => Math.floor(v),\n 'join': (v, arg) => v.join(arg),\n 'last': v => _.last(v),\n 'lstrip': v => stringify(v).replace(/^\\s+/, ''),\n 'map': (arr, arg) => arr.map(v => v[arg]),\n 'minus': bindFixed((v, arg) => v - arg),\n 'modulo': bindFixed((v, arg) => v % arg),\n 'newline_to_br': v => v.replace(/\\n/g, '
'),\n 'plus': bindFixed((v, arg) => Number(v) + Number(arg)),\n 'prepend': (v, arg) => arg + v,\n 'remove': (v, arg) => v.split(arg).join(''),\n 'remove_first': (v, l) => v.replace(l, ''),\n 'replace': (v, pattern, replacement) =>\n stringify(v).split(pattern).join(replacement),\n 'replace_first': (v, arg1, arg2) => stringify(v).replace(arg1, arg2),\n 'reverse': v => v.reverse(),\n 'round': (v, arg) => {\n const amp = Math.pow(10, arg || 0)\n return Math.round(v * amp, arg) / amp\n },\n 'rstrip': str => stringify(str).replace(/\\s+$/, ''),\n 'size': v => v.length,\n 'slice': (v, begin, length) =>\n v.substr(begin, length === undefined ? 1 : length),\n 'sort': (v, arg) => v.sort(arg),\n 'split': (v, arg) => stringify(v).split(arg),\n 'strip': (v) => stringify(v).trim(),\n 'strip_html': v => stringify(v).replace(/|||<.*?>/g, ''),\n 'strip_newlines': v => stringify(v).replace(/\\n/g, ''),\n 'times': (v, arg) => v * arg,\n 'truncate': (v, l, o) => {\n v = stringify(v)\n o = (o === undefined) ? '...' : o\n l = l || 16\n if (v.length <= l) return v\n return v.substr(0, l - o.length) + o\n },\n 'truncatewords': (v, l, o) => {\n if (o === undefined) o = '...'\n const arr = v.split(' ')\n let ret = arr.slice(0, l).join(' ')\n if (arr.length > l) ret += o\n return ret\n },\n 'uniq': function (arr) {\n const u = {}\n return (arr || []).filter(val => {\n if (u.hasOwnProperty(val)) {\n return false\n }\n u[val] = true\n return true\n })\n },\n 'upcase': str => stringify(str).toUpperCase(),\n 'url_encode': encodeURIComponent\n}\n\nfunction escape (str) {\n return stringify(str).replace(/&|<|>|\"|'/g, m => escapeMap[m])\n}\n\nfunction unescape (str) {\n return stringify(str).replace(/&(amp|lt|gt|#34|#39);/g, m => unescapeMap[m])\n}\n\nfunction getFixed (v) {\n const p = (v + '').split('.')\n return (p.length > 1) ? p[1].length : 0\n}\n\nfunction getMaxFixed (l, r) {\n return Math.max(getFixed(l), getFixed(r))\n}\n\nfunction stringify (obj) {\n return obj + ''\n}\n\nfunction bindFixed (cb) {\n return (l, r) => {\n const f = getMaxFixed(l, r)\n return cb(l, r).toFixed(f)\n }\n}\n\nfunction isValidDate (date) {\n return date instanceof Date && !isNaN(date.getTime())\n}\n\nexport default function registerAll (liquid) {\n return _.forOwn(filters, (func, name) => liquid.registerFilter(name, func))\n}\n\nregisterAll.filters = filters\n","import 'regenerator-runtime/runtime'\nimport * as Scope from './scope'\nimport {get as httpGet} from './util/http.js'\nimport * as _ from './util/underscore.js'\nimport assert from './util/assert.js'\nimport * as tokenizer from './tokenizer.js'\nimport {statFileAsync, readFileAsync} from './util/fs.js'\nimport path from 'path'\nimport {valid as isValidUrl, extname, resolve} from './util/url.js'\nimport * as lexical from './lexical.js'\nimport Render from './render.js'\nimport Tag from './tag.js'\nimport Filter from './filter.js'\nimport Parser from './parser'\nimport {isTruthy, isFalsy, evalExp, evalValue} from './syntax.js'\nimport {anySeries} from './util/promise.js'\nimport {ParseError, TokenizationError, RenderBreakError, AssertionError} from './util/error.js'\nimport tags from './tags/index.js'\nimport filters from './filters.js'\n\nconst _engine = {\n init: function (tag, filter, options) {\n if (options.cache) {\n this.cache = {}\n }\n this.options = options\n this.tag = tag\n this.filter = filter\n this.parser = Parser(tag, filter)\n this.renderer = Render()\n\n tags(this, Liquid)\n filters(this, Liquid)\n\n return this\n },\n parse: function (html, filepath) {\n const tokens = tokenizer.parse(html, filepath, this.options)\n return this.parser.parse(tokens)\n },\n render: function (tpl, ctx, opts) {\n opts = _.assign({}, this.options, opts)\n const scope = Scope.factory(ctx, opts)\n return this.renderer.renderTemplates(tpl, scope)\n },\n parseAndRender: async function (html, ctx, opts) {\n const tpl = await this.parse(html)\n return this.render(tpl, ctx, opts)\n },\n renderFile: async function (filepath, ctx, opts) {\n opts = _.assign({}, opts)\n const templates = await this.getTemplate(filepath, opts.root)\n return this.render(templates, ctx, opts)\n },\n evalValue: function (str, scope) {\n const tpl = this.parser.parseValue(str.trim())\n return this.renderer.evalValue(tpl, scope)\n },\n registerFilter: function (name, filter) {\n return this.filter.register(name, filter)\n },\n registerTag: function (name, tag) {\n return this.tag.register(name, tag)\n },\n lookup: function (filepath, root) {\n root = this.options.root.concat(root || [])\n root = _.uniq(root)\n const paths = root.map(root => path.resolve(root, filepath))\n return anySeries(paths, async path => {\n try {\n await statFileAsync(path)\n return path\n } catch (e) {\n e.message = `${e.code}: Failed to lookup ${filepath} in: ${root}`\n throw e\n }\n })\n },\n getTemplate: function (filepath, root) {\n return typeof XMLHttpRequest === 'undefined'\n ? this.getTemplateFromFile(filepath, root)\n : this.getTemplateFromUrl(filepath, root)\n },\n getTemplateFromFile: async function (filepath, root) {\n if (!path.extname(filepath)) {\n filepath += this.options.extname\n }\n filepath = await this.lookup(filepath, root)\n return this.respectCache(filepath, async () => {\n const str = await readFileAsync(filepath)\n return this.parse(str, filepath)\n })\n },\n getTemplateFromUrl: async function (filepath, root) {\n let fullUrl\n if (isValidUrl(filepath)) {\n fullUrl = filepath\n } else {\n if (!extname(filepath)) {\n filepath += this.options.extname\n }\n fullUrl = resolve(root || this.options.root, filepath)\n }\n return this.respectCache(\n filepath,\n async () => this.parse(await httpGet(fullUrl))\n )\n },\n respectCache: async function (key, getter) {\n const cacheEnabled = this.options.cache\n if (cacheEnabled && this.cache[key]) {\n return this.cache[key]\n }\n const value = await getter()\n if (cacheEnabled) {\n this.cache[key] = value\n }\n return value\n },\n express: function (opts) {\n opts = opts || {}\n const self = this\n return function (filePath, ctx, cb) {\n assert(Array.isArray(this.root) || _.isString(this.root),\n 'illegal views root, are you using express.js?')\n opts.root = this.root\n self.renderFile(filePath, ctx, opts).then(html => cb(null, html), cb)\n }\n }\n}\n\nfunction normalizeStringArray (value) {\n if (Array.isArray(value)) return value\n if (_.isString(value)) return [value]\n return []\n}\n\nexport default function Liquid (options) {\n options = _.assign({\n root: ['.'],\n cache: false,\n extname: '',\n dynamicPartials: true,\n trim_tag_right: false,\n trim_tag_left: false,\n trim_value_right: false,\n trim_value_left: false,\n greedy: true,\n strict_filters: false,\n strict_variables: false\n }, options)\n options.root = normalizeStringArray(options.root)\n\n const engine = Object.create(_engine)\n engine.init(Tag(), Filter(options), options)\n return engine\n}\n\nLiquid.isTruthy = isTruthy\nLiquid.isFalsy = isFalsy\nLiquid.evalExp = evalExp\nLiquid.evalValue = evalValue\nLiquid.Types = {\n ParseError,\n TokenizationError,\n RenderBreakError,\n AssertionError,\n AssignScope: Object.create(null),\n CaptureScope: Object.create(null),\n IncrementScope: Object.create(null),\n DecrementScope: Object.create(null)\n}\nLiquid.lexical = lexical\n"],"names":["global","Op","Object","prototype","hasOwn","hasOwnProperty","undefined","$Symbol","Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","toStringTag","inModule","module","runtime","regeneratorRuntime","exports","wrap","innerFn","outerFn","self","tryLocsList","protoGenerator","Generator","generator","create","context","Context","_invoke","makeInvokeMethod","tryCatch","fn","obj","arg","type","call","err","GenStateSuspendedStart","GenStateSuspendedYield","GenStateExecuting","GenStateCompleted","ContinueSentinel","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","getProto","getPrototypeOf","NativeIteratorPrototype","values","Gp","constructor","displayName","defineIteratorMethods","forEach","method","isGeneratorFunction","genFun","ctor","name","mark","setPrototypeOf","__proto__","awrap","__await","AsyncIterator","invoke","resolve","reject","record","result","value","Promise","then","unwrapped","error","previousPromise","enqueue","callInvokeWithMethodAndArg","async","iter","next","done","state","Error","doneResult","delegate","delegateResult","maybeInvokeDelegate","sent","_sent","dispatchException","abrupt","return","TypeError","info","resultName","nextLoc","toString","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","push","resetTryEntry","completion","reset","keys","object","key","reverse","length","pop","iterable","iteratorMethod","isNaN","i","skipTempReset","prev","charAt","slice","rootEntry","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","thrown","Function","toStr","isString","stringify","isNil","String","to_liquid","toLiquid","cache","JSON","isObject","indexOf","isArray","forOwn","iteratee","k","assign","srcs","Array","arguments","src","last","arr","uniq","u","a","l","range","start","stop","step","singleQuoted","doubleQuoted","quoted","RegExp","source","quoteBalanced","integer","number","bool","identifier","subscript","literal","variable","rangeLimit","rangeCapture","hash","hashCapture","tagLine","literalLine","variableLine","numberLine","boolLine","quotedLine","rangeLine","integerLine","valueDeclaration","valueList","filter","filterCapture","filterLine","operators","isInteger","str","test","isLiteral","isRange","isVariable","matchValue","exec","parseLiteral","res","match","Number","toLowerCase","initError","captureStackTrace","initLiquidError","token","input","line","file","mkContext","message","mkMessage","stack","TokenizationError","ParseError","e","originalError","RenderError","tpl","RenderBreakError","AssertionError","lines","split","begin","Math","max","end","min","_","map","align","join","n","blank","msg","predicate","Scope","contexts","reduce","ctx","val","path","paths","propertyAccessSeq","scope","findContextFor","readProperty","v","some","unshift","findIndex","splice","candidate","opts","strict_variables","seq","j","delemiter","matchRightBracket","lexical","get","factory","defaultOptions","url","xhr","XMLHttpRequest","onload","status","responseText","statusText","onerror","open","send","whiteSpaceCtrl","tokens","options","greedy","inRaw","shouldTrimLeft","shouldTrimRight","trim_left","trim_tag_left","trim_value_left","trim_right","trim_tag_right","trim_value_right","trimLeft","rLeft","replace","trimRight","rRight","parse","rLiquid","currIndent","lineNumber","LineNumber","lastMatchEnd","lastIndex","index","parseHTMLToken","parseTagToken","trim","parseValueToken","raw","pos","args","htmlFragment","html","parsedLinesCount","lastMatchBegin","readFileAsync","filepath","readFile","content","statFileAsync","stat","splitPathRe","urlRe","extname","valid","root","resolveUrl","base","document","createElement","href","head","getElementsByTagName","insertBefore","firstChild","resolved","removeChild","isTruthy","r","Operators","evalExp","exp","operatorREs","operatorRE","expRE","op","low","evalValue","high","isFalsy","render","templates","template","renderTag","partial","renderValue","renderTemplate","resolvedHTML","filters","initial","instance","markup","tagImpls","_tagInstance","tagImpl","impl","register","tag","construct","clear","valueRE","_filterInstance","output","apply","argList","strict_filters","x","re","keyMatch","currentMatchIsKey","Tag","Filter","stream","handlers","cb","event","h","trigger","stopRequested","shift","parseToken","parseTag","parseValue","substr","parseStream","s","init","anySeries","ret","item","idx","catch","mapSeries","liquid","Liquid","collection","renderer","renderTemplates","elseTemplates","offset","limit","reversed","forloop","finished","Types","registerTag","tagToken","remainTokens","p","parser","on","rIdentifier","AssignScope","CaptureScope","cond","cases","branch","staticFileRE","withRE","staticValue","with","dynamicPartials","parseAndRender","getAll","blocks","blockMode","getTemplate","originBlocks","originBlockMode","DecrementScope","rValue","groupRE","candidatesRE","group","candidates","fingerprint","groups","branches","IncrementScope","staticLayout","layout","tpls","block","childDefined","cols","floor","col","row","engine","monthNames","monthNamesShort","dayNames","dayNamesShort","suffixes","_date","d","feb","isLeapYear","num","getMonth","daysInMonth","getDate","startDay","now","getDayOfYear","getDay","jan1","Date","getFullYear","_number","pad","year","parseInt","substring","size","ch","formatCodes","toLocaleString","century","getHours","getMilliseconds","getMinutes","getSuffix","round","valueOf","getSeconds","getWeekOfYear","toLocaleDateString","toLocaleTimeString","tz","getTimezoneOffset","abs","b","N","L","format","remaining","results","func","escapeMap","unescapeMap","toUpperCase","ceil","concat","date","isValidDate","strftime","escape","unescape","bindFixed","pattern","replacement","arg1","arg2","amp","pow","sort","o","encodeURIComponent","m","getFixed","getMaxFixed","f","toFixed","getTime","registerAll","registerFilter","_engine","Parser","Render","tokenizer","code","getTemplateFromFile","getTemplateFromUrl","lookup","respectCache","isValidUrl","httpGet","fullUrl","getter","cacheEnabled","filePath","renderFile","normalizeStringArray"],"mappings":"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"} \ No newline at end of file diff --git a/dist/liquid.js b/dist/liquid.js index 2f396d263..59331c0d6 100644 --- a/dist/liquid.js +++ b/dist/liquid.js @@ -1,533 +1,1278 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Liquid = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i': '>', - '"': '"', - "'": ''' -}; -var unescapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - ''': "'" -}; - -var filters = { - 'abs': function abs(v) { - return Math.abs(v); - }, - 'append': function append(v, arg) { - return v + arg; - }, - 'capitalize': function capitalize(str) { - return stringify(str).charAt(0).toUpperCase() + str.slice(1); - }, - 'ceil': function ceil(v) { - return Math.ceil(v); - }, - 'concat': function concat(v, arg) { - return Array.prototype.concat.call(v, arg); - }, - 'date': function date(v, arg) { - var date = v; - if (v === 'now') { - date = new Date(); - } else if (_.isString(v)) { - date = new Date(v); - } - return isValidDate(date) ? strftime(date, arg) : v; - }, - 'default': function _default(v, arg) { - return isTruthy(v) ? v : arg; - }, - 'divided_by': function divided_by(v, arg) { - return v / arg; - }, - 'downcase': function downcase(v) { - return v.toLowerCase(); - }, - 'escape': escape, - - 'escape_once': function escape_once(str) { - return escape(unescape(str)); - }, - 'first': function first(v) { - return v[0]; - }, - 'floor': function floor(v) { - return Math.floor(v); - }, - 'join': function join(v, arg) { - return v.join(arg); - }, - 'last': function last(v) { - return _.last(v); - }, - 'lstrip': function lstrip(v) { - return stringify(v).replace(/^\s+/, ''); - }, - 'map': function map(arr, arg) { - return arr.map(function (v) { - return v[arg]; - }); - }, - 'minus': bindFixed(function (v, arg) { - return v - arg; - }), - 'modulo': bindFixed(function (v, arg) { - return v % arg; - }), - 'newline_to_br': function newline_to_br(v) { - return v.replace(/\n/g, '
'); - }, - 'plus': bindFixed(function (v, arg) { - return Number(v) + Number(arg); - }), - 'prepend': function prepend(v, arg) { - return arg + v; - }, - 'remove': function remove(v, arg) { - return v.split(arg).join(''); - }, - 'remove_first': function remove_first(v, l) { - return v.replace(l, ''); - }, - 'replace': function replace(v, pattern, replacement) { - return stringify(v).split(pattern).join(replacement); - }, - 'replace_first': function replace_first(v, arg1, arg2) { - return stringify(v).replace(arg1, arg2); - }, - 'reverse': function reverse(v) { - return v.reverse(); - }, - 'round': function round(v, arg) { - var amp = Math.pow(10, arg || 0); - return Math.round(v * amp, arg) / amp; - }, - 'rstrip': function rstrip(str) { - return stringify(str).replace(/\s+$/, ''); - }, - 'size': function size(v) { - return v.length; - }, - 'slice': function slice(v, begin, length) { - return v.substr(begin, length === undefined ? 1 : length); - }, - 'sort': function sort(v, arg) { - return v.sort(arg); - }, - 'split': function split(v, arg) { - return stringify(v).split(arg); - }, - 'strip': function strip(v) { - return stringify(v).trim(); - }, - 'strip_html': function strip_html(v) { - return stringify(v).replace(/|||<.*?>/g, ''); - }, - 'strip_newlines': function strip_newlines(v) { - return stringify(v).replace(/\n/g, ''); - }, - 'times': function times(v, arg) { - return v * arg; - }, - 'truncate': function truncate(v, l, o) { - v = stringify(v); - o = o === undefined ? '...' : o; - l = l || 16; - if (v.length <= l) return v; - return v.substr(0, l - o.length) + o; - }, - 'truncatewords': function truncatewords(v, l, o) { - if (o === undefined) o = '...'; - var arr = v.split(' '); - var ret = arr.slice(0, l).join(' '); - if (arr.length > l) ret += o; - return ret; - }, - 'uniq': function uniq(arr) { - var u = {}; - return (arr || []).filter(function (val) { - if (u.hasOwnProperty(val)) { - return false; - } - u[val] = true; - return true; - }); - }, - 'upcase': function upcase(str) { - return stringify(str).toUpperCase(); - }, - 'url_encode': encodeURIComponent -}; - -function escape(str) { - return stringify(str).replace(/&|<|>|"|'/g, function (m) { - return escapeMap[m]; - }); -} - -function unescape(str) { - return stringify(str).replace(/&(amp|lt|gt|#34|#39);/g, function (m) { - return unescapeMap[m]; - }); -} - -function getFixed(v) { - var p = (v + '').split('.'); - return p.length > 1 ? p[1].length : 0; -} - -function getMaxFixed(l, r) { - return Math.max(getFixed(l), getFixed(r)); -} - -function stringify(obj) { - return obj + ''; -} - -function bindFixed(cb) { - return function (l, r) { - var f = getMaxFixed(l, r); - return cb(l, r).toFixed(f); - }; -} - -function registerAll(liquid) { - return _.forOwn(filters, function (func, name) { - return liquid.registerFilter(name, func); - }); -} - -function isValidDate(date) { - return date instanceof Date && !isNaN(date.getTime()); -} - -registerAll.filters = filters; -module.exports = registerAll; - -},{"./syntax.js":12,"./util/strftime.js":34,"./util/underscore.js":35}],6:[function(require,module,exports){ -'use strict'; - -var _scope = require('./scope'); - -var _scope2 = _interopRequireDefault(_scope); - -var _underscore = require('./util/underscore.js'); - -var _underscore2 = _interopRequireDefault(_underscore); - -var _assert = require('./util/assert.js'); - -var _assert2 = _interopRequireDefault(_assert); - -var _tokenizer = require('./tokenizer.js'); - -var _tokenizer2 = _interopRequireDefault(_tokenizer); - -var _fs = require('./util/fs.js'); - -var _path = require('path'); - -var _path2 = _interopRequireDefault(_path); - -var _url = require('./util/url.js'); - -var _lexical = require('./lexical.js'); - -var _lexical2 = _interopRequireDefault(_lexical); - -var _render = require('./render.js'); - -var _render2 = _interopRequireDefault(_render); - -var _tag = require('./tag.js'); - -var _tag2 = _interopRequireDefault(_tag); - -var _filter = require('./filter.js'); - -var _filter2 = _interopRequireDefault(_filter); - -var _parser = require('./parser'); - -var _parser2 = _interopRequireDefault(_parser); - -var _syntax = require('./syntax.js'); - -var _tags = require('./tags'); - -var _tags2 = _interopRequireDefault(_tags); - -var _filters = require('./filters'); - -var _filters2 = _interopRequireDefault(_filters); - -var _promise = require('./util/promise.js'); - -var _error = require('./util/error.js'); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _engine = { - init: function init(tag, filter, options) { - if (options.cache) { - this.cache = {}; - } - this.options = options; - this.tag = tag; - this.filter = filter; - this.parser = (0, _parser2.default)(tag, filter); - this.renderer = (0, _render2.default)(); - - (0, _tags2.default)(this); - (0, _filters2.default)(this); - - return this; - }, - parse: function parse(html, filepath) { - var tokens = _tokenizer2.default.parse(html, filepath, this.options); - return this.parser.parse(tokens); - }, - render: function render(tpl, ctx, opts) { - opts = _underscore2.default.assign({}, this.options, opts); - var scope = _scope2.default.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); - }); - }, - renderFile: function renderFile(filepath, ctx, opts) { - var _this2 = this; - - opts = _underscore2.default.assign({}, opts); - return this.getTemplate(filepath, opts.root).then(function (templates) { - return _this2.render(templates, ctx, opts); - }); - }, - evalValue: function evalValue(str, scope) { - var tpl = this.parser.parseValue(str.trim()); - return this.renderer.evalValue(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 = _underscore2.default.uniq(root); - var paths = root.map(function (root) { - return _path2.default.resolve(root, filepath); - }); - return (0, _promise.anySeries)(paths, function (path) { - return (0, _fs.statFileAsync)(path).then(function () { - return path; + // Helper for defining the .next, .throw, and .return methods of the + // Iterator interface in terms of a single ._invoke method. + function defineIteratorMethods(prototype) { + ["next", "throw", "return"].forEach(function (method) { + prototype[method] = function (arg) { + return this._invoke(method, arg); + }; }); - }).catch(function (e) { - e.message = e.code + ': Failed to lookup ' + filepath + ' in: ' + root; - throw e; - }); - }, - getTemplate: function getTemplate(filepath, root) { - return typeof XMLHttpRequest === 'undefined' ? this.getTemplateFromFile(filepath, root) : this.getTemplateFromUrl(filepath, root); - }, - getTemplateFromFile: function getTemplateFromFile(filepath, root) { - var _this3 = this; - - if (!_path2.default.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 (0, _fs.readFileAsync)(filepath).then(function (str) { - return _this3.parse(str); - }).then(function (tpl) { - return _this3.cache[filepath] = tpl; - }); + + runtime.isGeneratorFunction = function (genFun) { + var ctor = typeof genFun === "function" && genFun.constructor; + return ctor ? ctor === GeneratorFunction || + // For the native GeneratorFunction constructor, the best we can + // do is to check its .name property. + (ctor.displayName || ctor.name) === "GeneratorFunction" : false; + }; + + runtime.mark = function (genFun) { + if (Object.setPrototypeOf) { + Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); } else { - return (0, _fs.readFileAsync)(filepath).then(function (str) { - return _this3.parse(str, filepath); - }); + genFun.__proto__ = GeneratorFunctionPrototype; + if (!(toStringTagSymbol in genFun)) { + genFun[toStringTagSymbol] = "GeneratorFunction"; + } } - }); - }, - getTemplateFromUrl: function getTemplateFromUrl(filepath, root) { - var _this4 = this; + genFun.prototype = Object.create(Gp); + return genFun; + }; - var fullUrl = void 0; - if ((0, _url.valid)(filepath)) { - fullUrl = filepath; - } else { - if (!(0, _url.extname)(filepath)) { - filepath += this.options.extname; + // Within the body of any async function, `await x` is transformed to + // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test + // `hasOwn.call(value, "__await")` to determine if the yielded value is + // meant to be awaited. + runtime.awrap = function (arg) { + return { __await: arg }; + }; + + function AsyncIterator(generator) { + function invoke(method, arg, resolve, reject) { + var record = tryCatch(generator[method], generator, arg); + if (record.type === "throw") { + reject(record.arg); + } else { + var result = record.arg; + var value = result.value; + if (value && (typeof value === "undefined" ? "undefined" : _typeof(value)) === "object" && hasOwn.call(value, "__await")) { + return Promise.resolve(value.__await).then(function (value) { + invoke("next", value, resolve, reject); + }, function (err) { + invoke("throw", err, resolve, reject); + }); + } + + return Promise.resolve(value).then(function (unwrapped) { + // When a yielded Promise is resolved, its final value becomes + // the .value of the Promise<{value,done}> result for the + // current iteration. + result.value = unwrapped; + resolve(result); + }, function (error) { + // If a rejected Promise was yielded, throw the rejection back + // into the async generator function so it can be handled there. + return invoke("throw", error, resolve, reject); + }); + } } - fullUrl = (0, _url.resolve)(root || this.options.root, filepath); + + var previousPromise; + + function enqueue(method, arg) { + function callInvokeWithMethodAndArg() { + return new Promise(function (resolve, reject) { + invoke(method, arg, resolve, reject); + }); + } + + return previousPromise = + // If enqueue has been called before, then we want to wait until + // all previous Promises have been resolved before calling invoke, + // so that results are always delivered in the correct order. If + // enqueue has not been called before, then it is important to + // call invoke immediately, without waiting on a callback to fire, + // so that the async generator function has the opportunity to do + // any necessary setup in a predictable way. This predictability + // is why the Promise constructor synchronously invokes its + // executor callback, and why async functions synchronously + // execute code before the first await. Since we implement simple + // async functions in terms of async generators, it is especially + // important to get this right, even though it requires care. + previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, + // Avoid propagating failures to Promises returned by later + // invocations of the iterator. + callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); + } + + // Define the unified helper method that is used to implement .next, + // .throw, and .return (see defineIteratorMethods). + this._invoke = enqueue; } - if (this.options.cache) { - var tpl = this.cache[filepath]; - if (tpl) { - return Promise.resolve(tpl); + + defineIteratorMethods(AsyncIterator.prototype); + AsyncIterator.prototype[asyncIteratorSymbol] = function () { + return this; + }; + runtime.AsyncIterator = AsyncIterator; + + // Note that simple async functions are implemented on top of + // AsyncIterator objects; they just return a Promise for the value of + // the final result produced by the iterator. + runtime.async = function (innerFn, outerFn, self, tryLocsList) { + var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList)); + + return runtime.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator. + : iter.next().then(function (result) { + return result.done ? result.value : iter.next(); + }); + }; + + function makeInvokeMethod(innerFn, self, context) { + var state = GenStateSuspendedStart; + + return function invoke(method, arg) { + if (state === GenStateExecuting) { + throw new Error("Generator is already running"); + } + + if (state === GenStateCompleted) { + if (method === "throw") { + throw arg; + } + + // Be forgiving, per 25.3.3.3.3 of the spec: + // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume + return doneResult(); + } + + context.method = method; + context.arg = arg; + + while (true) { + var delegate = context.delegate; + if (delegate) { + var delegateResult = maybeInvokeDelegate(delegate, context); + if (delegateResult) { + if (delegateResult === ContinueSentinel) continue; + return delegateResult; + } + } + + if (context.method === "next") { + // Setting context._sent for legacy support of Babel's + // function.sent implementation. + context.sent = context._sent = context.arg; + } else if (context.method === "throw") { + if (state === GenStateSuspendedStart) { + state = GenStateCompleted; + throw context.arg; + } + + context.dispatchException(context.arg); + } else if (context.method === "return") { + context.abrupt("return", context.arg); + } + + state = GenStateExecuting; + + var record = tryCatch(innerFn, self, context); + if (record.type === "normal") { + // If an exception is thrown from innerFn, we leave state === + // GenStateExecuting and loop back for another invocation. + state = context.done ? GenStateCompleted : GenStateSuspendedYield; + + if (record.arg === ContinueSentinel) { + continue; + } + + return { + value: record.arg, + done: context.done + }; + } else if (record.type === "throw") { + state = GenStateCompleted; + // Dispatch the exception by looping back around to the + // context.dispatchException(context.arg) call above. + context.method = "throw"; + context.arg = record.arg; + } + } + }; + } + + // Call delegate.iterator[context.method](context.arg) and handle the + // result, either by returning a { value, done } result from the + // delegate iterator, or by modifying context.method and context.arg, + // setting context.delegate to null, and returning the ContinueSentinel. + function maybeInvokeDelegate(delegate, context) { + var method = delegate.iterator[context.method]; + if (method === undefined) { + // A .throw or .return when the delegate iterator has no .throw + // method always terminates the yield* loop. + context.delegate = null; + + if (context.method === "throw") { + if (delegate.iterator.return) { + // If the delegate iterator has a return method, give it a + // chance to clean up. + context.method = "return"; + context.arg = undefined; + maybeInvokeDelegate(delegate, context); + + if (context.method === "throw") { + // If maybeInvokeDelegate(context) changed context.method from + // "return" to "throw", let that override the TypeError below. + return ContinueSentinel; + } + } + + context.method = "throw"; + context.arg = new TypeError("The iterator does not provide a 'throw' method"); + } + + return ContinueSentinel; + } + + var record = tryCatch(method, delegate.iterator, context.arg); + + if (record.type === "throw") { + context.method = "throw"; + context.arg = record.arg; + context.delegate = null; + return ContinueSentinel; + } + + var info = record.arg; + + if (!info) { + context.method = "throw"; + context.arg = new TypeError("iterator result is not an object"); + context.delegate = null; + return ContinueSentinel; + } + + if (info.done) { + // Assign the result of the finished delegate to the temporary + // variable specified by delegate.resultName (see delegateYield). + context[delegate.resultName] = info.value; + + // Resume execution at the desired location (see delegateYield). + context.next = delegate.nextLoc; + + // If context.method was "throw" but the delegate handled the + // exception, let the outer generator proceed normally. If + // context.method was "next", forget context.arg since it has been + // "consumed" by the delegate iterator. If context.method was + // "return", allow the original .return call to continue in the + // outer generator. + if (context.method !== "return") { + context.method = "next"; + context.arg = undefined; + } + } else { + // Re-yield the result returned by the delegate method. + return info; + } + + // The delegate iterator is finished, so forget it and continue with + // the outer generator. + context.delegate = null; + return ContinueSentinel; + } + + // Define Generator.prototype.{next,throw,return} in terms of the + // unified ._invoke helper method. + defineIteratorMethods(Gp); + + Gp[toStringTagSymbol] = "Generator"; + + // A Generator should always return itself as the iterator object when the + // @@iterator function is called on it. Some browsers' implementations of the + // iterator prototype chain incorrectly implement this, causing the Generator + // object to not be returned from this call. This ensures that doesn't happen. + // See https://github.com/facebook/regenerator/issues/274 for more details. + Gp[iteratorSymbol] = function () { + return this; + }; + + Gp.toString = function () { + return "[object Generator]"; + }; + + function pushTryEntry(locs) { + var entry = { tryLoc: locs[0] }; + + if (1 in locs) { + entry.catchLoc = locs[1]; + } + + if (2 in locs) { + entry.finallyLoc = locs[2]; + entry.afterLoc = locs[3]; + } + + this.tryEntries.push(entry); + } + + function resetTryEntry(entry) { + var record = entry.completion || {}; + record.type = "normal"; + delete record.arg; + entry.completion = record; + } + + function Context(tryLocsList) { + // The root entry object (effectively a try statement without a catch + // or a finally block) gives us a place to store values thrown from + // locations where there is no enclosing try statement. + this.tryEntries = [{ tryLoc: "root" }]; + tryLocsList.forEach(pushTryEntry, this); + this.reset(true); + } + + runtime.keys = function (object) { + var keys = []; + for (var key in object) { + keys.push(key); + } + keys.reverse(); + + // Rather than returning an object with a next method, we keep + // things simple and return the next function itself. + return function next() { + while (keys.length) { + var key = keys.pop(); + if (key in object) { + next.value = key; + next.done = false; + return next; + } + } + + // To avoid creating an additional object, we just hang the .value + // and .done properties off the next function object itself. This + // also ensures that the minifier will not anonymize the function. + next.done = true; + return next; + }; + }; + + function values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) { + return iteratorMethod.call(iterable); + } + + if (typeof iterable.next === "function") { + return iterable; + } + + if (!isNaN(iterable.length)) { + var i = -1, + next = function next() { + while (++i < iterable.length) { + if (hasOwn.call(iterable, i)) { + next.value = iterable[i]; + next.done = false; + return next; + } + } + + next.value = undefined; + next.done = true; + + return next; + }; + + return next.next = next; + } + } + + // Return an iterator with no values. + return { next: doneResult }; + } + runtime.values = values; + + function doneResult() { + return { value: undefined, done: true }; + } + + Context.prototype = { + constructor: Context, + + reset: function reset(skipTempReset) { + this.prev = 0; + this.next = 0; + // Resetting context._sent for legacy support of Babel's + // function.sent implementation. + this.sent = this._sent = undefined; + this.done = false; + this.delegate = null; + + this.method = "next"; + this.arg = undefined; + + this.tryEntries.forEach(resetTryEntry); + + if (!skipTempReset) { + for (var name in this) { + // Not sure about the optimal order of these conditions: + if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { + this[name] = undefined; + } + } + } + }, + + stop: function stop() { + this.done = true; + + var rootEntry = this.tryEntries[0]; + var rootRecord = rootEntry.completion; + if (rootRecord.type === "throw") { + throw rootRecord.arg; + } + + return this.rval; + }, + + dispatchException: function dispatchException(exception) { + if (this.done) { + throw exception; + } + + var context = this; + function handle(loc, caught) { + record.type = "throw"; + record.arg = exception; + context.next = loc; + + if (caught) { + // If the dispatched exception was caught by a catch block, + // then let that catch block handle the exception normally. + context.method = "next"; + context.arg = undefined; + } + + return !!caught; + } + + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + var record = entry.completion; + + if (entry.tryLoc === "root") { + // Exception thrown outside of any try block that could handle + // it, so set the completion value of the entire function to + // throw the exception. + return handle("end"); + } + + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"); + var hasFinally = hasOwn.call(entry, "finallyLoc"); + + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } else if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else if (hasCatch) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } + } else if (hasFinally) { + if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else { + throw new Error("try statement without catch or finally"); + } + } + } + }, + + abrupt: function abrupt(type, arg) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { + var finallyEntry = entry; + break; + } + } + + if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { + // Ignore the finally entry if control is not jumping to a + // location outside the try/catch block. + finallyEntry = null; + } + + var record = finallyEntry ? finallyEntry.completion : {}; + record.type = type; + record.arg = arg; + + if (finallyEntry) { + this.method = "next"; + this.next = finallyEntry.finallyLoc; + return ContinueSentinel; + } + + return this.complete(record); + }, + + complete: function complete(record, afterLoc) { + if (record.type === "throw") { + throw record.arg; + } + + if (record.type === "break" || record.type === "continue") { + this.next = record.arg; + } else if (record.type === "return") { + this.rval = this.arg = record.arg; + this.method = "return"; + this.next = "end"; + } else if (record.type === "normal" && afterLoc) { + this.next = afterLoc; + } + + return ContinueSentinel; + }, + + finish: function finish(finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.finallyLoc === finallyLoc) { + this.complete(entry.completion, entry.afterLoc); + resetTryEntry(entry); + return ContinueSentinel; + } + } + }, + + "catch": function _catch(tryLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.tryLoc === tryLoc) { + var record = entry.completion; + if (record.type === "throw") { + var thrown = record.arg; + resetTryEntry(entry); + } + return thrown; + } + } + + // The context.catch method must only be called with a location + // argument that corresponds to a known catch block. + throw new Error("illegal catch attempt"); + }, + + delegateYield: function delegateYield(iterable, resultName, nextLoc) { + this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }; + + if (this.method === "next") { + // Deliberately forget the last sent value so that we don't + // accidentally pass it on to the delegate. + this.arg = undefined; + } + + return ContinueSentinel; + } + }; + }( + // In sloppy mode, unbound `this` refers to the global object, fallback to + // Function constructor if we're in global strict mode. That is sadly a form + // of indirect eval which violates Content Security Policy. + function () { + return this || (typeof self === "undefined" ? "undefined" : _typeof(self)) === "object" && self; + }() || Function("return this")()); + + var toStr = Object.prototype.toString; + + /* + * Checks if value is classified as a String primitive or object. + * @param {any} value The value to check. + * @return {Boolean} Returns true if value is a string, else false. + */ + function isString(value) { + return toStr.call(value) === '[object String]'; + } + + function stringify(value) { + if (isNil(value)) { + return String(value); + } + if (typeof value.to_liquid === 'function') { + return stringify(value.to_liquid()); + } + if (typeof value.toLiquid === 'function') { + return stringify(value.toLiquid()); + } + if (isString(value)) { + return value; + } + + var cache = []; + return JSON.stringify(value, function (key, value) { + if (isObject(value)) { + if (cache.indexOf(value) !== -1) { + return; + } + cache.push(value); + } + return value; + }); + } + + function isNil(value) { + return value === null || value === undefined; + } + + function isArray(value) { + // be compatible with IE 8 + return toStr.call(value) === '[object Array]'; + } + + /* + * 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; } } + 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. + * + * Note: This method mutates object and is loosely based on Object.assign. + * + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @return {Object} Returns object. + */ + function assign(object) { + object = isObject(object) ? object : {}; + var srcs = Array.prototype.slice.call(arguments, 1); + srcs.forEach(function (src) { + return Object.assign(object, src); + }); + return object; + } + + function last(arr) { + return arr[arr.length - 1]; + } + + function uniq(arr) { + var u = {}; + var 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; + } + return a; + } + + /* + * 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) { + var type = typeof value === 'undefined' ? 'undefined' : _typeof(value); + return value != null && (type === 'object' || type === 'function'); + } + + /* + * 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; + + var arr = []; + for (var i = start; i < stop; i += step) { + arr.push(i); + } + return arr; + } + + // quote related + var singleQuoted = /'[^']*'/; + var doubleQuoted = /"[^"]*"/; + var quoted = new RegExp(singleQuoted.source + '|' + doubleQuoted.source); + var quoteBalanced = new RegExp('(?:' + quoted.source + '|[^\'"])*'); + + // basic types + var integer = /-?\d+/; + var number = /-?\d+\.?\d*|\.?\d+/; + var bool = /true|false/; + + // peoperty access + var identifier = /[\w-]+[?]?/; + var subscript = new RegExp('\\[(?:' + quoted.source + '|[\\w-\\.]+)\\]'); + var literal = new RegExp('(?:' + quoted.source + '|' + bool.source + '|' + number.source + ')'); + var variable = new RegExp(identifier.source + '(?:\\.' + identifier.source + '|' + subscript.source + ')*'); + + // range related + var rangeLimit = new RegExp('(?:' + variable.source + '|' + number.source + ')'); + var range$1 = new RegExp('\\(' + rangeLimit.source + '\\.\\.' + rangeLimit.source + '\\)'); + var rangeCapture = new RegExp('\\((' + rangeLimit.source + ')\\.\\.(' + rangeLimit.source + ')\\)'); + + var value = new RegExp('(?:' + variable.source + '|' + literal.source + '|' + range$1.source + ')'); + + // hash related + var hash = new RegExp('(?:' + identifier.source + ')\\s*:\\s*(?:' + value.source + ')'); + var hashCapture = new RegExp('(' + identifier.source + ')\\s*:\\s*(' + value.source + ')', 'g'); + + // full match + var tagLine = new RegExp('^\\s*(' + identifier.source + ')\\s*([\\s\\S]*)\\s*$'); + var literalLine = new RegExp('^' + literal.source + '$', 'i'); + var variableLine = new RegExp('^' + variable.source + '$'); + var numberLine = new RegExp('^' + number.source + '$'); + var boolLine = new RegExp('^' + bool.source + '$', 'i'); + var quotedLine = new RegExp('^' + quoted.source + '$'); + var rangeLine = new RegExp('^' + rangeCapture.source + '$'); + var integerLine = new RegExp('^' + integer.source + '$'); + + // filter related + var valueDeclaration = new RegExp('(?:' + identifier.source + '\\s*:\\s*)?' + value.source); + var valueList = new RegExp(valueDeclaration.source + '(\\s*,\\s*' + valueDeclaration.source + ')*'); + var filter = new RegExp(identifier.source + '(?:\\s*:\\s*' + valueList.source + ')?', 'g'); + var filterCapture = new RegExp('(' + identifier.source + ')(?:\\s*:\\s*(' + valueList.source + '))?'); + var filterLine = new RegExp('^' + filterCapture.source + '$'); + + var operators = [/\s+or\s+/, /\s+and\s+/, /==|!=|<=|>=|<|>|\s+contains\s+/]; + + function isInteger(str) { + return integerLine.test(str); + } + + function isLiteral(str) { + return literalLine.test(str); + } + + function isRange(str) { + return rangeLine.test(str); + } + + function isVariable(str) { + return variableLine.test(str); + } + + function matchValue(str) { + return value.exec(str); + } + + function parseLiteral(str) { + 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); + } + throw new TypeError('cannot parse \'' + str + '\' as literal'); + } + + var lexical = ({ + quoted: quoted, + quoteBalanced: quoteBalanced, + integer: integer, + number: number, + bool: bool, + identifier: identifier, + subscript: subscript, + literal: literal, + variable: variable, + rangeLimit: rangeLimit, + range: range$1, + rangeCapture: rangeCapture, + value: value, + hash: hash, + hashCapture: hashCapture, + tagLine: tagLine, + literalLine: literalLine, + variableLine: variableLine, + numberLine: numberLine, + boolLine: boolLine, + quotedLine: quotedLine, + rangeLine: rangeLine, + integerLine: integerLine, + valueDeclaration: valueDeclaration, + valueList: valueList, + filter: filter, + filterCapture: filterCapture, + filterLine: filterLine, + operators: operators, + isInteger: isInteger, + isLiteral: isLiteral, + isRange: isRange, + isVariable: isVariable, + matchValue: matchValue, + parseLiteral: parseLiteral + }); + + function initError() { + this.name = this.constructor.name; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } + + function initLiquidError(err, token) { + initError.call(this); + + this.input = token.input; + this.line = token.line; + this.file = token.file; + + var context = mkContext(token.input, token.line); + this.message = mkMessage(err.message, token); + this.stack = context + '\n' + (this.stack || this.message) + (err.stack ? '\nFrom ' + err.stack : ''); + } + + function TokenizationError(message, token) { + initLiquidError.call(this, { message: message }, token); + } + TokenizationError.prototype = Object.create(Error.prototype); + TokenizationError.prototype.constructor = TokenizationError; + + function ParseError(e, token) { + assign(this, e); + this.originalError = e; + + initLiquidError.call(this, e, token); + } + 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; + + initLiquidError.call(this, e, tpl.token); + } + RenderError.prototype = Object.create(Error.prototype); + RenderError.prototype.constructor = RenderError; + + function RenderBreakError(message) { + initError.call(this); + this.message = message + ''; + } + RenderBreakError.prototype = Object.create(Error.prototype); + RenderBreakError.prototype.constructor = RenderBreakError; + + function AssertionError(message) { + initError.call(this); + 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 context = range(begin, end + 1).map(function (l) { + return [l === line ? '>> ' : ' ', align(l, end), '| ', lines[l - 1]].join(''); + }).join('\n'); + + return context; + } + + function align(n, max) { + 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; + } + + function assert (predicate, message) { + if (!predicate) { + message = message || 'expect ' + predicate + ' to be true'; + throw new AssertionError(message); + } + } + + var Scope = { + getAll: function getAll() { + return this.contexts.reduce(function (ctx, val) { + return Object.assign(ctx, val); + }, Object.create(null)); + }, + get: function get(path) { + var _this = this; + + var paths = this.propertyAccessSeq(path); + var scope = this.findContextFor(paths[0]) || last(this.contexts); + return paths.reduce(function (value$$1, key) { + return _this.readProperty(value$$1, key); + }, scope); + }, + set: function set(path, v) { + var paths = this.propertyAccessSeq(path); + var scope = this.findContextFor(paths[0]) || last(this.contexts); + paths.some(function (key, i) { + if (!isObject(scope)) { + return true; + } + if (i === paths.length - 1) { + scope[key] = v; + return true; + } + if (undefined === scope[key]) { + scope[key] = {}; + } + scope = scope[key]; + }); + }, + unshift: function unshift(ctx) { + return this.contexts.unshift(ctx); + }, + push: function push(ctx) { + return this.contexts.push(ctx); + }, + pop: function pop(ctx) { + if (!arguments.length) { + return this.contexts.pop(); + } + var i = this.contexts.findIndex(function (scope) { + return scope === ctx; + }); + if (i === -1) { + throw new TypeError('scope not found, cannot pop'); + } + return this.contexts.splice(i, 1)[0]; + }, + findContextFor: function findContextFor(key, filter$$1) { + filter$$1 = filter$$1 || function () { + return true; + }; + for (var i = this.contexts.length - 1; i >= 0; i--) { + var candidate = this.contexts[i]; + if (!filter$$1(candidate)) continue; + if (key in candidate) { + return candidate; + } + } + return null; + }, + readProperty: function readProperty(obj, key) { + var val = void 0; + if (isNil(obj)) { + val = undefined; + } else { + if (typeof obj.to_liquid === 'function') { + obj = obj.to_liquid(); + } else if (typeof obj.toLiquid === 'function') { + obj = obj.toLiquid(); + } + + if (key === 'size' && (isArray(obj) || isString(obj))) { + val = obj.length; + } else { + val = obj[key]; + } + } + if (isNil(val) && this.opts.strict_variables) { + throw new TypeError('undefined variable: ' + key); + } + return val; + }, + + /* + * 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) { + str = String(str); + var seq = []; + var name = ''; + var j = void 0; + var i = 0; + while (i < str.length) { + switch (str[i]) { + case '[': + push(); + + var delemiter = str[i + 1]; + if (/['"]/.test(delemiter)) { + // foo["bar"] + j = str.indexOf(delemiter, i + 2); + assert(j !== -1, 'unbalanced ' + delemiter + ': ' + str); + name = str.slice(i + 2, j); + push(); + i = j + 2; + } else { + // foo[bar.coo] + j = matchRightBracket(str, i + 1); + assert(j !== -1, 'unbalanced []: ' + str); + name = str.slice(i + 1, j); + if (!isInteger(name)) { + // foo[bar] vs. foo[1] + name = this.get(name); + } + push(); + i = j + 1; + } + break; + case '.': + // foo.bar, foo[0].bar + push(); + i++; + break; + default: + // foo.bar + name += str[i]; + i++; + } + } + push(); + + if (!seq.length) { + throw new TypeError('invalid path:"' + str + '"'); + } + return seq; + + function push() { + if (name.length) seq.push(name); + name = ''; + } + } + }; + + 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; + } + } + } + return -1; + } + + function factory(ctx, opts) { + var defaultOptions = { + dynamicPartials: true, + strict_variables: false, + strict_filters: false, + blocks: {}, + root: [] + }; + var scope = Object.create(Scope); + scope.opts = assign(defaultOptions, opts); + scope.contexts = [ctx || {}]; + return scope; + } + + function get$1(url) { return new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest(); xhr.onload = function () { if (xhr.status >= 200 && xhr.status < 300) { - var _tpl = _this4.parse(xhr.responseText); - if (_this4.options.cache) { - _this4.cache[filepath] = _tpl; - } - resolve(_tpl); + resolve(xhr.responseText); } else { reject(new Error(xhr.statusText)); } @@ -535,987 +1280,942 @@ var _engine = { xhr.onerror = function () { reject(new Error('An error occurred whilst sending the response.')); }; - xhr.open('GET', fullUrl); + xhr.open('GET', url); xhr.send(); }); - }, - express: function express(opts) { - opts = opts || {}; - var self = this; - return function (filePath, ctx, callback) { - (0, _assert2.default)(Array.isArray(this.root) || _underscore2.default.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 = _underscore2.default.assign({ - root: ['.'], - cache: false, - extname: '', - dynamicPartials: true, - trim_tag_right: false, - trim_tag_left: false, - trim_value_right: false, - trim_value_left: false, - greedy: true, - strict_filters: false, - strict_variables: false - }, options); - options.root = normalizeStringArray(options.root); + function whiteSpaceCtrl(tokens, options) { + options = assign({ greedy: true }, options); + var inRaw = false; - var engine = Object.create(_engine); - engine.init((0, _tag2.default)(), (0, _filter2.default)(options), options); - return engine; -} - -function normalizeStringArray(value) { - if (Array.isArray(value)) return value; - if (_underscore2.default.isString(value)) return [value]; - return []; -} - -var Types = { - ParseError: _error.ParseError, - TokenizationEroor: _error.TokenizationEroor, - RenderBreakError: _error.RenderBreakError, - AssertionError: _error.AssertionError -}; - -factory.isTruthy = _syntax.isTruthy; -factory.isFalsy = _syntax.isFalsy; -factory.evalExp = _syntax.evalExp; -factory.evalValue = _syntax.evalValue; -factory.Types = Types; -factory.lexical = _lexical2.default; - -module.exports = factory; - -},{"./filter.js":4,"./filters":5,"./lexical.js":7,"./parser":9,"./render.js":10,"./scope":11,"./syntax.js":12,"./tag.js":13,"./tags":24,"./tokenizer.js":29,"./util/assert.js":30,"./util/error.js":31,"./util/fs.js":32,"./util/promise.js":33,"./util/underscore.js":35,"./util/url.js":36,"path":2}],7:[function(require,module,exports){ -'use strict'; - -// quote related -var singleQuoted = /'[^']*'/; -var doubleQuoted = /"[^"]*"/; -var quoted = new RegExp(singleQuoted.source + '|' + doubleQuoted.source); -var quoteBalanced = new RegExp('(?:' + quoted.source + '|[^\'"])*'); - -// basic types -var integer = /-?\d+/; -var number = /-?\d+\.?\d*|\.?\d+/; -var bool = /true|false/; - -// peoperty access -var identifier = /[\w-]+[?]?/; -var subscript = new RegExp('\\[(?:' + quoted.source + '|[\\w-\\.]+)\\]'); -var literal = new RegExp('(?:' + quoted.source + '|' + bool.source + '|' + number.source + ')'); -var variable = new RegExp(identifier.source + '(?:\\.' + identifier.source + '|' + subscript.source + ')*'); - -// range related -var rangeLimit = new RegExp('(?:' + variable.source + '|' + number.source + ')'); -var range = new RegExp('\\(' + rangeLimit.source + '\\.\\.' + rangeLimit.source + '\\)'); -var rangeCapture = new RegExp('\\((' + rangeLimit.source + ')\\.\\.(' + rangeLimit.source + ')\\)'); - -var value = new RegExp('(?:' + variable.source + '|' + literal.source + '|' + range.source + ')'); - -// hash related -var hash = new RegExp('(?:' + identifier.source + ')\\s*:\\s*(?:' + value.source + ')'); -var hashCapture = new RegExp('(' + identifier.source + ')\\s*:\\s*(' + value.source + ')', 'g'); - -// full match -var tagLine = new RegExp('^\\s*(' + identifier.source + ')\\s*([\\s\\S]*)\\s*$'); -var literalLine = new RegExp('^' + literal.source + '$', 'i'); -var variableLine = new RegExp('^' + variable.source + '$'); -var numberLine = new RegExp('^' + number.source + '$'); -var boolLine = new RegExp('^' + bool.source + '$', 'i'); -var quotedLine = new RegExp('^' + quoted.source + '$'); -var rangeLine = new RegExp('^' + rangeCapture.source + '$'); -var integerLine = new RegExp('^' + integer.source + '$'); - -// filter related -var valueDeclaration = new RegExp('(?:' + identifier.source + '\\s*:\\s*)?' + value.source); -var valueList = new RegExp(valueDeclaration.source + '(\\s*,\\s*' + valueDeclaration.source + ')*'); -var filter = new RegExp(identifier.source + '(?:\\s*:\\s*' + valueList.source + ')?', 'g'); -var filterCapture = new RegExp('(' + identifier.source + ')(?:\\s*:\\s*(' + valueList.source + '))?'); -var filterLine = new RegExp('^' + filterCapture.source + '$'); - -var operators = [/\s+or\s+/, /\s+and\s+/, /==|!=|<=|>=|<|>|\s+contains\s+/]; - -function isInteger(str) { - return integerLine.test(str); -} - -function isLiteral(str) { - return literalLine.test(str); -} - -function isRange(str) { - return rangeLine.test(str); -} - -function isVariable(str) { - return variableLine.test(str); -} - -function matchValue(str) { - return value.exec(str); -} - -function parseLiteral(str) { - 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); - } - throw new TypeError('cannot parse \'' + str + '\' as literal'); -} - -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 -}; - -},{}],8:[function(require,module,exports){ -'use strict'; - -module.exports = function (isTruthy) { - return { - '==': 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 isTruthy(l) && isTruthy(r); - }, - 'or': function or(l, r) { - return isTruthy(l) || isTruthy(r); - } - }; -}; - -},{}],9:[function(require,module,exports){ -'use strict'; - -var lexical = require('./lexical.js'); -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; + tokens.forEach(function (token, i) { + if (shouldTrimLeft(token, inRaw, options)) { + trimLeft(tokens[i - 1], options.greedy); } - }, - start: function start() { - this.trigger('start'); - var token = void 0; - 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 (token.type === 'tag' && token.name === 'raw') inRaw = true; + if (token.type === 'tag' && token.name === 'endraw') inRaw = false; + + if (shouldTrimRight(token, inRaw, options)) { + trimRight(tokens[i + 1], options.greedy); } - if (!this.stopRequested) this.trigger('end'); - return this; - }, - stop: function stop() { - this.stopRequested = true; - return this; - } - }; - - function parse(tokens) { - var token = void 0; - var templates = []; - while (token = tokens.shift()) { - templates.push(parseToken(token, tokens)); - } - return templates; + }); } - function parseToken(token, tokens) { - try { - var tpl = null; - if (token.type === 'tag') { - tpl = parseTag(token, tokens); - } else if (token.type === 'value') { - tpl = parseValue(token.value); - } else { - // token.type === 'html' - tpl = token; + function shouldTrimLeft(token, inRaw, options) { + if (inRaw) return false; + if (token.type === 'tag') return token.trim_left || options.trim_tag_left; + if (token.type === 'value') return token.trim_left || options.trim_value_left; + } + + function shouldTrimRight(token, inRaw, options) { + if (inRaw) return false; + if (token.type === 'tag') return token.trim_right || options.trim_tag_right; + if (token.type === 'value') return token.trim_right || options.trim_value_right; + } + + function trimLeft(token, greedy) { + if (!token || token.type !== 'html') return; + + var rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g; + token.value = token.value.replace(rLeft, ''); + } + + function trimRight(token, greedy) { + if (!token || token.type !== 'html') return; + + var rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g; + token.value = token.value.replace(rRight, ''); + } + + function parse(input, file, options) { + assert(isString(input), 'illegal input'); + + var rLiquid = /({%-?([\s\S]*?)-?%})|({{-?([\s\S]*?)-?}})/g; + var currIndent = 0; + var lineNumber = LineNumber(input); + var lastMatchEnd = 0; + var tokens = []; + + for (var match; match = rLiquid.exec(input); lastMatchEnd = rLiquid.lastIndex) { + if (match.index > lastMatchEnd) { + tokens.push(parseHTMLToken(lastMatchEnd, match.index)); } - tpl.token = token; - return tpl; - } catch (e) { - throw new ParseError(e, token); + tokens.push(match[1] ? parseTagToken(match[1], match[2].trim(), match.index) : parseValueToken(match[3], match[4].trim(), match.index)); + } + if (input.length > lastMatchEnd) { + tokens.push(parseHTMLToken(lastMatchEnd, input.length)); + } + whiteSpaceCtrl(tokens, options); + return tokens; + + function parseTagToken(raw, value$$1, pos) { + var match = value$$1.match(tagLine); + var token = { + type: 'tag', + indent: currIndent, + line: lineNumber.get(pos), + trim_left: raw.slice(0, 3) === '{%-', + trim_right: raw.slice(-3) === '-%}', + raw: raw, + value: value$$1, + input: input, + file: file + }; + if (!match) { + throw new TokenizationError('illegal tag syntax', token); + } + token.name = match[1]; + token.args = match[2]; + return token; + } + + function parseValueToken(raw, value$$1, pos) { + return { + type: 'value', + line: lineNumber.get(pos), + trim_left: raw.slice(0, 3) === '{{-', + trim_right: raw.slice(-3) === '-}}', + raw: raw, + value: value$$1, + input: input, + file: file + }; + } + + function parseHTMLToken(begin, end) { + var htmlFragment = input.slice(begin, end); + currIndent = last(htmlFragment.split('\n')).length; + + return { + type: 'html', + raw: htmlFragment, + value: htmlFragment + }; } } - function parseTag(token, tokens) { - if (token.name === 'continue' || token.name === 'break') return token; - return Tag.construct(token, tokens); - } - - function parseValue(str) { - var match = lexical.matchValue(str); - assert(match, 'illegal value string: ' + str); - - var initial = match[0]; - str = str.substr(match.index + match[0].length); - - var filters = []; - while (match = lexical.filter.exec(str)) { - filters.push([match[0].trim()]); - } + function LineNumber(html) { + var parsedLinesCount = 0; + var lastMatchBegin = -1; return { - type: 'value', - initial: initial, - filters: filters.map(function (str) { - return Filter.construct(str); - }) + get: function get(pos) { + var lines = html.slice(lastMatchBegin + 1, pos).split('\n'); + parsedLinesCount += lines.length - 1; + lastMatchBegin = pos; + return parsedLinesCount + 1; + } }; } - function parseStream(tokens) { - var s = Object.create(stream); - return s.init(tokens); - } + var fs = {}; - return { - parse: parse, - parseTag: parseTag, - parseStream: parseStream, - parseValue: parseValue - }; -}; - -},{"./lexical.js":7,"./util/assert.js":30,"./util/error.js":31}],10:[function(require,module,exports){ -'use strict'; - -var Syntax = require('./syntax.js'); -var mapSeries = require('./util/promise.js').mapSeries; -var RenderBreakError = require('./util/error.js').RenderBreakError; -var _ = require('./util/underscore.js'); -var RenderError = require('./util/error.js').RenderError; -var assert = require('./util/assert.js'); - -var render = { - - renderTemplates: function renderTemplates(templates, scope) { - var _this = this; - - 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); + function readFileAsync(filepath) { + return new Promise(function (resolve, reject) { + fs.readFile(filepath, 'utf8', function (err, content) { + err ? reject(err) : resolve(content); }); - }).then(function () { - return html; }); - - function renderTemplate(template) { - if (template.type === 'tag') { - return this.renderTag(template, scope).then(function (partial) { - return partial === undefined ? '' : partial; - }); - } else if (template.type === 'value') { - return this.renderValue(template, scope); - } 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); - }, - - renderValue: function renderValue(template, scope) { - var _this2 = this; - - return Promise.resolve().then(function () { - return _this2.evalValue(template, scope); - }).then(function (partial) { - return partial === undefined ? '' : _.stringify(partial); - }); - }, - - evalValue: function evalValue(template, scope) { - assert(scope, 'unable to evalValue: 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; -} - -module.exports = factory; - -},{"./syntax.js":12,"./util/assert.js":30,"./util/error.js":31,"./util/promise.js":33,"./util/underscore.js":35}],11:[function(require,module,exports){ -'use strict'; - -var _ = require('./util/underscore.js'); -var lexical = require('./lexical.js'); -var assert = require('./util/assert.js'); - -var Scope = { - getAll: function getAll() { - return this.contexts.reduce(function (ctx, val) { - return Object.assign(ctx, val); - }, Object.create(null)); - }, - get: function get(path) { - var _this = this; - - var paths = this.propertyAccessSeq(path); - var scope = this.findContextFor(paths[0]) || _.last(this.contexts); - return paths.reduce(function (value, key) { - return _this.readProperty(value, key); - }, scope); - }, - set: function set(path, v) { - var paths = this.propertyAccessSeq(path); - var scope = this.findContextFor(paths[0]) || _.last(this.contexts); - paths.some(function (key, i) { - if (!_.isObject(scope)) { - return true; - } - if (i === paths.length - 1) { - scope[key] = v; - return true; - } - if (undefined === scope[key]) { - scope[key] = {}; - } - scope = scope[key]; + function statFileAsync(path) { + return new Promise(function (resolve, reject) { + fs.stat(path, function (err, stat) { + return err ? reject(err) : resolve(stat); + }); }); - }, - unshift: function unshift(ctx) { - return this.contexts.unshift(ctx); - }, - push: function push(ctx) { - return this.contexts.push(ctx); - }, - pop: function pop(ctx) { - if (!arguments.length) { - return this.contexts.pop(); + } + + var path = {}; + + var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/; + var urlRe = /^(?:\w+:)?\/\/([^\s.]+\.\S{2}|localhost[:?\d]*)\S*$/; + + // https://github.com/jinder/path/blob/master/path.js#L567 + function extname(path) { + return splitPathRe.exec(path).slice(1)[3]; + } + + // https://www.npmjs.com/package/is-url + function valid(path) { + return urlRe.test(path); + } + + function resolve(root, path) { + if (isArray(root)) { + root = root[0]; } - var i = this.contexts.findIndex(function (scope) { - return scope === ctx; - }); - if (i === -1) { - throw new TypeError('scope not found, cannot pop'); + if (root && last(root) !== '/') { + root += '/'; } - return this.contexts.splice(i, 1)[0]; - }, - findContextFor: function findContextFor(key, filter) { - filter = filter || function () { - return true; + return resolveUrl(root, path); + } + + function resolveUrl(root, path) { + var base = document.createElement('base'); + base.href = arguments[0]; + + var head = document.getElementsByTagName('head')[0]; + head.insertBefore(base, head.firstChild); + + var a = document.createElement('a'); + a.href = path; + var resolved = a.href; + base.href = resolved; + + head.removeChild(base); + + return resolved; + } + + function Operators (isTruthy) { + return { + '==': 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 isTruthy(l) && isTruthy(r); + }, + 'or': function or(l, r) { + return isTruthy(l) || isTruthy(r); + } }; - for (var i = this.contexts.length - 1; i >= 0; i--) { - var candidate = this.contexts[i]; - if (!filter(candidate)) continue; - if (key in candidate) { - return candidate; + } + + var operators$1 = Operators(isTruthy); + + function evalExp(exp, scope) { + assert(scope, 'unable to evalExp: scope undefined'); + var operatorREs = operators; + var match = void 0; + for (var i = 0; i < operatorREs.length; i++) { + var operatorRE = operatorREs[i]; + var expRE = new RegExp('^(' + quoteBalanced.source + ')(' + operatorRE.source + ')(' + quoteBalanced.source + ')$'); + if (match = exp.match(expRE)) { + var l = evalExp(match[1], scope); + var op = operators$1[match[2].trim()]; + var r = evalExp(match[3], scope); + return op(l, r); } } - return null; - }, - readProperty: function readProperty(obj, key) { - var val = void 0; - if (_.isNil(obj)) { - val = undefined; - } else { - if (typeof obj.to_liquid === 'function') { - obj = obj.to_liquid(); - } else if (typeof obj.toLiquid === 'function') { - obj = obj.toLiquid(); - } - - if (key === 'size' && (_.isArray(obj) || _.isString(obj))) { - val = obj.length; - } else { - val = obj[key]; + + if (match = exp.match(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; } - if (_.isNil(val) && this.opts.strict_variables) { - throw new TypeError('undefined variable: ' + key); + + return evalValue(exp, scope); + } + + function evalValue(str, scope) { + str = str && str.trim(); + if (!str) return undefined; + + if (isLiteral(str)) { + return parseLiteral(str); } - return val; - }, + if (isVariable(str)) { + return scope.get(str); + } + throw new TypeError('cannot eval \'' + str + '\' as value'); + } - /* - * 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) { - str = String(str); - var seq = []; - var name = ''; - var j = void 0; - var i = 0; - while (i < str.length) { - switch (str[i]) { - case '[': - push(); + function isTruthy(val) { + return !isFalsy(val); + } - var delemiter = str[i + 1]; - if (/['"]/.test(delemiter)) { - // foo["bar"] - j = str.indexOf(delemiter, i + 2); - assert(j !== -1, 'unbalanced ' + delemiter + ': ' + str); - name = str.slice(i + 2, j); - push(); - i = j + 2; - } else { - // foo[bar.coo] - j = matchRightBracket(str, i + 1); - assert(j !== -1, 'unbalanced []: ' + str); - name = str.slice(i + 1, j); - if (!lexical.isInteger(name)) { - // foo[bar] vs. foo[1] - name = this.get(name); + function isFalsy(val) { + return val === false || undefined === val || val === null; + } + + var render = { + renderTemplates: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(templates, scope) { + var renderTemplate = function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(template) { + var partial; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!(template.type === 'tag')) { + _context.next = 5; + break; + } + + _context.next = 3; + return this.renderTag(template, scope); + + case 3: + partial = _context.sent; + return _context.abrupt('return', partial === undefined ? '' : partial); + + case 5: + if (!(template.type === 'value')) { + _context.next = 7; + break; + } + + return _context.abrupt('return', this.renderValue(template, scope)); + + case 7: + return _context.abrupt('return', template.value); + + case 8: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + return function renderTemplate(_x3) { + return _ref2.apply(this, arguments); + }; + }(); + + var html, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, tpl; + + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + assert(scope, 'unable to evalTemplates: scope undefined'); + + html = ''; + _iteratorNormalCompletion = true; + _didIteratorError = false; + _iteratorError = undefined; + _context2.prev = 5; + _iterator = templates[Symbol.iterator](); + + case 7: + if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { + _context2.next = 24; + break; + } + + tpl = _step.value; + _context2.prev = 9; + _context2.next = 12; + return renderTemplate.call(this, tpl); + + case 12: + html += _context2.sent; + _context2.next = 21; + break; + + case 15: + _context2.prev = 15; + _context2.t0 = _context2['catch'](9); + + if (!(_context2.t0 instanceof RenderBreakError)) { + _context2.next = 20; + break; + } + + _context2.t0.resolvedHTML = html; + throw _context2.t0; + + case 20: + throw new RenderError(_context2.t0, tpl); + + case 21: + _iteratorNormalCompletion = true; + _context2.next = 7; + break; + + case 24: + _context2.next = 30; + break; + + case 26: + _context2.prev = 26; + _context2.t1 = _context2['catch'](5); + _didIteratorError = true; + _iteratorError = _context2.t1; + + case 30: + _context2.prev = 30; + _context2.prev = 31; + + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + + case 33: + _context2.prev = 33; + + if (!_didIteratorError) { + _context2.next = 36; + break; + } + + throw _iteratorError; + + case 36: + return _context2.finish(33); + + case 37: + return _context2.finish(30); + + case 38: + return _context2.abrupt('return', html); + + case 39: + case 'end': + return _context2.stop(); } - push(); - i = j + 1; } - break; - case '.': - // foo.bar, foo[0].bar - push(); - i++; - break; - default: - // foo.bar - name += str[i]; - i++; + }, _callee2, this, [[5, 26, 30, 38], [9, 15], [31,, 33, 37]]); + })); + + function renderTemplates(_x, _x2) { + return _ref.apply(this, arguments); } - } - push(); - if (!seq.length) { - throw new TypeError('invalid path:"' + str + '"'); - } - return seq; + return renderTemplates; + }(), - function push() { - if (name.length) seq.push(name); - name = ''; - } - } -}; + renderTag: function () { + var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(template, scope) { + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + if (!(template.name === 'continue')) { + _context3.next = 2; + break; + } -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; + throw new RenderBreakError('continue'); + + case 2: + if (!(template.name === 'break')) { + _context3.next = 4; + break; + } + + throw new RenderBreakError('break'); + + case 4: + return _context3.abrupt('return', template.render(scope)); + + case 5: + case 'end': + return _context3.stop(); + } + } + }, _callee3, this); + })); + + function renderTag(_x4, _x5) { + return _ref3.apply(this, arguments); } - } - } - return -1; -} -exports.factory = function (ctx, opts) { - var defaultOptions = { - dynamicPartials: true, - strict_variables: false, - strict_filters: false, - blocks: {}, - root: [] - }; - var scope = Object.create(Scope); - scope.opts = _.assign(defaultOptions, opts); - scope.contexts = [ctx || {}]; - return scope; -}; + return renderTag; + }(), -exports.types = { - AssignScope: Object.create(null), - CaptureScope: Object.create(null), - IncrementScope: Object.create(null), - DecrementScope: Object.create(null) -}; + renderValue: function () { + var _ref4 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(template, scope) { + var partial; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + partial = this.evalValue(template, scope); + return _context4.abrupt('return', partial === undefined ? '' : stringify(partial)); -},{"./lexical.js":7,"./util/assert.js":30,"./util/underscore.js":35}],12:[function(require,module,exports){ -'use strict'; + case 2: + case 'end': + return _context4.stop(); + } + } + }, _callee4, this); + })); -var operators = require('./operators.js')(isTruthy); -var lexical = require('./lexical.js'); -var assert = require('./util/assert.js'); - -function evalExp(exp, scope) { - assert(scope, 'unable to evalExp: scope undefined'); - var operatorREs = lexical.operators; - var match = void 0; - 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); - var high = evalValue(match[2], scope); - var range = []; - for (var j = low; j <= high; j++) { - range.push(j); - } - return range; - } - - return evalValue(exp, scope); -} - -function evalValue(str, scope) { - str = str && str.trim(); - if (!str) return undefined; - - if (lexical.isLiteral(str)) { - return lexical.parseLiteral(str); - } - if (lexical.isVariable(str)) { - return scope.get(str); - } - throw new TypeError('cannot eval \'' + str + '\' as value'); -} - -function isTruthy(val) { - return !isFalsy(val); -} - -function isFalsy(val) { - return val === false || undefined === val || val === null; -} - -module.exports = { - evalExp: evalExp, evalValue: evalValue, isTruthy: isTruthy, isFalsy: isFalsy -}; - -},{"./lexical.js":7,"./operators.js":8,"./util/assert.js":30}],13:[function(require,module,exports){ -'use strict'; - -var lexical = require('./lexical.js'); -var Syntax = require('./syntax.js'); -var assert = require('./util/assert.js'); - -function hash(markup, scope) { - var obj = {}; - var match = void 0; - 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 _tagInstance = { - render: function render(scope) { - var obj = hash(this.token.args, scope); - var impl = this.tagImpl; - if (typeof impl.render !== 'function') { - return Promise.resolve(''); + function renderValue(_x6, _x7) { + return _ref4.apply(this, arguments); } - return Promise.resolve().then(function () { - return impl.render(scope, obj); - }); - }, - 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); - } + return renderValue; + }(), + + evalValue: function evalValue$$1(template, scope) { + assert(scope, 'unable to evalValue: scope undefined'); + return template.filters.reduce(function (prev, filter) { + return filter.render(prev, scope); + }, evalExp(template.initial, scope)); } }; - function register(name, tag) { - tagImpls[name] = tag; - } - - function construct(token, tokens) { - var instance = Object.create(_tagInstance); - instance.parse(token, tokens); + function Render () { + var instance = Object.create(render); return instance; } - function clear() { - tagImpls = {}; + function hash$1(markup, scope) { + var obj = {}; + var match = void 0; + hashCapture.lastIndex = 0; + while (match = hashCapture.exec(markup)) { + var k = match[1]; + var v = match[2]; + obj[k] = evalValue(v, scope); + } + return obj; } - return { - construct: construct, - register: register, - clear: clear - }; -}; + function Tag () { + var tagImpls = {}; -},{"./lexical.js":7,"./syntax.js":12,"./util/assert.js":30}],14:[function(require,module,exports){ -'use strict'; + var _tagInstance = { + render: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(scope) { + var obj, impl; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + obj = hash$1(this.token.args, scope); + impl = this.tagImpl; -var _index = require('../index'); + if (!(typeof impl.render !== 'function')) { + _context.next = 4; + break; + } -var _assert = require('../util/assert.js'); + return _context.abrupt('return', ''); -var _assert2 = _interopRequireDefault(_assert); + case 4: + return _context.abrupt('return', impl.render(scope, obj)); -var _scope = require('../scope'); + case 5: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + function render(_x) { + return _ref.apply(this, arguments); + } -var re = new RegExp('(' + _index.lexical.identifier.source + ')\\s*=(.*)'); + return render; + }(), + parse: function parse(token, tokens) { + this.type = 'tag'; + this.token = token; + this.name = token.name; -module.exports = function (liquid) { - liquid.registerTag('assign', { - parse: function parse(token) { - var match = token.args.match(re); - (0, _assert2.default)(match, 'illegal token ' + token.raw); - this.key = match[1]; - this.value = match[2]; - }, - render: function render(scope) { - var ctx = Object.create(_scope.types.AssignScope); - ctx[this.key] = liquid.evalValue(this.value, scope); - scope.push(ctx); - return Promise.resolve(''); - } - }); -}; - -},{"../index":6,"../scope":11,"../util/assert.js":30}],15:[function(require,module,exports){ -'use strict'; - -var Liquid = require('..'); -var lexical = Liquid.lexical; -var re = new RegExp('(' + lexical.identifier.source + ')'); -var assert = require('../util/assert.js'); -var types = require('../scope.js').types; - -module.exports = function (liquid) { - liquid.registerTag('capture', { - parse: function parse(tagToken, remainTokens) { - var _this = this; - - var match = tagToken.args.match(re); - assert(match, tagToken.args + ' not valid identifier'); - - this.variable = match[1]; - this.templates = []; - - var stream = liquid.parser.parseStream(remainTokens); - stream.on('tag:endcapture', function (token) { - return stream.stop(); - }).on('template', function (tpl) { - return _this.templates.push(tpl); - }).on('end', function (x) { - throw new Error('tag ' + tagToken.raw + ' not closed'); - }); - stream.start(); - }, - render: function render(scope, hash) { - var _this2 = this; - - return liquid.renderer.renderTemplates(this.templates, scope).then(function (html) { - var ctx = Object.create(types.CaptureScope); - ctx[_this2.variable] = html; - scope.push(ctx); - }); - } - }); -}; - -},{"..":6,"../scope.js":11,"../util/assert.js":30}],16:[function(require,module,exports){ -'use strict'; - -var _ = require('..'); - -var _2 = _interopRequireDefault(_); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -module.exports = function (liquid) { - liquid.registerTag('case', { - - parse: function parse(tagToken, remainTokens) { - var _this = this; - - this.cond = tagToken.args; - this.cases = []; - this.elseTemplates = []; - - var p = []; - var stream = liquid.parser.parseStream(remainTokens).on('tag:when', function (token) { - _this.cases.push({ - val: token.args, - templates: p = [] - }); - }).on('tag:else', function () { - return p = _this.elseTemplates; - }).on('tag:endcase', function (token) { - return stream.stop(); - }).on('template', function (tpl) { - return p.push(tpl); - }).on('end', function (x) { - throw new Error('tag ' + tagToken.raw + ' not closed'); - }); - - stream.start(); - }, - - render: function render(scope, hash) { - for (var i = 0; i < this.cases.length; i++) { - var branch = this.cases[i]; - var val = _2.default.evalExp(branch.val, scope); - var cond = _2.default.evalExp(this.cond, scope); - if (val === cond) { - return liquid.renderer.renderTemplates(branch.templates, scope); + 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); } } - return liquid.renderer.renderTemplates(this.elseTemplates, scope); + }; + + function register(name, tag) { + tagImpls[name] = tag; } - }); -}; -},{"..":6}],17:[function(require,module,exports){ -'use strict'; + function construct(token, tokens) { + var instance = Object.create(_tagInstance); + instance.parse(token, tokens); + return instance; + } -module.exports = function (liquid) { - liquid.registerTag('comment', { - parse: function parse(tagToken, remainTokens) { - var stream = liquid.parser.parseStream(remainTokens); - stream.on('token', function (token) { - if (token.name === 'endcomment') stream.stop(); - }).on('end', function (x) { - throw new Error('tag ' + tagToken.raw + ' not closed'); + function clear() { + tagImpls = {}; + } + + return { + construct: construct, + register: register, + clear: clear + }; + } + + var valueRE = new RegExp('' + value.source, 'g'); + + function Filter (options) { + options = assign({}, options); + var filters = {}; + + var _filterInstance = { + render: function render(output, scope) { + var args = this.args.map(function (arg) { + return evalValue(arg, scope); + }); + args.unshift(output); + return this.filter.apply(null, args); + }, + parse: function parse(str) { + var match = filterLine.exec(str); + assert(match, 'illegal filter: ' + str); + + var name = match[1]; + var argList = match[2] || ''; + var filter$$1 = filters[name]; + if (typeof filter$$1 !== 'function') { + if (options.strict_filters) { + throw new TypeError('undefined filter: ' + name); + } + this.name = name; + this.filter = function (x) { + return x; + }; + this.args = []; + return this; + } + + var args = []; + while (match = valueRE.exec(argList.trim())) { + var v = match[0]; + var re = new RegExp(v + '\\s*:', 'g'); + var keyMatch = re.exec(match.input); + var currentMatchIsKey = keyMatch && keyMatch.index === match.index; + currentMatchIsKey ? args.push('\'' + v + '\'') : args.push(v); + } + + this.name = name; + this.filter = filter$$1; + this.args = args; + + return this; + } + }; + + function construct(str) { + var instance = Object.create(_filterInstance); + return instance.parse(str); + } + + function register(name, filter$$1) { + filters[name] = filter$$1; + } + + function clear() { + filters = {}; + } + + return { + construct: construct, register: register, clear: clear + }; + } + + function Parser (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 = void 0; + 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; + } + }; + + function parse(tokens) { + var token = void 0; + var templates = []; + while (token = tokens.shift()) { + templates.push(parseToken(token, tokens)); + } + return templates; + } + + function parseToken(token, tokens) { + try { + var tpl = null; + if (token.type === 'tag') { + tpl = parseTag(token, tokens); + } else if (token.type === 'value') { + tpl = parseValue(token.value); + } else { + // token.type === 'html' + tpl = token; + } + tpl.token = token; + return tpl; + } catch (e) { + throw new ParseError(e, token); + } + } + + function parseTag(token, tokens) { + if (token.name === 'continue' || token.name === 'break') return token; + return Tag.construct(token, tokens); + } + + function parseValue(str) { + var match = matchValue(str); + assert(match, 'illegal value string: ' + str); + + var initial = match[0]; + str = str.substr(match.index + match[0].length); + + var filters = []; + while (match = filter.exec(str)) { + filters.push([match[0].trim()]); + } + + return { + type: 'value', + 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, + parseValue: parseValue + }; + } + + /* + * 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). + */ + 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); }); - stream.start(); - } - }); -}; + }); + return ret; + } -},{}],18:[function(require,module,exports){ -'use strict'; - -var Liquid = require('..'); -var lexical = Liquid.lexical; -var groupRE = new RegExp('^(?:(' + lexical.value.source + ')\\s*:\\s*)?(.*)$'); -var candidatesRE = new RegExp(lexical.value.source, 'g'); -var assert = require('../util/assert.js'); - -module.exports = function (liquid) { - liquid.registerTag('cycle', { - - parse: function parse(tagToken, remainTokens) { - var match = groupRE.exec(tagToken.args); - assert(match, 'illegal tag: ' + tagToken.raw); - - this.group = match[1] || ''; - var candidates = match[2]; - - this.candidates = []; - - while (match = candidatesRE.exec(candidates)) { - this.candidates.push(match[0]); - } - assert(this.candidates.length, 'empty candidates: ' + tagToken.raw); - }, - - render: function render(scope, hash) { - var group = Liquid.evalValue(this.group, scope); - var fingerprint = 'cycle:' + group + ':' + this.candidates.join(','); - - var groups = scope.opts.groups = scope.opts.groups || {}; - var idx = groups[fingerprint]; - - if (idx === undefined) { - idx = groups[fingerprint] = 0; - } - - var candidate = this.candidates[idx]; - idx = (idx + 1) % this.candidates.length; - groups[fingerprint] = idx; - - return Promise.resolve(Liquid.evalValue(candidate, scope)); - } - }); -}; - -},{"..":6,"../util/assert.js":30}],19:[function(require,module,exports){ -'use strict'; - -var Liquid = require('..'); -var lexical = Liquid.lexical; -var assert = require('../util/assert.js'); -var types = require('../scope').types; - -module.exports = function (liquid) { - liquid.registerTag('decrement', { - parse: function parse(token) { - var match = token.args.match(lexical.identifier); - assert(match, 'illegal identifier ' + token.args); - this.variable = match[0]; - }, - render: function render(scope, hash) { - var context = scope.findContextFor(this.variable, function (ctx) { - return Object.getPrototypeOf(ctx) !== types.CaptureScope && Object.getPrototypeOf(ctx) !== types.AssignScope; + /* + * 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). + */ + 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); }); - if (!context) { - context = Object.create(types.DecrementScope); - scope.unshift(context); - } - if (typeof context[this.variable] !== 'number') { - context[this.variable] = 0; - } - return --context[this.variable]; - } - }); -}; + }); + return ret.then(function () { + return result; + }); + } -},{"..":6,"../scope":11,"../util/assert.js":30}],20:[function(require,module,exports){ -'use strict'; + function For (liquid, Liquid) { + var render = function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(scope, hash) { + var _this2 = this; -var _index = require('../index'); + var collection, offset, limit, contexts, html, finished; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + collection = Liquid.evalExp(this.collection, scope); -var _index2 = _interopRequireDefault(_index); -var _promise = require('../util/promise.js'); + if (!Array.isArray(collection)) { + if (isString(collection) && collection.length > 0) { + collection = [collection]; + } else if (isObject(collection)) { + collection = Object.keys(collection).map(function (key) { + return [key, collection[key]]; + }); + } + } -var _underscore = require('../util/underscore.js'); + if (!(!Array.isArray(collection) || !collection.length)) { + _context2.next = 4; + break; + } -var _underscore2 = _interopRequireDefault(_underscore); + return _context2.abrupt('return', liquid.renderer.renderTemplates(this.elseTemplates, scope)); -var _assert = require('../util/assert.js'); + case 4: + offset = hash.offset || 0; + limit = hash.limit === undefined ? collection.length : hash.limit; -var _assert2 = _interopRequireDefault(_assert); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + collection = collection.slice(offset, offset + limit); + if (this.reversed) collection.reverse(); -var RenderBreakError = _index2.default.Types.RenderBreakError; -var re = new RegExp('^(' + _index.lexical.identifier.source + ')\\s+in\\s+' + ('(' + _index.lexical.value.source + ')') + ('(?:\\s+' + _index.lexical.hash.source + ')*') + '(?:\\s+(reversed))?' + ('(?:\\s+' + _index.lexical.hash.source + ')*$')); + contexts = collection.map(function (item, i) { + var ctx = {}; + ctx[_this2.variable] = item; + ctx.forloop = { + first: i === 0, + index: i + 1, + index0: i, + last: i === collection.length - 1, + length: collection.length, + rindex: collection.length - i, + rindex0: collection.length - i - 1 + }; + return ctx; + }); + html = ''; + finished = false; + _context2.next = 13; + return mapSeries(contexts, function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(context) { + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + if (!finished) { + _context.next = 2; + break; + } -module.exports = function (liquid) { - liquid.registerTag('for', { + return _context.abrupt('return'); - parse: function parse(tagToken, remainTokens) { + case 2: + + scope.push(context); + _context.prev = 3; + _context.next = 6; + return liquid.renderer.renderTemplates(_this2.templates, scope); + + case 6: + html += _context.sent; + _context.next = 17; + break; + + case 9: + _context.prev = 9; + _context.t0 = _context['catch'](3); + + if (!(_context.t0 instanceof RenderBreakError)) { + _context.next = 16; + break; + } + + html += _context.t0.resolvedHTML; + if (_context.t0.message === 'break') { + finished = true; + } + _context.next = 17; + break; + + case 16: + throw _context.t0; + + case 17: + scope.pop(context); + + case 18: + case 'end': + return _context.stop(); + } + } + }, _callee, _this2, [[3, 9]]); + })); + + return function (_x3) { + return _ref2.apply(this, arguments); + }; + }()); + + case 13: + return _context2.abrupt('return', html); + + case 14: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); + + return function render(_x, _x2) { + return _ref.apply(this, arguments); + }; + }(); + + var RenderBreakError = Liquid.Types.RenderBreakError; + var lexical = Liquid.lexical; + var re = new RegExp('^(' + lexical.identifier.source + ')\\s+in\\s+' + ('(' + lexical.value.source + ')') + ('(?:\\s+' + lexical.hash.source + ')*') + '(?:\\s+(reversed))?' + ('(?:\\s+' + lexical.hash.source + ')*$')); + + liquid.registerTag('for', { parse: parse, render: render }); + + function parse(tagToken, remainTokens) { var _this = this; var match = re.exec(tagToken.args); - (0, _assert2.default)(match, 'illegal tag: ' + tagToken.raw); + assert(match, 'illegal tag: ' + tagToken.raw); this.variable = match[1]; this.collection = match[2]; this.reversed = !!match[3]; @@ -1537,1233 +2237,1507 @@ module.exports = function (liquid) { }); stream.start(); - }, + } + } - render: function render(scope, hash) { - var _this2 = this; + function Assign (liquid, Liquid) { + var rIdentifier = Liquid.lexical.identifier; + var re = new RegExp('(' + rIdentifier.source + ')\\s*=(.*)'); + var AssignScope = Liquid.Types.AssignScope; - var collection = _index2.default.evalExp(this.collection, scope); - if (!Array.isArray(collection)) { - if (_underscore2.default.isString(collection) && collection.length > 0) { - collection = [collection]; - } else if (_underscore2.default.isObject(collection)) { - collection = Object.keys(collection).map(function (key) { - return [key, collection[key]]; - }); - } + liquid.registerTag('assign', { + parse: function parse(token) { + var match = token.args.match(re); + assert(match, 'illegal token ' + token.raw); + this.key = match[1]; + this.value = match[2]; + }, + render: function render(scope) { + var ctx = Object.create(AssignScope); + ctx[this.key] = liquid.evalValue(this.value, scope); + scope.push(ctx); + return Promise.resolve(''); } - if (!Array.isArray(collection) || !collection.length) { + }); + } + + function Capture (liquid, Liquid) { + var rIdentifier = Liquid.lexical.identifier; + var re = new RegExp('(' + rIdentifier.source + ')'); + var CaptureScope = Liquid.Types.CaptureScope; + + + liquid.registerTag('capture', { + parse: function parse(tagToken, remainTokens) { + var _this = this; + + var match = tagToken.args.match(re); + assert(match, tagToken.args + ' not valid identifier'); + + this.variable = match[1]; + this.templates = []; + + var stream = liquid.parser.parseStream(remainTokens); + stream.on('tag:endcapture', function (token) { + return stream.stop(); + }).on('template', function (tpl) { + return _this.templates.push(tpl); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + stream.start(); + }, + render: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(scope, hash) { + var html, ctx; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return liquid.renderer.renderTemplates(this.templates, scope); + + case 2: + html = _context.sent; + ctx = Object.create(CaptureScope); + + ctx[this.variable] = html; + scope.push(ctx); + + case 6: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + function render(_x, _x2) { + return _ref.apply(this, arguments); + } + + return render; + }() + }); + } + + function Case (liquid, Liquid) { + liquid.registerTag('case', { + + parse: function parse(tagToken, remainTokens) { + var _this = this; + + this.cond = tagToken.args; + this.cases = []; + this.elseTemplates = []; + + var p = []; + var stream = liquid.parser.parseStream(remainTokens).on('tag:when', function (token) { + _this.cases.push({ + val: token.args, + templates: p = [] + }); + }).on('tag:else', function () { + return p = _this.elseTemplates; + }).on('tag:endcase', function (token) { + return stream.stop(); + }).on('template', function (tpl) { + return p.push(tpl); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + + stream.start(); + }, + + render: function render(scope, hash) { + for (var i = 0; i < this.cases.length; i++) { + var branch = this.cases[i]; + var val = Liquid.evalExp(branch.val, scope); + var cond = Liquid.evalExp(this.cond, scope); + if (val === cond) { + return liquid.renderer.renderTemplates(branch.templates, scope); + } + } return liquid.renderer.renderTemplates(this.elseTemplates, scope); } + }); + } - var offset = hash.offset || 0; - var limit = hash.limit === undefined ? collection.length : hash.limit; + function Comment (liquid) { + liquid.registerTag('comment', { + parse: function parse(tagToken, remainTokens) { + var stream = liquid.parser.parseStream(remainTokens); + stream.on('token', function (token) { + if (token.name === 'endcomment') stream.stop(); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + stream.start(); + } + }); + } - collection = collection.slice(offset, offset + limit); - if (this.reversed) collection.reverse(); + var staticFileRE = /[^\s,]+/; - 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 === collection.length - 1, - length: collection.length, - rindex: collection.length - i, - rindex0: collection.length - i - 1 - }; - return ctx; - }); + function Include (liquid, Liquid) { + var lexical = Liquid.lexical; + var withRE = new RegExp('with\\s+(' + lexical.value.source + ')'); - var html = ''; - return (0, _promise.mapSeries)(contexts, function (context) { - return Promise.resolve().then(function () { - return scope.push(context); - }).then(function () { - 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; + liquid.registerTag('include', { + parse: function parse(token) { + var match = staticFileRE.exec(token.args); + if (match) { + this.staticValue = match[0]; + } + + match = lexical.value.exec(token.args); + if (match) { + this.value = match[0]; + } + + match = withRE.exec(token.args); + if (match) { + this.with = match[1]; + } + }, + render: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(scope, hash) { + var filepath, template, originBlocks, originBlockMode, templates, html; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + filepath = void 0; + + if (!scope.opts.dynamicPartials) { + _context.next = 12; + break; + } + + if (!lexical.quotedLine.exec(this.value)) { + _context.next = 9; + break; + } + + template = this.value.slice(1, -1); + _context.next = 6; + return liquid.parseAndRender(template, scope.getAll(), scope.opts); + + case 6: + filepath = _context.sent; + _context.next = 10; + break; + + case 9: + filepath = Liquid.evalValue(this.value, scope); + + case 10: + _context.next = 13; + break; + + case 12: + filepath = this.staticValue; + + case 13: + assert(filepath, 'cannot include with empty filename'); + + originBlocks = scope.opts.blocks; + originBlockMode = scope.opts.blockMode; + + + scope.opts.blocks = {}; + scope.opts.blockMode = 'output'; + if (this.with) { + hash[filepath] = Liquid.evalValue(this.with, scope); + } + _context.next = 21; + return liquid.getTemplate(filepath, scope.opts.root); + + case 21: + templates = _context.sent; + + scope.push(hash); + _context.next = 25; + return liquid.renderer.renderTemplates(templates, scope); + + case 25: + html = _context.sent; + + scope.pop(hash); + scope.opts.blocks = originBlocks; + scope.opts.blockMode = originBlockMode; + return _context.abrupt('return', html); + + case 30: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + function render(_x, _x2) { + return _ref.apply(this, arguments); + } + + return render; + }() + }); + } + + function Decrement (liquid, Liquid) { + var lexical = Liquid.lexical; + var _Liquid$Types = Liquid.Types, + CaptureScope = _Liquid$Types.CaptureScope, + AssignScope = _Liquid$Types.AssignScope, + DecrementScope = _Liquid$Types.DecrementScope; + + + liquid.registerTag('decrement', { + parse: function parse(token) { + var match = token.args.match(lexical.identifier); + assert(match, 'illegal identifier ' + token.args); + this.variable = match[0]; + }, + render: function render(scope, hash) { + var context = scope.findContextFor(this.variable, function (ctx) { + return Object.getPrototypeOf(ctx) !== CaptureScope && Object.getPrototypeOf(ctx) !== AssignScope; + }); + if (!context) { + context = Object.create(DecrementScope); + scope.unshift(context); + } + if (typeof context[this.variable] !== 'number') { + context[this.variable] = 0; + } + return --context[this.variable]; + } + }); + } + + function Cycle (liquid, Liquid) { + var rValue = Liquid.lexical.value; + var groupRE = new RegExp('^(?:(' + rValue.source + ')\\s*:\\s*)?(.*)$'); + var candidatesRE = new RegExp(rValue.source, 'g'); + + liquid.registerTag('cycle', { + + parse: function parse(tagToken, remainTokens) { + var match = groupRE.exec(tagToken.args); + assert(match, 'illegal tag: ' + tagToken.raw); + + this.group = match[1] || ''; + var candidates = match[2]; + + this.candidates = []; + + while (match = candidatesRE.exec(candidates)) { + this.candidates.push(match[0]); + } + assert(this.candidates.length, 'empty candidates: ' + tagToken.raw); + }, + + render: function render(scope, hash) { + var group = Liquid.evalValue(this.group, scope); + var fingerprint = 'cycle:' + group + ':' + this.candidates.join(','); + + var groups = scope.opts.groups = scope.opts.groups || {}; + var idx = groups[fingerprint]; + + if (idx === undefined) { + idx = groups[fingerprint] = 0; + } + + var candidate = this.candidates[idx]; + idx = (idx + 1) % this.candidates.length; + groups[fingerprint] = idx; + + return Liquid.evalValue(candidate, scope); + } + }); + } + + function If (liquid, Liquid) { + liquid.registerTag('if', { + + parse: function parse(tagToken, remainTokens) { + var _this = this; + + this.branches = []; + this.elseTemplates = []; + + var p = void 0; + var stream = liquid.parser.parseStream(remainTokens).on('start', function () { + return _this.branches.push({ + cond: tagToken.args, + templates: p = [] + }); + }).on('tag:elsif', function (token) { + _this.branches.push({ + cond: token.args, + templates: p = [] + }); + }).on('tag:else', function () { + return p = _this.elseTemplates; + }).on('tag:endif', function (token) { + return stream.stop(); + }).on('template', function (tpl) { + return p.push(tpl); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + + stream.start(); + }, + + render: function render(scope, hash) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.branches[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var branch = _step.value; + + var cond = Liquid.evalExp(branch.cond, scope); + if (Liquid.isTruthy(cond)) { + return liquid.renderer.renderTemplates(branch.templates, scope); + } } - throw e; - }).then(function () { - return scope.pop(context); - }); - }).catch(function (e) { - if (e instanceof RenderBreakError && e.message === 'break') { - return; - } - throw e; - }).then(function () { - return html; - }); - } - }); -}; - -},{"../index":6,"../util/assert.js":30,"../util/promise.js":33,"../util/underscore.js":35}],21:[function(require,module,exports){ -'use strict'; - -var _ = require('..'); - -var _2 = _interopRequireDefault(_); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -module.exports = function (liquid) { - liquid.registerTag('if', { - - parse: function parse(tagToken, remainTokens) { - var _this = this; - - this.branches = []; - this.elseTemplates = []; - - var p = void 0; - var stream = liquid.parser.parseStream(remainTokens).on('start', function () { - return _this.branches.push({ - cond: tagToken.args, - templates: p = [] - }); - }).on('tag:elsif', function (token) { - _this.branches.push({ - cond: token.args, - templates: p = [] - }); - }).on('tag:else', function () { - return p = _this.elseTemplates; - }).on('tag:endif', function (token) { - return stream.stop(); - }).on('template', function (tpl) { - return p.push(tpl); - }).on('end', function (x) { - throw new Error('tag ' + tagToken.raw + ' not closed'); - }); - - stream.start(); - }, - - render: function render(scope, hash) { - for (var i = 0; i < this.branches.length; i++) { - var branch = this.branches[i]; - var cond = _2.default.evalExp(branch.cond, scope); - if (_2.default.isTruthy(cond)) { - return liquid.renderer.renderTemplates(branch.templates, scope); - } - } - return liquid.renderer.renderTemplates(this.elseTemplates, scope); - } - }); -}; - -},{"..":6}],22:[function(require,module,exports){ -'use strict'; - -var Liquid = require('..'); -var lexical = Liquid.lexical; -var withRE = new RegExp('with\\s+(' + lexical.value.source + ')'); -var staticFileRE = /[^\s,]+/; -var assert = require('../util/assert.js'); - -module.exports = function (liquid) { - liquid.registerTag('include', { - parse: function parse(token) { - var match = staticFileRE.exec(token.args); - if (match) { - this.staticValue = match[0]; - } - - match = lexical.value.exec(token.args); - if (match) { - this.value = match[0]; - } - - match = withRE.exec(token.args); - if (match) { - this.with = match[1]; - } - }, - render: function render(scope, hash) { - var _this = this; - - var pFilepath = void 0; - if (scope.opts.dynamicPartials) { - if (lexical.quotedLine.exec(this.value)) { - var template = this.value.slice(1, -1); - pFilepath = liquid.parseAndRender(template, scope.getAll(), scope.opts); - } else { - pFilepath = Promise.resolve(Liquid.evalValue(this.value, scope)); - } - } else { - pFilepath = Promise.resolve(this.staticValue); - } - - var originBlocks = scope.opts.blocks; - var originBlockMode = scope.opts.blockMode; - - return pFilepath.then(function (filepath) { - assert(filepath, 'cannot include with empty filename'); - scope.opts.blocks = {}; - scope.opts.blockMode = 'output'; - if (_this.with) { - hash[filepath] = Liquid.evalValue(_this.with, scope); - } - return liquid.getTemplate(filepath, scope.opts.root); - }).then(function (templates) { - scope.push(hash); - return liquid.renderer.renderTemplates(templates, scope); - }).then(function (html) { - scope.pop(hash); - scope.opts.blocks = originBlocks; - scope.opts.blockMode = originBlockMode; - return html; - }); - } - }); -}; - -},{"..":6,"../util/assert.js":30}],23:[function(require,module,exports){ -'use strict'; - -var Liquid = require('../index'); -var assert = require('../util/assert.js'); -var lexical = Liquid.lexical; -var types = require('../scope').types; - -module.exports = function (liquid) { - liquid.registerTag('increment', { - parse: function parse(token) { - var match = token.args.match(lexical.identifier); - assert(match, 'illegal identifier ' + token.args); - this.variable = match[0]; - }, - render: function render(scope, hash) { - var context = scope.findContextFor(this.variable, function (ctx) { - return Object.getPrototypeOf(ctx) !== types.CaptureScope && Object.getPrototypeOf(ctx) !== types.AssignScope; - }); - if (!context) { - context = Object.create(types.IncrementScope); - scope.unshift(context); - } - if (typeof context[this.variable] !== 'number') { - context[this.variable] = 0; - } - var val = context[this.variable]; - context[this.variable]++; - return val; - } - }); -}; - -},{"../index":6,"../scope":11,"../util/assert.js":30}],24:[function(require,module,exports){ -'use strict'; - -module.exports = function (engine) { - require('./assign.js')(engine); - require('./capture.js')(engine); - require('./case.js')(engine); - require('./comment.js')(engine); - require('./cycle.js')(engine); - require('./decrement.js')(engine); - require('./for.js')(engine); - require('./if.js')(engine); - require('./include.js')(engine); - require('./increment.js')(engine); - require('./layout.js')(engine); - require('./raw.js')(engine); - require('./tablerow.js')(engine); - require('./unless.js')(engine); -}; - -},{"./assign.js":14,"./capture.js":15,"./case.js":16,"./comment.js":17,"./cycle.js":18,"./decrement.js":19,"./for.js":20,"./if.js":21,"./include.js":22,"./increment.js":23,"./layout.js":25,"./raw.js":26,"./tablerow.js":27,"./unless.js":28}],25:[function(require,module,exports){ -'use strict'; - -var Liquid = require('..'); -var lexical = Liquid.lexical; -var assert = require('../util/assert.js'); -var staticFileRE = /\S+/; - -/* - * blockMode: - * * "store": store rendered html into blocks - * * "output": output rendered html - */ - -module.exports = function (liquid) { - liquid.registerTag('layout', { - parse: function parse(token, remainTokens) { - var match = staticFileRE.exec(token.args); - if (match) { - this.staticLayout = match[0]; - } - - match = lexical.value.exec(token.args); - if (match) { - this.layout = match[0]; - } - - this.tpls = liquid.parser.parse(remainTokens); - }, - render: function render(scope, hash) { - var layout = scope.opts.dynamicPartials ? Liquid.evalValue(this.layout, scope) : this.staticLayout; - assert(layout, 'cannot apply layout with empty filename'); - - // render the remaining tokens immediately - scope.opts.blockMode = 'store'; - return liquid.renderer.renderTemplates(this.tpls, scope).then(function (html) { - if (scope.opts.blocks[''] === undefined) { - scope.opts.blocks[''] = html; - } - return liquid.getTemplate(layout, scope.opts.root); - }).then(function (templates) { - scope.push(hash); - scope.opts.blockMode = 'output'; - return liquid.renderer.renderTemplates(templates, scope); - }).then(function (partial) { - scope.pop(hash); - return partial; - }); - } - }); - - liquid.registerTag('block', { - parse: function parse(token, remainTokens) { - var _this = this; - - var match = /\w+/.exec(token.args); - this.block = match ? match[0] : ''; - - this.tpls = []; - var stream = liquid.parser.parseStream(remainTokens).on('tag:endblock', function () { - return stream.stop(); - }).on('template', function (tpl) { - return _this.tpls.push(tpl); - }).on('end', function () { - throw new Error('tag ' + token.raw + ' not closed'); - }); - stream.start(); - }, - render: function render(scope) { - var _this2 = this; - - return Promise.resolve(scope.opts.blocks[this.block]).then(function (html) { - return html === undefined - // render default block - ? liquid.renderer.renderTemplates(_this2.tpls, scope) - // use child-defined block - : html; - }).then(function (html) { - if (scope.opts.blockMode === 'store') { - scope.opts.blocks[_this2.block] = html; - return ''; - } - return html; - }); - } - }); -}; - -},{"..":6,"../util/assert.js":30}],26:[function(require,module,exports){ -'use strict'; - -module.exports = function (liquid) { - liquid.registerTag('raw', { - parse: function parse(tagToken, remainTokens) { - var _this = this; - - 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 () { - throw new Error('tag ' + tagToken.raw + ' not closed'); - }); - stream.start(); - }, - render: function render(scope, hash) { - return this.tokens.map(function (token) { - return token.raw; - }).join(''); - } - }); -}; - -},{}],27:[function(require,module,exports){ -'use strict'; - -var _ = require('..'); - -var _2 = _interopRequireDefault(_); - -var _promise = require('../util/promise.js'); - -var _assert = require('../util/assert.js'); - -var _assert2 = _interopRequireDefault(_assert); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var lexical = _2.default.lexical; -var re = new RegExp('^(' + lexical.identifier.source + ')\\s+in\\s+' + ('(' + lexical.value.source + ')') + ('(?:\\s+' + lexical.hash.source + ')*$')); - -module.exports = function (liquid) { - liquid.registerTag('tablerow', { - - parse: function parse(tagToken, remainTokens) { - var _this = this; - - var match = re.exec(tagToken.args); - (0, _assert2.default)(match, 'illegal tag: ' + tagToken.raw); - - this.variable = match[1]; - this.collection = match[2]; - this.templates = []; - - var p = void 0; - var stream = liquid.parser.parseStream(remainTokens).on('start', function () { - return p = _this.templates; - }).on('tag:endtablerow', function (token) { - return stream.stop(); - }).on('template', function (tpl) { - return p.push(tpl); - }).on('end', function () { - throw new Error('tag ' + tagToken.raw + ' not closed'); - }); - - stream.start(); - }, - - render: function render(scope, hash) { - var _this2 = this; - - var collection = _2.default.evalExp(this.collection, scope) || []; - - var html = ''; - var offset = hash.offset || 0; - var limit = hash.limit === undefined ? collection.length : hash.limit; - - var cols = hash.cols; - var row = void 0; - var col = void 0; - - // build array of arguments to pass to sequential promises... - collection = collection.slice(offset, offset + limit); - if (!cols) cols = collection.length; - var contexts = collection.map(function (item, i) { - var ctx = {}; - ctx[_this2.variable] = item; - return ctx; - }); - - return (0, _promise.mapSeries)(contexts, function (context, idx) { - row = Math.floor(idx / cols) + 1; - col = idx % cols + 1; - if (col === 1) { - if (row !== 1) { - html += ''; + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } } - html += ''; } - html += ''; - scope.push(context); - return liquid.renderer.renderTemplates(_this2.templates, scope).then(function (partial) { - scope.pop(context); - html += partial; - html += ''; - return html; + return liquid.renderer.renderTemplates(this.elseTemplates, scope); + } + }); + } + + function Increment (liquid, Liquid) { + var lexical = Liquid.lexical; + var _Liquid$Types = Liquid.Types, + CaptureScope = _Liquid$Types.CaptureScope, + AssignScope = _Liquid$Types.AssignScope, + IncrementScope = _Liquid$Types.IncrementScope; + + + liquid.registerTag('increment', { + parse: function parse(token) { + var match = token.args.match(lexical.identifier); + assert(match, 'illegal identifier ' + token.args); + this.variable = match[0]; + }, + render: function render(scope, hash) { + var context = scope.findContextFor(this.variable, function (ctx) { + return Object.getPrototypeOf(ctx) !== CaptureScope && Object.getPrototypeOf(ctx) !== AssignScope; }); - }).then(function () { - if (row > 0) { - html += ''; + if (!context) { + context = Object.create(IncrementScope); + scope.unshift(context); } - return html; - }); - } - }); -}; + if (typeof context[this.variable] !== 'number') { + context[this.variable] = 0; + } + var val = context[this.variable]; + context[this.variable]++; + return val; + } + }); + } -},{"..":6,"../util/assert.js":30,"../util/promise.js":33}],28:[function(require,module,exports){ -'use strict'; + /* + * blockMode: + * * "store": store rendered html into blocks + * * "output": output rendered html + */ -var _index = require('../index'); + function Layout (liquid, Liquid) { + var rValue = Liquid.lexical.value; + var staticFileRE = /\S+/; -var _index2 = _interopRequireDefault(_index); + liquid.registerTag('layout', { + parse: function parse(token, remainTokens) { + var match = staticFileRE.exec(token.args); + if (match) { + this.staticLayout = match[0]; + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + match = rValue.exec(token.args); + if (match) { + this.layout = match[0]; + } -module.exports = function (liquid) { - liquid.registerTag('unless', { - parse: function parse(tagToken, remainTokens) { - var _this = this; + this.tpls = liquid.parser.parse(remainTokens); + }, + render: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(scope, hash) { + var layout, html, templates, partial; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + layout = scope.opts.dynamicPartials ? Liquid.evalValue(this.layout, scope) : this.staticLayout; - this.templates = []; - this.elseTemplates = []; - var p = void 0; - var stream = liquid.parser.parseStream(remainTokens).on('start', function (x) { - p = _this.templates; - _this.cond = tagToken.args; - }).on('tag:else', function () { - return p = _this.elseTemplates; - }).on('tag:endunless', function (token) { - return stream.stop(); - }).on('template', function (tpl) { - return p.push(tpl); - }).on('end', function (x) { - throw new Error('tag ' + tagToken.raw + ' not closed'); - }); + assert(layout, 'cannot apply layout with empty filename'); - stream.start(); + // render the remaining tokens immediately + scope.opts.blockMode = 'store'; + _context.next = 5; + return liquid.renderer.renderTemplates(this.tpls, scope); + + case 5: + html = _context.sent; + + if (scope.opts.blocks[''] === undefined) { + scope.opts.blocks[''] = html; + } + _context.next = 9; + return liquid.getTemplate(layout, scope.opts.root); + + case 9: + templates = _context.sent; + + scope.push(hash); + scope.opts.blockMode = 'output'; + _context.next = 14; + return liquid.renderer.renderTemplates(templates, scope); + + case 14: + partial = _context.sent; + + scope.pop(hash); + return _context.abrupt('return', partial); + + case 17: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + function render(_x, _x2) { + return _ref.apply(this, arguments); + } + + return render; + }() + }); + + liquid.registerTag('block', { + parse: function parse(token, remainTokens) { + var _this = this; + + var match = /\w+/.exec(token.args); + this.block = match ? match[0] : ''; + + this.tpls = []; + var stream = liquid.parser.parseStream(remainTokens).on('tag:endblock', function () { + return stream.stop(); + }).on('template', function (tpl) { + return _this.tpls.push(tpl); + }).on('end', function () { + throw new Error('tag ' + token.raw + ' not closed'); + }); + stream.start(); + }, + render: function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(scope) { + var childDefined, html; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + childDefined = scope.opts.blocks[this.block]; + + if (!(childDefined !== undefined)) { + _context2.next = 5; + break; + } + + _context2.t0 = childDefined; + _context2.next = 8; + break; + + case 5: + _context2.next = 7; + return liquid.renderer.renderTemplates(this.tpls, scope); + + case 7: + _context2.t0 = _context2.sent; + + case 8: + html = _context2.t0; + + if (!(scope.opts.blockMode === 'store')) { + _context2.next = 12; + break; + } + + scope.opts.blocks[this.block] = html; + return _context2.abrupt('return', ''); + + case 12: + return _context2.abrupt('return', html); + + case 13: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function render(_x3) { + return _ref2.apply(this, arguments); + } + + return render; + }() + }); + } + + function Raw (liquid) { + liquid.registerTag('raw', { + parse: function parse(tagToken, remainTokens) { + var _this = this; + + 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 () { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + stream.start(); + }, + render: function render(scope, hash) { + return this.tokens.map(function (token) { + return token.raw; + }).join(''); + } + }); + } + + function Tablerow (liquid, Liquid) { + var lexical = Liquid.lexical; + var re = new RegExp('^(' + lexical.identifier.source + ')\\s+in\\s+' + ('(' + lexical.value.source + ')') + ('(?:\\s+' + lexical.hash.source + ')*$')); + + liquid.registerTag('tablerow', { + + 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.templates = []; + + var p = void 0; + var stream = liquid.parser.parseStream(remainTokens).on('start', function () { + return p = _this.templates; + }).on('tag:endtablerow', function (token) { + return stream.stop(); + }).on('template', function (tpl) { + return p.push(tpl); + }).on('end', function () { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + + stream.start(); + }, + + render: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(scope, hash) { + var _this2 = this; + + var collection, offset, limit, cols, contexts, row, html; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + collection = Liquid.evalExp(this.collection, scope) || []; + offset = hash.offset || 0; + limit = hash.limit === undefined ? collection.length : hash.limit; + + + collection = collection.slice(offset, offset + limit); + cols = hash.cols || collection.length; + contexts = collection.map(function (item, i) { + var ctx = {}; + ctx[_this2.variable] = item; + return ctx; + }); + row = void 0; + html = ''; + _context2.next = 10; + return mapSeries(contexts, function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(context, idx) { + var col; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + row = Math.floor(idx / cols) + 1; + col = idx % cols + 1; + + if (col === 1) { + if (row !== 1) { + html += ''; + } + html += ''; + } + + html += ''; + scope.push(context); + _context.next = 7; + return liquid.renderer.renderTemplates(_this2.templates, scope); + + case 7: + html += _context.sent; + + html += ''; + scope.pop(context); + return _context.abrupt('return', html); + + case 11: + case 'end': + return _context.stop(); + } + } + }, _callee, _this2); + })); + + return function (_x3, _x4) { + return _ref2.apply(this, arguments); + }; + }()); + + case 10: + if (row > 0) { + html += ''; + } + return _context2.abrupt('return', html); + + case 12: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function render(_x, _x2) { + return _ref.apply(this, arguments); + } + + return render; + }() + }); + } + + function Unless (liquid, Liquid) { + liquid.registerTag('unless', { + parse: function parse(tagToken, remainTokens) { + var _this = this; + + this.templates = []; + this.elseTemplates = []; + var p = void 0; + var stream = liquid.parser.parseStream(remainTokens).on('start', function (x) { + p = _this.templates; + _this.cond = tagToken.args; + }).on('tag:else', function () { + return p = _this.elseTemplates; + }).on('tag:endunless', function (token) { + return stream.stop(); + }).on('template', function (tpl) { + return p.push(tpl); + }).on('end', function (x) { + throw new Error('tag ' + tagToken.raw + ' not closed'); + }); + + stream.start(); + }, + + render: function render(scope, hash) { + var cond = Liquid.evalExp(this.cond, scope); + return Liquid.isFalsy(cond) ? liquid.renderer.renderTemplates(this.templates, scope) : liquid.renderer.renderTemplates(this.elseTemplates, scope); + } + }); + } + + function tags (engine, Liquid) { + Assign(engine, Liquid); + Capture(engine, Liquid); + Case(engine, Liquid); + Comment(engine, Liquid); + Cycle(engine, Liquid); + Decrement(engine, Liquid); + For(engine, Liquid); + If(engine, Liquid); + Include(engine, Liquid); + Increment(engine, Liquid); + Layout(engine, Liquid); + Raw(engine, Liquid); + Tablerow(engine, Liquid); + Unless(engine, Liquid); + } + + 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' + + // 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]; }, - render: function render(scope, hash) { - var cond = _index2.default.evalExp(this.cond, scope); - return _index2.default.isFalsy(cond) ? liquid.renderer.renderTemplates(this.templates, scope) : liquid.renderer.renderTemplates(this.elseTemplates, scope); - } - }); -}; + getDayOfYear: function getDayOfYear(d) { + var num = 0; + for (var i = 0; i < d.getMonth(); ++i) { + num += _date.daysInMonth(d)[i]; + } + return num + d.getDate(); + }, -},{"../index":6}],29:[function(require,module,exports){ -'use strict'; + // 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); + }, -var lexical = require('./lexical.js'); -var TokenizationError = require('./util/error.js').TokenizationError; -var _ = require('./util/underscore.js'); -var whiteSpaceCtrl = require('./whitespace-ctrl.js'); -var assert = require('./util/assert.js'); + isLeapYear: function isLeapYear(d) { + var year = d.getFullYear(); + return !!((year & 3) === 0 && (year % 100 || year % 400 === 0 && year)); + }, -function parse(input, file, options) { - assert(_.isString(input), 'illegal input'); + getSuffix: function getSuffix(d) { + var str = d.getDate().toString(); + var index = parseInt(str.slice(-1)); + return suffixes[index] || suffixes['default']; + }, - var rLiquid = /({%-?([\s\S]*?)-?%})|({{-?([\s\S]*?)-?}})/g; - var currIndent = 0; - var lineNumber = LineNumber(input); - var lastMatchEnd = 0; - var tokens = []; - - for (var match; match = rLiquid.exec(input); lastMatchEnd = rLiquid.lastIndex) { - if (match.index > lastMatchEnd) { - tokens.push(parseHTMLToken(lastMatchEnd, match.index)); - } - tokens.push(match[1] ? parseTagToken(match[1], match[2].trim(), match.index) : parseValueToken(match[3], match[4].trim(), match.index)); - } - if (input.length > lastMatchEnd) { - tokens.push(parseHTMLToken(lastMatchEnd, input.length)); - } - whiteSpaceCtrl(tokens, options); - return tokens; - - function parseTagToken(raw, value, pos) { - var match = value.match(lexical.tagLine); - var token = { - type: 'tag', - indent: currIndent, - line: lineNumber.get(pos), - trim_left: raw.slice(0, 3) === '{%-', - trim_right: raw.slice(-3) === '-%}', - raw: raw, - value: value, - input: input, - file: file - }; - if (!match) { - throw new TokenizationError('illegal tag syntax', token); - } - token.name = match[1]; - token.args = match[2]; - return token; - } - - function parseValueToken(raw, value, pos) { - return { - type: 'value', - line: lineNumber.get(pos), - trim_left: raw.slice(0, 3) === '{{-', - trim_right: raw.slice(-3) === '-}}', - raw: raw, - value: value, - input: input, - file: file - }; - } - - function parseHTMLToken(begin, end) { - var htmlFragment = input.slice(begin, end); - currIndent = _.last(htmlFragment.split('\n')).length; - - return { - type: 'html', - raw: htmlFragment, - value: htmlFragment - }; - } -} - -function LineNumber(html) { - var parsedLinesCount = 0; - var lastMatchBegin = -1; - - return { - get: function get(pos) { - var lines = html.slice(lastMatchBegin + 1, pos).split('\n'); - parsedLinesCount += lines.length - 1; - lastMatchBegin = pos; - return parsedLinesCount + 1; + century: function century(d) { + return parseInt(d.getFullYear().toString().substring(0, 2), 10); } }; -} -exports.parse = parse; -exports.whiteSpaceCtrl = whiteSpaceCtrl; + var _number = { + pad: function pad(value, size, ch) { + if (!ch) ch = '0'; + var result = value.toString(); + var pad = size - result.length; -},{"./lexical.js":7,"./util/assert.js":30,"./util/error.js":31,"./util/underscore.js":35,"./whitespace-ctrl.js":37}],30:[function(require,module,exports){ -'use strict'; - -var AssertionError = require('./error.js').AssertionError; - -function assert(predicate, message) { - if (!predicate) { - message = message || 'expect ' + predicate + ' to be true'; - throw new AssertionError(message); - } -} - -module.exports = assert; - -},{"./error.js":31}],31:[function(require,module,exports){ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.TokenizationError = TokenizationError; -exports.ParseError = ParseError; -exports.RenderError = RenderError; -exports.RenderBreakError = RenderBreakError; -exports.AssertionError = AssertionError; - -var _underscore = require('./underscore.js'); - -var _underscore2 = _interopRequireDefault(_underscore); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function initError() { - this.name = this.constructor.name; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } -} - -function initLiquidError(err, token) { - initError.call(this); - - this.input = token.input; - this.line = token.line; - this.file = token.file; - - var context = mkContext(token.input, token.line); - this.message = mkMessage(err.message, token); - this.stack = context + '\n' + (this.stack || this.message) + (err.stack ? '\nFrom ' + err.stack : ''); -} - -function TokenizationError(message, token) { - initLiquidError.call(this, { message: message }, token); -} -TokenizationError.prototype = Object.create(Error.prototype); -TokenizationError.prototype.constructor = TokenizationError; - -function ParseError(e, token) { - _underscore2.default.assign(this, e); - this.originalError = e; - - initLiquidError.call(this, e, token); -} -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; - } - _underscore2.default.assign(this, e); - this.originalError = e; - - initLiquidError.call(this, e, tpl.token); -} -RenderError.prototype = Object.create(Error.prototype); -RenderError.prototype.constructor = RenderError; - -function RenderBreakError(message) { - initError.call(this); - this.message = message + ''; -} -RenderBreakError.prototype = Object.create(Error.prototype); -RenderBreakError.prototype.constructor = RenderBreakError; - -function AssertionError(message) { - initError.call(this); - 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 context = _underscore2.default.range(begin, end + 1).map(function (l) { - return [l === line ? '>> ' : ' ', align(l, end), '| ', lines[l - 1]].join(''); - }).join('\n'); - - return context; -} - -function align(n, max) { - 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; -} - -},{"./underscore.js":35}],32:[function(require,module,exports){ -'use strict'; - -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); - }); - }); -}; - -function statFileAsync(path) { - return new Promise(function (resolve, reject) { - fs.stat(path, function (err, stat) { - return err ? reject(err) : resolve(stat); - }); - }); -}; - -module.exports = { - readFileAsync: readFileAsync, - statFileAsync: statFileAsync -}; - -},{"fs":1}],33:[function(require,module,exports){ -'use strict'; - -/* - * 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). - */ -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); - }); - }); - 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). - */ -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; - }); -} - -exports.anySeries = anySeries; -exports.mapSeries = mapSeries; - -},{}],34:[function(require,module,exports){ -'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 suffixes = { - 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]; - }, - - 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; - - while (pad-- > 0) { - result = ch + result; - } - - return result; - } -}; - -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 '%'; - } -}; -formatCodes.h = formatCodes.b; -formatCodes.N = formatCodes.L; - -var strftime = function strftime(d, format) { - var output = ''; - var remaining = format; - - 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 = formatCodes[ch]; - output += func ? func.call(this, d) : '%' + ch; - } -}; - -module.exports = strftime; - -},{}],35:[function(require,module,exports){ -'use strict'; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var toStr = Object.prototype.toString; - -/* - * Checks if value is classified as a String primitive or object. - * @param {any} value The value to check. - * @return {Boolean} Returns true if value is a string, else false. - */ -function isString(value) { - return toStr.call(value) === '[object String]'; -} - -function stringify(value) { - if (isNil(value)) { - return String(value); - } - if (typeof value.to_liquid === 'function') { - return stringify(value.to_liquid()); - } - if (typeof value.toLiquid === 'function') { - return stringify(value.toLiquid()); - } - if (isString(value)) { - return value; - } - - var cache = []; - return JSON.stringify(value, function (key, value) { - if (isObject(value)) { - if (cache.indexOf(value) !== -1) { - return; + while (pad-- > 0) { + result = ch + result; } - cache.push(value); + + return result; } - return value; - }); -} + }; -function isNil(value) { - return value === null || value === undefined; -} + 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 '%'; + } + }; + formatCodes.h = formatCodes.b; + formatCodes.N = formatCodes.L; -function isArray(value) { - // be compatible with IE 8 - return toStr.call(value) === '[object Array]'; -} + function strftime (d, format) { + var output = ''; + var remaining = format; -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'; -} + while (true) { + var r = /%./g; + var results = r.exec(remaining); -/* - * 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; + // 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; } } - 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. - * - * Note: This method mutates object and is loosely based on Object.assign. - * - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @return {Object} Returns object. - */ -function assign(object) { - object = isObject(object) ? object : {}; - var srcs = Array.prototype.slice.call(arguments, 1); - srcs.forEach(function (src) { - return Object.assign(object, src); - }); - return object; -} + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + var unescapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'" + }; -function last(arr) { - return arr[arr.length - 1]; -} + var filters = { + 'abs': function abs(v) { + return Math.abs(v); + }, + 'append': function append(v, arg) { + return v + arg; + }, + 'capitalize': function capitalize(str) { + return stringify$1(str).charAt(0).toUpperCase() + str.slice(1); + }, + 'ceil': function ceil(v) { + return Math.ceil(v); + }, + 'concat': function concat(v, arg) { + return Array.prototype.concat.call(v, arg); + }, + 'date': function date(v, arg) { + var date = v; + if (v === 'now') { + date = new Date(); + } else if (isString(v)) { + date = new Date(v); + } + return isValidDate(date) ? strftime(date, arg) : v; + }, + 'default': function _default(v, arg) { + return isTruthy(v) ? v : arg; + }, + 'divided_by': function divided_by(v, arg) { + return v / arg; + }, + 'downcase': function downcase(v) { + return v.toLowerCase(); + }, + 'escape': escape, -function uniq(arr) { - var u = {}; - var a = []; - for (var i = 0, l = arr.length; i < l; ++i) { - if (u.hasOwnProperty(arr[i])) { - continue; + 'escape_once': function escape_once(str) { + return escape(unescape(str)); + }, + 'first': function first(v) { + return v[0]; + }, + 'floor': function floor(v) { + return Math.floor(v); + }, + 'join': function join(v, arg) { + return v.join(arg); + }, + 'last': function last$$1(v) { + return last(v); + }, + 'lstrip': function lstrip(v) { + return stringify$1(v).replace(/^\s+/, ''); + }, + 'map': function map(arr, arg) { + return arr.map(function (v) { + return v[arg]; + }); + }, + 'minus': bindFixed(function (v, arg) { + return v - arg; + }), + 'modulo': bindFixed(function (v, arg) { + return v % arg; + }), + 'newline_to_br': function newline_to_br(v) { + return v.replace(/\n/g, '
'); + }, + 'plus': bindFixed(function (v, arg) { + return Number(v) + Number(arg); + }), + 'prepend': function prepend(v, arg) { + return arg + v; + }, + 'remove': function remove(v, arg) { + return v.split(arg).join(''); + }, + 'remove_first': function remove_first(v, l) { + return v.replace(l, ''); + }, + 'replace': function replace(v, pattern, replacement) { + return stringify$1(v).split(pattern).join(replacement); + }, + 'replace_first': function replace_first(v, arg1, arg2) { + return stringify$1(v).replace(arg1, arg2); + }, + 'reverse': function reverse(v) { + return v.reverse(); + }, + 'round': function round(v, arg) { + var amp = Math.pow(10, arg || 0); + return Math.round(v * amp, arg) / amp; + }, + 'rstrip': function rstrip(str) { + return stringify$1(str).replace(/\s+$/, ''); + }, + 'size': function size(v) { + return v.length; + }, + 'slice': function slice(v, begin, length) { + return v.substr(begin, length === undefined ? 1 : length); + }, + 'sort': function sort(v, arg) { + return v.sort(arg); + }, + 'split': function split(v, arg) { + return stringify$1(v).split(arg); + }, + 'strip': function strip(v) { + return stringify$1(v).trim(); + }, + 'strip_html': function strip_html(v) { + return stringify$1(v).replace(/|||<.*?>/g, ''); + }, + 'strip_newlines': function strip_newlines(v) { + return stringify$1(v).replace(/\n/g, ''); + }, + 'times': function times(v, arg) { + return v * arg; + }, + 'truncate': function truncate(v, l, o) { + v = stringify$1(v); + o = o === undefined ? '...' : o; + l = l || 16; + if (v.length <= l) return v; + return v.substr(0, l - o.length) + o; + }, + 'truncatewords': function truncatewords(v, l, o) { + if (o === undefined) o = '...'; + var arr = v.split(' '); + var ret = arr.slice(0, l).join(' '); + if (arr.length > l) ret += o; + return ret; + }, + 'uniq': function uniq$$1(arr) { + var u = {}; + return (arr || []).filter(function (val) { + if (u.hasOwnProperty(val)) { + return false; + } + u[val] = true; + return true; + }); + }, + 'upcase': function upcase(str) { + return stringify$1(str).toUpperCase(); + }, + 'url_encode': encodeURIComponent + }; + + function escape(str) { + return stringify$1(str).replace(/&|<|>|"|'/g, function (m) { + return escapeMap[m]; + }); + } + + function unescape(str) { + return stringify$1(str).replace(/&(amp|lt|gt|#34|#39);/g, function (m) { + return unescapeMap[m]; + }); + } + + function getFixed(v) { + var p = (v + '').split('.'); + return p.length > 1 ? p[1].length : 0; + } + + function getMaxFixed(l, r) { + return Math.max(getFixed(l), getFixed(r)); + } + + function stringify$1(obj) { + return obj + ''; + } + + function bindFixed(cb) { + return function (l, r) { + var f = getMaxFixed(l, r); + return cb(l, r).toFixed(f); + }; + } + + function isValidDate(date) { + return date instanceof Date && !isNaN(date.getTime()); + } + + function registerAll(liquid) { + return forOwn(filters, function (func, name) { + return liquid.registerFilter(name, func); + }); + } + + registerAll.filters = filters; + + var _engine = { + init: function init(tag, filter$$1, options) { + if (options.cache) { + this.cache = {}; + } + this.options = options; + this.tag = tag; + this.filter = filter$$1; + this.parser = Parser(tag, filter$$1); + this.renderer = Render(); + + tags(this, Liquid); + registerAll(this, Liquid); + + return this; + }, + parse: function parse$$1(html, filepath) { + var tokens = parse(html, filepath, this.options); + return this.parser.parse(tokens); + }, + render: function render(tpl, ctx, opts) { + opts = assign({}, this.options, opts); + var scope = factory(ctx, opts); + return this.renderer.renderTemplates(tpl, scope); + }, + parseAndRender: function () { + var _ref = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(html, ctx, opts) { + var tpl; + return regeneratorRuntime.wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return this.parse(html); + + case 2: + tpl = _context.sent; + return _context.abrupt('return', this.render(tpl, ctx, opts)); + + case 4: + case 'end': + return _context.stop(); + } + } + }, _callee, this); + })); + + function parseAndRender(_x, _x2, _x3) { + return _ref.apply(this, arguments); + } + + return parseAndRender; + }(), + renderFile: function () { + var _ref2 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(filepath, ctx, opts) { + var templates; + return regeneratorRuntime.wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + opts = assign({}, opts); + _context2.next = 3; + return this.getTemplate(filepath, opts.root); + + case 3: + templates = _context2.sent; + return _context2.abrupt('return', this.render(templates, ctx, opts)); + + case 5: + case 'end': + return _context2.stop(); + } + } + }, _callee2, this); + })); + + function renderFile(_x4, _x5, _x6) { + return _ref2.apply(this, arguments); + } + + return renderFile; + }(), + evalValue: function evalValue$$1(str, scope) { + var tpl = this.parser.parseValue(str.trim()); + return this.renderer.evalValue(tpl, scope); + }, + registerFilter: function registerFilter(name, filter$$1) { + return this.filter.register(name, filter$$1); + }, + registerTag: function registerTag(name, tag) { + return this.tag.register(name, tag); + }, + lookup: function lookup(filepath, root) { + var _this = this; + + root = this.options.root.concat(root || []); + root = uniq(root); + var paths = root.map(function (root) { + return path.resolve(root, filepath); + }); + return anySeries(paths, function () { + var _ref3 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(path$$1) { + return regeneratorRuntime.wrap(function _callee3$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _context3.prev = 0; + _context3.next = 3; + return statFileAsync(path$$1); + + case 3: + return _context3.abrupt('return', path$$1); + + case 6: + _context3.prev = 6; + _context3.t0 = _context3['catch'](0); + + _context3.t0.message = _context3.t0.code + ': Failed to lookup ' + filepath + ' in: ' + root; + throw _context3.t0; + + case 10: + case 'end': + return _context3.stop(); + } + } + }, _callee3, _this, [[0, 6]]); + })); + + return function (_x7) { + return _ref3.apply(this, arguments); + }; + }()); + }, + getTemplate: function getTemplate(filepath, root) { + return typeof XMLHttpRequest === 'undefined' ? this.getTemplateFromFile(filepath, root) : this.getTemplateFromUrl(filepath, root); + }, + getTemplateFromFile: function () { + var _ref4 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5(filepath, root) { + var _this2 = this; + + return regeneratorRuntime.wrap(function _callee5$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + if (!path.extname(filepath)) { + filepath += this.options.extname; + } + _context5.next = 3; + return this.lookup(filepath, root); + + case 3: + filepath = _context5.sent; + return _context5.abrupt('return', this.respectCache(filepath, asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() { + var str; + return regeneratorRuntime.wrap(function _callee4$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return readFileAsync(filepath); + + case 2: + str = _context4.sent; + return _context4.abrupt('return', _this2.parse(str, filepath)); + + case 4: + case 'end': + return _context4.stop(); + } + } + }, _callee4, _this2); + })))); + + case 5: + case 'end': + return _context5.stop(); + } + } + }, _callee5, this); + })); + + function getTemplateFromFile(_x8, _x9) { + return _ref4.apply(this, arguments); + } + + return getTemplateFromFile; + }(), + getTemplateFromUrl: function () { + var _ref6 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7(filepath, root) { + var _this3 = this; + + var fullUrl; + return regeneratorRuntime.wrap(function _callee7$(_context7) { + while (1) { + switch (_context7.prev = _context7.next) { + case 0: + fullUrl = void 0; + + if (valid(filepath)) { + fullUrl = filepath; + } else { + if (!extname(filepath)) { + filepath += this.options.extname; + } + fullUrl = resolve(root || this.options.root, filepath); + } + return _context7.abrupt('return', this.respectCache(filepath, asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() { + return regeneratorRuntime.wrap(function _callee6$(_context6) { + while (1) { + switch (_context6.prev = _context6.next) { + case 0: + _context6.t0 = _this3; + _context6.next = 3; + return get$1(fullUrl); + + case 3: + _context6.t1 = _context6.sent; + return _context6.abrupt('return', _context6.t0.parse.call(_context6.t0, _context6.t1)); + + case 5: + case 'end': + return _context6.stop(); + } + } + }, _callee6, _this3); + })))); + + case 3: + case 'end': + return _context7.stop(); + } + } + }, _callee7, this); + })); + + function getTemplateFromUrl(_x10, _x11) { + return _ref6.apply(this, arguments); + } + + return getTemplateFromUrl; + }(), + respectCache: function () { + var _ref8 = asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8(key, getter) { + var cacheEnabled, value$$1; + return regeneratorRuntime.wrap(function _callee8$(_context8) { + while (1) { + switch (_context8.prev = _context8.next) { + case 0: + cacheEnabled = this.options.cache; + + if (!(cacheEnabled && this.cache[key])) { + _context8.next = 3; + break; + } + + return _context8.abrupt('return', this.cache[key]); + + case 3: + _context8.next = 5; + return getter(); + + case 5: + value$$1 = _context8.sent; + + if (cacheEnabled) { + this.cache[key] = value$$1; + } + return _context8.abrupt('return', value$$1); + + case 8: + case 'end': + return _context8.stop(); + } + } + }, _callee8, this); + })); + + function respectCache(_x12, _x13) { + return _ref8.apply(this, arguments); + } + + return respectCache; + }(), + express: function express(opts) { + opts = opts || {}; + var self = this; + return function (filePath, ctx, cb) { + assert(Array.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 cb(null, html); + }, cb); + }; } - a.push(arr[i]); - u[arr[i]] = 1; + }; + + function normalizeStringArray(value$$1) { + if (Array.isArray(value$$1)) return value$$1; + if (isString(value$$1)) return [value$$1]; + return []; } - return a; -} -/* - * 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) { - var type = typeof value === 'undefined' ? 'undefined' : _typeof(value); - return value != null && (type === 'object' || type === 'function'); -} + function Liquid(options) { + options = assign({ + root: ['.'], + cache: false, + extname: '', + dynamicPartials: true, + trim_tag_right: false, + trim_tag_left: false, + trim_value_right: false, + trim_value_left: false, + greedy: true, + strict_filters: false, + strict_variables: false + }, options); + options.root = normalizeStringArray(options.root); -/* - * 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; + var engine = Object.create(_engine); + engine.init(Tag(), Filter(options), options); + return engine; } - step = step || 1; - var arr = []; - for (var i = start; i < stop; i += step) { - arr.push(i); - } - return arr; -} + Liquid.isTruthy = isTruthy; + Liquid.isFalsy = isFalsy; + Liquid.evalExp = evalExp; + Liquid.evalValue = evalValue; + Liquid.Types = { + ParseError: ParseError, + TokenizationError: TokenizationError, + RenderBreakError: RenderBreakError, + AssertionError: AssertionError, + AssignScope: Object.create(null), + CaptureScope: Object.create(null), + IncrementScope: Object.create(null), + DecrementScope: Object.create(null) + }; + Liquid.lexical = lexical; -// lang -exports.isString = isString; -exports.isObject = isObject; -exports.isArray = isArray; -exports.isNil = isNil; -exports.isError = isError; + return Liquid; -// array -exports.range = range; -exports.last = last; - -// object -exports.forOwn = forOwn; -exports.assign = assign; -exports.uniq = uniq; -exports.stringify = stringify; - -},{}],36:[function(require,module,exports){ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.extname = extname; -exports.valid = valid; -exports.resolve = resolve; - -var _resolveUrl = require('resolve-url'); - -var _resolveUrl2 = _interopRequireDefault(_resolveUrl); - -var _underscore = require('./underscore'); - -var _underscore2 = _interopRequireDefault(_underscore); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/; -var urlRe = /^(?:\w+:)?\/\/([^\s.]+\.\S{2}|localhost[:?\d]*)\S*$/; - -// https://github.com/jinder/path/blob/master/path.js#L567 -function extname(path) { - return splitPathRe.exec(path).slice(1)[3]; -} - -// https://www.npmjs.com/package/is-url -function valid(path) { - return urlRe.test(path); -} - -function resolve(root, path) { - if (Object.prototype.toString.call(root) === '[object Array]') { - root = root[0]; - } - if (root && _underscore2.default.last(root) !== '/') { - root += '/'; - } - return (0, _resolveUrl2.default)(root, path); -} - -},{"./underscore":35,"resolve-url":3}],37:[function(require,module,exports){ -'use strict'; - -var _ = require('./util/underscore.js'); - -function whiteSpaceCtrl(tokens, options) { - options = _.assign({ greedy: true }, options); - var inRaw = false; - - tokens.forEach(function (token, i) { - if (shouldTrimLeft(token, inRaw, options)) { - trimLeft(tokens[i - 1], options.greedy); - } - - if (token.type === 'tag' && token.name === 'raw') inRaw = true; - if (token.type === 'tag' && token.name === 'endraw') inRaw = false; - - if (shouldTrimRight(token, inRaw, options)) { - trimRight(tokens[i + 1], options.greedy); - } - }); -} - -function shouldTrimLeft(token, inRaw, options) { - if (inRaw) return false; - if (token.type === 'tag') return token.trim_left || options.trim_tag_left; - if (token.type === 'value') return token.trim_left || options.trim_value_left; -} - -function shouldTrimRight(token, inRaw, options) { - if (inRaw) return false; - if (token.type === 'tag') return token.trim_right || options.trim_tag_right; - if (token.type === 'value') return token.trim_right || options.trim_value_right; -} - -function trimLeft(token, greedy) { - if (!token || token.type !== 'html') return; - - var rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g; - token.value = token.value.replace(rLeft, ''); -} - -function trimRight(token, greedy) { - if (!token || token.type !== 'html') return; - - var rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g; - token.value = token.value.replace(rRight, ''); -} - -module.exports = whiteSpaceCtrl; - -},{"./util/underscore.js":35}]},{},[6])(6) -}); +}))); +//# sourceMappingURL=liquid.js.map diff --git a/dist/liquid.js.map b/dist/liquid.js.map new file mode 100644 index 000000000..8c5096a42 --- /dev/null +++ b/dist/liquid.js.map @@ -0,0 +1 @@ +{"version":3,"file":"liquid.js","sources":["../node_modules/regenerator-runtime/runtime.js","../src/util/underscore.js","../src/lexical.js","../src/util/error.js","../src/util/assert.js","../src/scope.js","../src/util/http.js","../src/whitespace-ctrl.js","../src/tokenizer.js","../src/util/fs.js","../src/util/url.js","../src/operators.js","../src/syntax.js","../src/render.js","../src/tag.js","../src/filter.js","../src/parser.js","../src/util/promise.js","../src/tags/for.js","../src/tags/assign.js","../src/tags/capture.js","../src/tags/case.js","../src/tags/comment.js","../src/tags/include.js","../src/tags/decrement.js","../src/tags/cycle.js","../src/tags/if.js","../src/tags/increment.js","../src/tags/layout.js","../src/tags/raw.js","../src/tags/tablerow.js","../src/tags/unless.js","../src/tags/index.js","../src/util/strftime.js","../src/filters.js","../src/index.js"],"sourcesContent":["/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n!(function(global) {\n \"use strict\";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n var inModule = typeof module === \"object\";\n var runtime = global.regeneratorRuntime;\n if (runtime) {\n if (inModule) {\n // If regeneratorRuntime is defined globally and we're in a module,\n // make the exports object identical to regeneratorRuntime.\n module.exports = runtime;\n }\n // Don't bother evaluating the rest of this file if the runtime was\n // already defined globally.\n return;\n }\n\n // Define the runtime globally (as expected by generated code) as either\n // module.exports (if we're in a module) or a new, empty object.\n runtime = global.regeneratorRuntime = inModule ? module.exports : {};\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n runtime.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don't natively support it.\n var IteratorPrototype = {};\n IteratorPrototype[iteratorSymbol] = function () {\n return this;\n };\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n GeneratorFunctionPrototype.constructor = GeneratorFunction;\n GeneratorFunctionPrototype[toStringTagSymbol] =\n GeneratorFunction.displayName = \"GeneratorFunction\";\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n prototype[method] = function(arg) {\n return this._invoke(method, arg);\n };\n });\n }\n\n runtime.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n runtime.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n if (!(toStringTagSymbol in genFun)) {\n genFun[toStringTagSymbol] = \"GeneratorFunction\";\n }\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n // meant to be awaited.\n runtime.awrap = function(arg) {\n return { __await: arg };\n };\n\n function AsyncIterator(generator) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value &&\n typeof value === \"object\" &&\n hasOwn.call(value, \"__await\")) {\n return Promise.resolve(value.__await).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return Promise.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new Promise(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n AsyncIterator.prototype[asyncIteratorSymbol] = function () {\n return this;\n };\n runtime.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n runtime.async = function(innerFn, outerFn, self, tryLocsList) {\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList)\n );\n\n return runtime.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === \"throw\") {\n if (delegate.iterator.return) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n Gp[toStringTagSymbol] = \"Generator\";\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n Gp[iteratorSymbol] = function() {\n return this;\n };\n\n Gp.toString = function() {\n return \"[object Generator]\";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n runtime.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n runtime.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n})(\n // In sloppy mode, unbound `this` refers to the global object, fallback to\n // Function constructor if we're in global strict mode. That is sadly a form\n // of indirect eval which violates Content Security Policy.\n (function() {\n return this || (typeof self === \"object\" && self);\n })() || Function(\"return this\")()\n);\n","const toStr = Object.prototype.toString\n\n/*\n * Checks if value is classified as a String primitive or object.\n * @param {any} value The value to check.\n * @return {Boolean} Returns true if value is a string, else false.\n */\nexport function isString (value) {\n return toStr.call(value) === '[object String]'\n}\n\nexport function stringify (value) {\n if (isNil(value)) {\n return String(value)\n }\n if (typeof value.to_liquid === 'function') {\n return stringify(value.to_liquid())\n }\n if (typeof value.toLiquid === 'function') {\n return stringify(value.toLiquid())\n }\n if (isString(value)) {\n return value\n }\n\n const cache = []\n return JSON.stringify(value, (key, value) => {\n if (isObject(value)) {\n if (cache.indexOf(value) !== -1) {\n return\n }\n cache.push(value)\n }\n return value\n })\n}\n\nexport function isNil (value) {\n return value === null || value === undefined\n}\n\nexport function isArray (value) {\n // be compatible with IE 8\n return toStr.call(value) === '[object Array]'\n}\n\nexport function isError (value) {\n const signature = Object.prototype.toString.call(value)\n // [object XXXError]\n return signature.substr(-6, 5) === 'Error' ||\n (typeof value.message === 'string' && typeof value.name === 'string')\n}\n\n/*\n * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property.\n * The iteratee is invoked with three arguments: (value, key, object).\n * Iteratee functions may exit iteration early by explicitly returning false.\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @return {Object} Returns object.\n */\nexport function forOwn (object, iteratee) {\n object = object || {}\n for (const k in object) {\n if (object.hasOwnProperty(k)) {\n if (iteratee(object[k], k, object) === false) break\n }\n }\n return object\n}\n\n/*\n * Assigns own enumerable string keyed properties of source objects to the destination object.\n * Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * Note: This method mutates object and is loosely based on Object.assign.\n *\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @return {Object} Returns object.\n */\nexport function assign (object) {\n object = isObject(object) ? object : {}\n const srcs = Array.prototype.slice.call(arguments, 1)\n srcs.forEach((src) => Object.assign(object, src))\n return object\n}\n\nexport function last (arr) {\n return arr[arr.length - 1]\n}\n\nexport function uniq (arr) {\n const u = {}\n const a = []\n for (let i = 0, l = arr.length; i < l; ++i) {\n if (u.hasOwnProperty(arr[i])) {\n continue\n }\n a.push(arr[i])\n u[arr[i]] = 1\n }\n return a\n}\n\n/*\n * Checks if value is the language type of Object.\n * (e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))\n * @param {any} value The value to check.\n * @return {Boolean} Returns true if value is an object, else false.\n */\nexport function isObject (value) {\n const type = typeof value\n return value != null && (type === 'object' || type === 'function')\n}\n\n/*\n * A function to create flexibly-numbered lists of integers,\n * handy for each and map loops. start, if omitted, defaults to 0; step defaults to 1.\n * Returns a list of integers from start (inclusive) to stop (exclusive),\n * incremented (or decremented) by step, exclusive.\n * Note that ranges that stop before they start are considered to be zero-length instead of\n * negative — if you'd like a negative range, use a negative step.\n */\nexport function range (start, stop, step) {\n if (arguments.length === 1) {\n stop = start\n start = 0\n }\n step = step || 1\n\n const arr = []\n for (let i = start; i < stop; i += step) {\n arr.push(i)\n }\n return arr\n}\n","// quote related\nconst singleQuoted = /'[^']*'/\nconst doubleQuoted = /\"[^\"]*\"/\nexport const quoted = new RegExp(`${singleQuoted.source}|${doubleQuoted.source}`)\nexport const quoteBalanced = new RegExp(`(?:${quoted.source}|[^'\"])*`)\n\n// basic types\nexport const integer = /-?\\d+/\nexport const number = /-?\\d+\\.?\\d*|\\.?\\d+/\nexport const bool = /true|false/\n\n// peoperty access\nexport const identifier = /[\\w-]+[?]?/\nexport const subscript = new RegExp(`\\\\[(?:${quoted.source}|[\\\\w-\\\\.]+)\\\\]`)\nexport const literal = new RegExp(`(?:${quoted.source}|${bool.source}|${number.source})`)\nexport const variable = new RegExp(`${identifier.source}(?:\\\\.${identifier.source}|${subscript.source})*`)\n\n// range related\nexport const rangeLimit = new RegExp(`(?:${variable.source}|${number.source})`)\nexport const range = new RegExp(`\\\\(${rangeLimit.source}\\\\.\\\\.${rangeLimit.source}\\\\)`)\nexport const rangeCapture = new RegExp(`\\\\((${rangeLimit.source})\\\\.\\\\.(${rangeLimit.source})\\\\)`)\n\nexport const value = new RegExp(`(?:${variable.source}|${literal.source}|${range.source})`)\n\n// hash related\nexport const hash = new RegExp(`(?:${identifier.source})\\\\s*:\\\\s*(?:${value.source})`)\nexport const hashCapture = new RegExp(`(${identifier.source})\\\\s*:\\\\s*(${value.source})`, 'g')\n\n// full match\nexport const tagLine = new RegExp(`^\\\\s*(${identifier.source})\\\\s*([\\\\s\\\\S]*)\\\\s*$`)\nexport const literalLine = new RegExp(`^${literal.source}$`, 'i')\nexport const variableLine = new RegExp(`^${variable.source}$`)\nexport const numberLine = new RegExp(`^${number.source}$`)\nexport const boolLine = new RegExp(`^${bool.source}$`, 'i')\nexport const quotedLine = new RegExp(`^${quoted.source}$`)\nexport const rangeLine = new RegExp(`^${rangeCapture.source}$`)\nexport const integerLine = new RegExp(`^${integer.source}$`)\n\n// filter related\nexport const valueDeclaration = new RegExp(`(?:${identifier.source}\\\\s*:\\\\s*)?${value.source}`)\nexport const valueList = new RegExp(`${valueDeclaration.source}(\\\\s*,\\\\s*${valueDeclaration.source})*`)\nexport const filter = new RegExp(`${identifier.source}(?:\\\\s*:\\\\s*${valueList.source})?`, 'g')\nexport const filterCapture = new RegExp(`(${identifier.source})(?:\\\\s*:\\\\s*(${valueList.source}))?`)\nexport const filterLine = new RegExp(`^${filterCapture.source}$`)\n\nexport const operators = [\n /\\s+or\\s+/,\n /\\s+and\\s+/,\n /==|!=|<=|>=|<|>|\\s+contains\\s+/\n]\n\nexport function isInteger (str) {\n return integerLine.test(str)\n}\n\nexport function isLiteral (str) {\n return literalLine.test(str)\n}\n\nexport function isRange (str) {\n return rangeLine.test(str)\n}\n\nexport function isVariable (str) {\n return variableLine.test(str)\n}\n\nexport function matchValue (str) {\n return value.exec(str)\n}\n\nexport function parseLiteral (str) {\n let res = str.match(numberLine)\n if (res) {\n return Number(str)\n }\n res = str.match(boolLine)\n if (res) {\n return str.toLowerCase() === 'true'\n }\n res = str.match(quotedLine)\n if (res) {\n return str.slice(1, -1)\n }\n throw new TypeError(`cannot parse '${str}' as literal`)\n}\n","import * as _ from './underscore.js'\n\nfunction initError () {\n this.name = this.constructor.name\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor)\n }\n}\n\nfunction initLiquidError (err, token) {\n initError.call(this)\n\n this.input = token.input\n this.line = token.line\n this.file = token.file\n\n const context = mkContext(token.input, token.line)\n this.message = mkMessage(err.message, token)\n this.stack = context +\n '\\n' + (this.stack || this.message) +\n (err.stack ? '\\nFrom ' + err.stack : '')\n}\n\nexport function TokenizationError (message, token) {\n initLiquidError.call(this, {message: message}, token)\n}\nTokenizationError.prototype = Object.create(Error.prototype)\nTokenizationError.prototype.constructor = TokenizationError\n\nexport function ParseError (e, token) {\n _.assign(this, e)\n this.originalError = e\n\n initLiquidError.call(this, e, token)\n}\nParseError.prototype = Object.create(Error.prototype)\nParseError.prototype.constructor = ParseError\n\nexport function RenderError (e, tpl) {\n // return the original render error\n if (e instanceof RenderError) {\n return e\n }\n _.assign(this, e)\n this.originalError = e\n\n initLiquidError.call(this, e, tpl.token)\n}\nRenderError.prototype = Object.create(Error.prototype)\nRenderError.prototype.constructor = RenderError\n\nexport function RenderBreakError (message) {\n initError.call(this)\n this.message = message + ''\n}\nRenderBreakError.prototype = Object.create(Error.prototype)\nRenderBreakError.prototype.constructor = RenderBreakError\n\nexport function AssertionError (message) {\n initError.call(this)\n this.message = message + ''\n}\nAssertionError.prototype = Object.create(Error.prototype)\nAssertionError.prototype.constructor = AssertionError\n\nfunction mkContext (input, line) {\n const lines = input.split('\\n')\n const begin = Math.max(line - 2, 1)\n const end = Math.min(line + 3, lines.length)\n\n const context = _\n .range(begin, end + 1)\n .map(l => [\n (l === line) ? '>> ' : ' ',\n align(l, end),\n '| ',\n lines[l - 1]\n ].join(''))\n .join('\\n')\n\n return context\n}\n\nfunction align (n, max) {\n const length = (max + '').length\n const str = n + ''\n const blank = Array(length - str.length).join(' ')\n return blank + str\n}\n\nfunction mkMessage (msg, token) {\n msg = msg || ''\n if (token.file) {\n msg += ', file:' + token.file\n }\n if (token.line) {\n msg += ', line:' + token.line\n }\n return msg\n}\n","import {AssertionError} from './error.js'\n\nexport default function (predicate, message) {\n if (!predicate) {\n message = message || `expect ${predicate} to be true`\n throw new AssertionError(message)\n }\n}\n","import * as _ from './util/underscore.js'\nimport * as lexical from './lexical.js'\nimport assert from './util/assert.js'\n\nconst Scope = {\n getAll: function () {\n return this.contexts.reduce((ctx, val) => Object.assign(ctx, val), Object.create(null))\n },\n get: function (path) {\n const paths = this.propertyAccessSeq(path)\n const scope = this.findContextFor(paths[0]) || _.last(this.contexts)\n return paths.reduce((value, key) => this.readProperty(value, key), scope)\n },\n set: function (path, v) {\n const paths = this.propertyAccessSeq(path)\n let scope = this.findContextFor(paths[0]) || _.last(this.contexts)\n paths.some((key, i) => {\n if (!_.isObject(scope)) {\n return true\n }\n if (i === paths.length - 1) {\n scope[key] = v\n return true\n }\n if (undefined === scope[key]) {\n scope[key] = {}\n }\n scope = scope[key]\n })\n },\n unshift: function (ctx) {\n return this.contexts.unshift(ctx)\n },\n push: function (ctx) {\n return this.contexts.push(ctx)\n },\n pop: function (ctx) {\n if (!arguments.length) {\n return this.contexts.pop()\n }\n const i = this.contexts.findIndex(scope => scope === ctx)\n if (i === -1) {\n throw new TypeError('scope not found, cannot pop')\n }\n return this.contexts.splice(i, 1)[0]\n },\n findContextFor: function (key, filter) {\n filter = filter || (() => true)\n for (let i = this.contexts.length - 1; i >= 0; i--) {\n const candidate = this.contexts[i]\n if (!filter(candidate)) continue\n if (key in candidate) {\n return candidate\n }\n }\n return null\n },\n readProperty: function (obj, key) {\n let val\n if (_.isNil(obj)) {\n val = undefined\n } else {\n if (typeof obj.to_liquid === 'function') {\n obj = obj.to_liquid()\n } else if (typeof obj.toLiquid === 'function') {\n obj = obj.toLiquid()\n }\n\n if (key === 'size' && (_.isArray(obj) || _.isString(obj))) {\n val = obj.length\n } else {\n val = obj[key]\n }\n }\n if (_.isNil(val) && this.opts.strict_variables) {\n throw new TypeError(`undefined variable: ${key}`)\n }\n return val\n },\n\n /*\n * Parse property access sequence from access string\n * @example\n * accessSeq(\"foo.bar\") // ['foo', 'bar']\n * accessSeq(\"foo['bar']\") // ['foo', 'bar']\n * accessSeq(\"foo['b]r']\") // ['foo', 'b]r']\n * accessSeq(\"foo[bar.coo]\") // ['foo', 'bar'], for bar.coo == 'bar'\n */\n propertyAccessSeq: function (str) {\n str = String(str)\n const seq = []\n let name = ''\n let j\n let i = 0\n while (i < str.length) {\n switch (str[i]) {\n case '[':\n push()\n\n const delemiter = str[i + 1]\n if (/['\"]/.test(delemiter)) { // foo[\"bar\"]\n j = str.indexOf(delemiter, i + 2)\n assert(j !== -1, `unbalanced ${delemiter}: ${str}`)\n name = str.slice(i + 2, j)\n push()\n i = j + 2\n } else { // foo[bar.coo]\n j = matchRightBracket(str, i + 1)\n assert(j !== -1, `unbalanced []: ${str}`)\n name = str.slice(i + 1, j)\n if (!lexical.isInteger(name)) { // foo[bar] vs. foo[1]\n name = this.get(name)\n }\n push()\n i = j + 1\n }\n break\n case '.':// foo.bar, foo[0].bar\n push()\n i++\n break\n default:// foo.bar\n name += str[i]\n i++\n }\n }\n push()\n\n if (!seq.length) {\n throw new TypeError(`invalid path:\"${str}\"`)\n }\n return seq\n\n function push () {\n if (name.length) seq.push(name)\n name = ''\n }\n }\n}\n\nfunction matchRightBracket (str, begin) {\n let stack = 1 // count of '[' - count of ']'\n for (let i = begin; i < str.length; i++) {\n if (str[i] === '[') {\n stack++\n }\n if (str[i] === ']') {\n stack--\n if (stack === 0) {\n return i\n }\n }\n }\n return -1\n}\n\nexport function factory (ctx, opts) {\n const defaultOptions = {\n dynamicPartials: true,\n strict_variables: false,\n strict_filters: false,\n blocks: {},\n root: []\n }\n const scope = Object.create(Scope)\n scope.opts = _.assign(defaultOptions, opts)\n scope.contexts = [ctx || {}]\n return scope\n}\n","export function get (url) {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest()\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve(xhr.responseText)\n } else {\n reject(new Error(xhr.statusText))\n }\n }\n xhr.onerror = () => {\n reject(new Error('An error occurred whilst sending the response.'))\n }\n xhr.open('GET', url)\n xhr.send()\n })\n}\n","import {assign} from './util/underscore.js'\n\nexport default function whiteSpaceCtrl (tokens, options) {\n options = assign({ greedy: true }, options)\n let inRaw = false\n\n tokens.forEach((token, i) => {\n if (shouldTrimLeft(token, inRaw, options)) {\n trimLeft(tokens[i - 1], options.greedy)\n }\n\n if (token.type === 'tag' && token.name === 'raw') inRaw = true\n if (token.type === 'tag' && token.name === 'endraw') inRaw = false\n\n if (shouldTrimRight(token, inRaw, options)) {\n trimRight(tokens[i + 1], options.greedy)\n }\n })\n}\n\nfunction shouldTrimLeft (token, inRaw, options) {\n if (inRaw) return false\n if (token.type === 'tag') return token.trim_left || options.trim_tag_left\n if (token.type === 'value') return token.trim_left || options.trim_value_left\n}\n\nfunction shouldTrimRight (token, inRaw, options) {\n if (inRaw) return false\n if (token.type === 'tag') return token.trim_right || options.trim_tag_right\n if (token.type === 'value') return token.trim_right || options.trim_value_right\n}\n\nfunction trimLeft (token, greedy) {\n if (!token || token.type !== 'html') return\n\n const rLeft = greedy ? /\\s+$/g : /[\\t\\r ]*$/g\n token.value = token.value.replace(rLeft, '')\n}\n\nfunction trimRight (token, greedy) {\n if (!token || token.type !== 'html') return\n\n const rRight = greedy ? /^\\s+/g : /^[\\t\\r ]*\\n?/g\n token.value = token.value.replace(rRight, '')\n}\n","import * as lexical from './lexical.js'\nimport {TokenizationError} from './util/error.js'\nimport * as _ from './util/underscore.js'\nimport assert from './util/assert.js'\nimport whiteSpaceCtrl from './whitespace-ctrl.js'\n\nexport {default as whiteSpaceCtrl} from './whitespace-ctrl.js'\n\nexport function parse (input, file, options) {\n assert(_.isString(input), 'illegal input')\n\n const rLiquid = /({%-?([\\s\\S]*?)-?%})|({{-?([\\s\\S]*?)-?}})/g\n let currIndent = 0\n const lineNumber = LineNumber(input)\n let lastMatchEnd = 0\n const tokens = []\n\n for (let match; (match = rLiquid.exec(input)); lastMatchEnd = rLiquid.lastIndex) {\n if (match.index > lastMatchEnd) {\n tokens.push(parseHTMLToken(lastMatchEnd, match.index))\n }\n tokens.push(match[1]\n ? parseTagToken(match[1], match[2].trim(), match.index)\n : parseValueToken(match[3], match[4].trim(), match.index))\n }\n if (input.length > lastMatchEnd) {\n tokens.push(parseHTMLToken(lastMatchEnd, input.length))\n }\n whiteSpaceCtrl(tokens, options)\n return tokens\n\n function parseTagToken (raw, value, pos) {\n const match = value.match(lexical.tagLine)\n const token = {\n type: 'tag',\n indent: currIndent,\n line: lineNumber.get(pos),\n trim_left: raw.slice(0, 3) === '{%-',\n trim_right: raw.slice(-3) === '-%}',\n raw,\n value,\n input,\n file\n }\n if (!match) {\n throw new TokenizationError(`illegal tag syntax`, token)\n }\n token.name = match[1]\n token.args = match[2]\n return token\n }\n\n function parseValueToken (raw, value, pos) {\n return {\n type: 'value',\n line: lineNumber.get(pos),\n trim_left: raw.slice(0, 3) === '{{-',\n trim_right: raw.slice(-3) === '-}}',\n raw,\n value,\n input,\n file\n }\n }\n\n function parseHTMLToken (begin, end) {\n const htmlFragment = input.slice(begin, end)\n currIndent = _.last((htmlFragment).split('\\n')).length\n\n return {\n type: 'html',\n raw: htmlFragment,\n value: htmlFragment\n }\n }\n}\n\nfunction LineNumber (html) {\n let parsedLinesCount = 0\n let lastMatchBegin = -1\n\n return {\n get: function (pos) {\n const lines = html.slice(lastMatchBegin + 1, pos).split('\\n')\n parsedLinesCount += lines.length - 1\n lastMatchBegin = pos\n return parsedLinesCount + 1\n }\n }\n}\n","import fs from 'fs'\n\nexport function readFileAsync (filepath) {\n return new Promise(function (resolve, reject) {\n fs.readFile(filepath, 'utf8', function (err, content) {\n err ? reject(err) : resolve(content)\n })\n })\n};\n\nexport function statFileAsync (path) {\n return new Promise(function (resolve, reject) {\n fs.stat(path, (err, stat) => err ? reject(err) : resolve(stat))\n })\n};\n","import {last, isArray} from './underscore'\n\nconst splitPathRe = /^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^/]+?|)(\\.[^./]*|))(?:[/]*)$/\nconst urlRe = /^(?:\\w+:)?\\/\\/([^\\s.]+\\.\\S{2}|localhost[:?\\d]*)\\S*$/\n\n// https://github.com/jinder/path/blob/master/path.js#L567\nexport function extname (path) {\n return splitPathRe.exec(path).slice(1)[3]\n}\n\n// https://www.npmjs.com/package/is-url\nexport function valid (path) {\n return urlRe.test(path)\n}\n\nexport function resolve (root, path) {\n if (isArray(root)) {\n root = root[0]\n }\n if (root && last(root) !== '/') {\n root += '/'\n }\n return resolveUrl(root, path)\n}\n\nfunction resolveUrl (root, path) {\n const base = document.createElement('base')\n base.href = arguments[0]\n\n const head = document.getElementsByTagName('head')[0]\n head.insertBefore(base, head.firstChild)\n\n const a = document.createElement('a')\n a.href = path\n const resolved = a.href\n base.href = resolved\n\n head.removeChild(base)\n\n return resolved\n}\n","export default function (isTruthy) {\n return {\n '==': (l, r) => l === r,\n '!=': (l, r) => l !== r,\n '>': (l, r) => l !== null && r !== null && l > r,\n '<': (l, r) => l !== null && r !== null && l < r,\n '>=': (l, r) => l !== null && r !== null && l >= r,\n '<=': (l, r) => l !== null && r !== null && l <= r,\n 'contains': (l, r) => {\n if (!l) return false\n if (typeof l.indexOf !== 'function') return false\n return l.indexOf(r) > -1\n },\n 'and': (l, r) => isTruthy(l) && isTruthy(r),\n 'or': (l, r) => isTruthy(l) || isTruthy(r)\n }\n}\n","import Operators from './operators.js'\nimport * as lexical from './lexical.js'\nimport assert from './util/assert.js'\n\nconst operators = Operators(isTruthy)\n\nexport function evalExp (exp, scope) {\n assert(scope, 'unable to evalExp: scope undefined')\n const operatorREs = lexical.operators\n let match\n for (let i = 0; i < operatorREs.length; i++) {\n const operatorRE = operatorREs[i]\n const expRE = new RegExp(`^(${lexical.quoteBalanced.source})(${operatorRE.source})(${lexical.quoteBalanced.source})$`)\n if ((match = exp.match(expRE))) {\n const l = evalExp(match[1], scope)\n const op = operators[match[2].trim()]\n const r = evalExp(match[3], scope)\n return op(l, r)\n }\n }\n\n if ((match = exp.match(lexical.rangeLine))) {\n const low = evalValue(match[1], scope)\n const high = evalValue(match[2], scope)\n const range = []\n for (let j = low; j <= high; j++) {\n range.push(j)\n }\n return range\n }\n\n return evalValue(exp, scope)\n}\n\nexport function evalValue (str, scope) {\n str = str && str.trim()\n if (!str) return undefined\n\n if (lexical.isLiteral(str)) {\n return lexical.parseLiteral(str)\n }\n if (lexical.isVariable(str)) {\n return scope.get(str)\n }\n throw new TypeError(`cannot eval '${str}' as value`)\n}\n\nexport function isTruthy (val) {\n return !isFalsy(val)\n}\n\nexport function isFalsy (val) {\n return val === false || undefined === val || val === null\n}\n","import {evalExp} from './syntax.js'\nimport {RenderBreakError, RenderError} from './util/error.js'\nimport {stringify} from './util/underscore.js'\nimport assert from './util/assert.js'\n\nconst render = {\n renderTemplates: async function (templates, scope) {\n assert(scope, 'unable to evalTemplates: scope undefined')\n\n let html = ''\n for (const tpl of templates) {\n try {\n html += await renderTemplate.call(this, tpl)\n } catch (e) {\n if (e instanceof RenderBreakError) {\n e.resolvedHTML = html\n throw e\n }\n throw new RenderError(e, tpl)\n }\n }\n return html\n\n async function renderTemplate (template) {\n if (template.type === 'tag') {\n const partial = await this.renderTag(template, scope)\n return partial === undefined ? '' : partial\n }\n if (template.type === 'value') {\n return this.renderValue(template, scope)\n }\n return template.value\n }\n },\n\n renderTag: async function (template, scope) {\n if (template.name === 'continue') {\n throw new RenderBreakError('continue')\n }\n if (template.name === 'break') {\n throw new RenderBreakError('break')\n }\n return template.render(scope)\n },\n\n renderValue: async function (template, scope) {\n const partial = this.evalValue(template, scope)\n return partial === undefined ? '' : stringify(partial)\n },\n\n evalValue: function (template, scope) {\n assert(scope, 'unable to evalValue: scope undefined')\n return template.filters.reduce(\n (prev, filter) => filter.render(prev, scope),\n evalExp(template.initial, scope))\n }\n}\n\nexport default function () {\n const instance = Object.create(render)\n return instance\n}\n","import {hashCapture} from './lexical.js'\nimport {evalValue} from './syntax.js'\nimport assert from './util/assert.js'\n\nfunction hash (markup, scope) {\n const obj = {}\n let match\n hashCapture.lastIndex = 0\n while ((match = hashCapture.exec(markup))) {\n const k = match[1]\n const v = match[2]\n obj[k] = evalValue(v, scope)\n }\n return obj\n}\n\nexport default function () {\n let tagImpls = {}\n\n const _tagInstance = {\n render: async function (scope) {\n const obj = hash(this.token.args, scope)\n const impl = this.tagImpl\n if (typeof impl.render !== 'function') {\n return ''\n }\n return impl.render(scope, obj)\n },\n parse: function (token, tokens) {\n this.type = 'tag'\n this.token = token\n this.name = token.name\n\n const tagImpl = tagImpls[this.name]\n assert(tagImpl, `tag ${this.name} not found`)\n this.tagImpl = Object.create(tagImpl)\n if (this.tagImpl.parse) {\n this.tagImpl.parse(token, tokens)\n }\n }\n }\n\n function register (name, tag) {\n tagImpls[name] = tag\n }\n\n function construct (token, tokens) {\n const instance = Object.create(_tagInstance)\n instance.parse(token, tokens)\n return instance\n }\n\n function clear () {\n tagImpls = {}\n }\n\n return {\n construct,\n register,\n clear\n }\n}\n","import * as lexical from './lexical.js'\nimport {evalValue} from './syntax.js'\nimport assert from './util/assert.js'\nimport {assign} from './util/underscore.js'\n\nconst valueRE = new RegExp(`${lexical.value.source}`, 'g')\n\nexport default function (options) {\n options = assign({}, options)\n let filters = {}\n\n const _filterInstance = {\n render: function (output, scope) {\n const args = this.args.map(arg => evalValue(arg, scope))\n args.unshift(output)\n return this.filter.apply(null, args)\n },\n parse: function (str) {\n let match = lexical.filterLine.exec(str)\n assert(match, 'illegal filter: ' + str)\n\n const name = match[1]\n const argList = match[2] || ''\n const filter = filters[name]\n if (typeof filter !== 'function') {\n if (options.strict_filters) {\n throw new TypeError(`undefined filter: ${name}`)\n }\n this.name = name\n this.filter = x => x\n this.args = []\n return this\n }\n\n const args = []\n while ((match = valueRE.exec(argList.trim()))) {\n const v = match[0]\n const re = new RegExp(`${v}\\\\s*:`, 'g')\n const keyMatch = re.exec(match.input)\n const currentMatchIsKey = keyMatch && keyMatch.index === match.index\n currentMatchIsKey ? args.push(`'${v}'`) : args.push(v)\n }\n\n this.name = name\n this.filter = filter\n this.args = args\n\n return this\n }\n }\n\n function construct (str) {\n const instance = Object.create(_filterInstance)\n return instance.parse(str)\n }\n\n function register (name, filter) {\n filters[name] = filter\n }\n\n function clear () {\n filters = {}\n }\n\n return {\n construct, register, clear\n }\n}\n","import * as lexical from './lexical.js'\nimport {ParseError} from './util/error.js'\nimport assert from './util/assert.js'\n\nexport default function (Tag, Filter) {\n const stream = {\n init: function (tokens) {\n this.tokens = tokens\n this.handlers = {}\n return this\n },\n on: function (name, cb) {\n this.handlers[name] = cb\n return this\n },\n trigger: function (event, arg) {\n const h = this.handlers[event]\n if (typeof h === 'function') {\n h(arg)\n return true\n }\n },\n start: function () {\n this.trigger('start')\n let token\n while (!this.stopRequested && (token = this.tokens.shift())) {\n if (this.trigger('token', token)) continue\n if (token.type === 'tag' &&\n this.trigger(`tag:${token.name}`, token)) {\n continue\n }\n const template = parseToken(token, this.tokens)\n this.trigger('template', template)\n }\n if (!this.stopRequested) this.trigger('end')\n return this\n },\n stop: function () {\n this.stopRequested = true\n return this\n }\n }\n\n function parse (tokens) {\n let token\n const templates = []\n while ((token = tokens.shift())) {\n templates.push(parseToken(token, tokens))\n }\n return templates\n }\n\n function parseToken (token, tokens) {\n try {\n let tpl = null\n if (token.type === 'tag') {\n tpl = parseTag(token, tokens)\n } else if (token.type === 'value') {\n tpl = parseValue(token.value)\n } else { // token.type === 'html'\n tpl = token\n }\n tpl.token = token\n return tpl\n } catch (e) {\n throw new ParseError(e, token)\n }\n }\n\n function parseTag (token, tokens) {\n if (token.name === 'continue' || token.name === 'break') return token\n return Tag.construct(token, tokens)\n }\n\n function parseValue (str) {\n let match = lexical.matchValue(str)\n assert(match, `illegal value string: ${str}`)\n\n const initial = match[0]\n str = str.substr(match.index + match[0].length)\n\n const filters = []\n while ((match = lexical.filter.exec(str))) {\n filters.push([match[0].trim()])\n }\n\n return {\n type: 'value',\n initial: initial,\n filters: filters.map(str => Filter.construct(str))\n }\n }\n\n function parseStream (tokens) {\n const s = Object.create(stream)\n return s.init(tokens)\n }\n\n return {\n parse,\n parseTag,\n parseStream,\n parseValue\n }\n}\n","/*\n * Call functions in serial until someone resolved.\n * @param {Array} iterable the array to iterate with.\n * @param {Array} iteratee returns a new promise.\n * The iteratee is invoked with three arguments: (value, index, iterable).\n */\nexport function anySeries (iterable, iteratee) {\n let ret = Promise.reject(new Error('init'))\n iterable.forEach(function (item, idx) {\n ret = ret.catch(e => iteratee(item, idx, iterable))\n })\n return ret\n}\n\n/*\n * Call functions in serial until someone rejected.\n * @param {Array} iterable the array to iterate with.\n * @param {Array} iteratee returns a new promise.\n * The iteratee is invoked with three arguments: (value, index, iterable).\n */\nexport function mapSeries (iterable, iteratee) {\n let ret = Promise.resolve('init')\n const result = []\n iterable.forEach(function (item, idx) {\n ret = ret\n .then(() => iteratee(item, idx, iterable))\n .then(x => result.push(x))\n })\n return ret.then(() => result)\n}\n","import {mapSeries} from '../util/promise.js'\nimport {isString, isObject} from '../util/underscore.js'\nimport assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const RenderBreakError = Liquid.Types.RenderBreakError\n const lexical = Liquid.lexical\n const re = new RegExp(`^(${lexical.identifier.source})\\\\s+in\\\\s+` +\n `(${lexical.value.source})` +\n `(?:\\\\s+${lexical.hash.source})*` +\n `(?:\\\\s+(reversed))?` +\n `(?:\\\\s+${lexical.hash.source})*$`)\n\n liquid.registerTag('for', {parse, render})\n\n function parse (tagToken, remainTokens) {\n const match = re.exec(tagToken.args)\n assert(match, `illegal tag: ${tagToken.raw}`)\n this.variable = match[1]\n this.collection = match[2]\n this.reversed = !!match[3]\n\n this.templates = []\n this.elseTemplates = []\n\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', () => (p = this.templates))\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endfor', () => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', () => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n }\n async function render (scope, hash) {\n let collection = Liquid.evalExp(this.collection, scope)\n\n if (!Array.isArray(collection)) {\n if (isString(collection) && collection.length > 0) {\n collection = [collection]\n } else if (isObject(collection)) {\n collection = Object.keys(collection).map((key) => [key, collection[key]])\n }\n }\n if (!Array.isArray(collection) || !collection.length) {\n return liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n\n const offset = hash.offset || 0\n const limit = (hash.limit === undefined) ? collection.length : hash.limit\n\n collection = collection.slice(offset, offset + limit)\n if (this.reversed) collection.reverse()\n\n const contexts = collection.map((item, i) => {\n const ctx = {}\n ctx[this.variable] = item\n ctx.forloop = {\n first: i === 0,\n index: i + 1,\n index0: i,\n last: i === collection.length - 1,\n length: collection.length,\n rindex: collection.length - i,\n rindex0: collection.length - i - 1\n }\n return ctx\n })\n\n let html = ''\n let finished = false\n await mapSeries(contexts, async context => {\n if (finished) return\n\n scope.push(context)\n try {\n html += await liquid.renderer.renderTemplates(this.templates, scope)\n } catch (e) {\n if (e instanceof RenderBreakError) {\n html += e.resolvedHTML\n if (e.message === 'break') {\n finished = true\n }\n } else throw e\n }\n scope.pop(context)\n })\n return html\n }\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const rIdentifier = Liquid.lexical.identifier\n const re = new RegExp(`(${rIdentifier.source})\\\\s*=(.*)`)\n const {AssignScope} = Liquid.Types\n\n liquid.registerTag('assign', {\n parse: function (token) {\n const match = token.args.match(re)\n assert(match, `illegal token ${token.raw}`)\n this.key = match[1]\n this.value = match[2]\n },\n render: function (scope) {\n const ctx = Object.create(AssignScope)\n ctx[this.key] = liquid.evalValue(this.value, scope)\n scope.push(ctx)\n return Promise.resolve('')\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const rIdentifier = Liquid.lexical.identifier\n const re = new RegExp(`(${rIdentifier.source})`)\n const {CaptureScope} = Liquid.Types\n\n liquid.registerTag('capture', {\n parse: function (tagToken, remainTokens) {\n const match = tagToken.args.match(re)\n assert(match, `${tagToken.args} not valid identifier`)\n\n this.variable = match[1]\n this.templates = []\n\n const stream = liquid.parser.parseStream(remainTokens)\n stream.on('tag:endcapture', token => stream.stop())\n .on('template', tpl => this.templates.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n stream.start()\n },\n render: async function (scope, hash) {\n const html = await liquid.renderer.renderTemplates(this.templates, scope)\n const ctx = Object.create(CaptureScope)\n ctx[this.variable] = html\n scope.push(ctx)\n }\n })\n}\n","export default function (liquid, Liquid) {\n liquid.registerTag('case', {\n\n parse: function (tagToken, remainTokens) {\n this.cond = tagToken.args\n this.cases = []\n this.elseTemplates = []\n\n let p = []\n const stream = liquid.parser.parseStream(remainTokens)\n .on('tag:when', token => {\n this.cases.push({\n val: token.args,\n templates: p = []\n })\n })\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endcase', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: function (scope, hash) {\n for (let i = 0; i < this.cases.length; i++) {\n const branch = this.cases[i]\n const val = Liquid.evalExp(branch.val, scope)\n const cond = Liquid.evalExp(this.cond, scope)\n if (val === cond) {\n return liquid.renderer.renderTemplates(branch.templates, scope)\n }\n }\n return liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n })\n}\n","export default function (liquid) {\n liquid.registerTag('comment', {\n parse: function (tagToken, remainTokens) {\n const stream = liquid.parser.parseStream(remainTokens)\n stream\n .on('token', token => {\n if (token.name === 'endcomment') stream.stop()\n })\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n stream.start()\n }\n })\n}\n","import assert from '../util/assert.js'\n\nconst staticFileRE = /[^\\s,]+/\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const withRE = new RegExp(`with\\\\s+(${lexical.value.source})`)\n\n liquid.registerTag('include', {\n parse: function (token) {\n let match = staticFileRE.exec(token.args)\n if (match) {\n this.staticValue = match[0]\n }\n\n match = lexical.value.exec(token.args)\n if (match) {\n this.value = match[0]\n }\n\n match = withRE.exec(token.args)\n if (match) {\n this.with = match[1]\n }\n },\n render: async function (scope, hash) {\n let filepath\n if (scope.opts.dynamicPartials) {\n if (lexical.quotedLine.exec(this.value)) {\n const template = this.value.slice(1, -1)\n filepath = await liquid.parseAndRender(template, scope.getAll(), scope.opts)\n } else {\n filepath = Liquid.evalValue(this.value, scope)\n }\n } else {\n filepath = this.staticValue\n }\n assert(filepath, `cannot include with empty filename`)\n\n const originBlocks = scope.opts.blocks\n const originBlockMode = scope.opts.blockMode\n\n scope.opts.blocks = {}\n scope.opts.blockMode = 'output'\n if (this.with) {\n hash[filepath] = Liquid.evalValue(this.with, scope)\n }\n const templates = await liquid.getTemplate(filepath, scope.opts.root)\n scope.push(hash)\n const html = await liquid.renderer.renderTemplates(templates, scope)\n scope.pop(hash)\n scope.opts.blocks = originBlocks\n scope.opts.blockMode = originBlockMode\n return html\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const {CaptureScope, AssignScope, DecrementScope} = Liquid.Types\n\n liquid.registerTag('decrement', {\n parse: function (token) {\n const match = token.args.match(lexical.identifier)\n assert(match, `illegal identifier ${token.args}`)\n this.variable = match[0]\n },\n render: function (scope, hash) {\n let context = scope.findContextFor(\n this.variable,\n ctx => {\n return Object.getPrototypeOf(ctx) !== CaptureScope &&\n Object.getPrototypeOf(ctx) !== AssignScope\n }\n )\n if (!context) {\n context = Object.create(DecrementScope)\n scope.unshift(context)\n }\n if (typeof context[this.variable] !== 'number') {\n context[this.variable] = 0\n }\n return --context[this.variable]\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const rValue = Liquid.lexical.value\n const groupRE = new RegExp(`^(?:(${rValue.source})\\\\s*:\\\\s*)?(.*)$`)\n const candidatesRE = new RegExp(rValue.source, 'g')\n\n liquid.registerTag('cycle', {\n\n parse: function (tagToken, remainTokens) {\n let match = groupRE.exec(tagToken.args)\n assert(match, `illegal tag: ${tagToken.raw}`)\n\n this.group = match[1] || ''\n const candidates = match[2]\n\n this.candidates = []\n\n while ((match = candidatesRE.exec(candidates))) {\n this.candidates.push(match[0])\n }\n assert(this.candidates.length, `empty candidates: ${tagToken.raw}`)\n },\n\n render: function (scope, hash) {\n const group = Liquid.evalValue(this.group, scope)\n const fingerprint = `cycle:${group}:` + this.candidates.join(',')\n\n const groups = scope.opts.groups = scope.opts.groups || {}\n let idx = groups[fingerprint]\n\n if (idx === undefined) {\n idx = groups[fingerprint] = 0\n }\n\n const candidate = this.candidates[idx]\n idx = (idx + 1) % this.candidates.length\n groups[fingerprint] = idx\n\n return Liquid.evalValue(candidate, scope)\n }\n })\n}\n","export default function (liquid, Liquid) {\n liquid.registerTag('if', {\n\n parse: function (tagToken, remainTokens) {\n this.branches = []\n this.elseTemplates = []\n\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', () => this.branches.push({\n cond: tagToken.args,\n templates: (p = [])\n }))\n .on('tag:elsif', token => {\n this.branches.push({\n cond: token.args,\n templates: p = []\n })\n })\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endif', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: function (scope, hash) {\n for (const branch of this.branches) {\n const cond = Liquid.evalExp(branch.cond, scope)\n if (Liquid.isTruthy(cond)) {\n return liquid.renderer.renderTemplates(branch.templates, scope)\n }\n }\n return liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const {CaptureScope, AssignScope, IncrementScope} = Liquid.Types\n\n liquid.registerTag('increment', {\n parse: function (token) {\n const match = token.args.match(lexical.identifier)\n assert(match, `illegal identifier ${token.args}`)\n this.variable = match[0]\n },\n render: function (scope, hash) {\n let context = scope.findContextFor(\n this.variable,\n ctx => {\n return Object.getPrototypeOf(ctx) !== CaptureScope &&\n Object.getPrototypeOf(ctx) !== AssignScope\n }\n )\n if (!context) {\n context = Object.create(IncrementScope)\n scope.unshift(context)\n }\n if (typeof context[this.variable] !== 'number') {\n context[this.variable] = 0\n }\n const val = context[this.variable]\n context[this.variable]++\n return val\n }\n })\n}\n","import assert from '../util/assert.js'\n\n/*\n * blockMode:\n * * \"store\": store rendered html into blocks\n * * \"output\": output rendered html\n */\n\nexport default function (liquid, Liquid) {\n const rValue = Liquid.lexical.value\n const staticFileRE = /\\S+/\n\n liquid.registerTag('layout', {\n parse: function (token, remainTokens) {\n let match = staticFileRE.exec(token.args)\n if (match) {\n this.staticLayout = match[0]\n }\n\n match = rValue.exec(token.args)\n if (match) {\n this.layout = match[0]\n }\n\n this.tpls = liquid.parser.parse(remainTokens)\n },\n render: async function (scope, hash) {\n const layout = scope.opts.dynamicPartials\n ? Liquid.evalValue(this.layout, scope)\n : this.staticLayout\n assert(layout, `cannot apply layout with empty filename`)\n\n // render the remaining tokens immediately\n scope.opts.blockMode = 'store'\n const html = await liquid.renderer.renderTemplates(this.tpls, scope)\n if (scope.opts.blocks[''] === undefined) {\n scope.opts.blocks[''] = html\n }\n const templates = await liquid.getTemplate(layout, scope.opts.root)\n scope.push(hash)\n scope.opts.blockMode = 'output'\n const partial = await liquid.renderer.renderTemplates(templates, scope)\n scope.pop(hash)\n return partial\n }\n })\n\n liquid.registerTag('block', {\n parse: function (token, remainTokens) {\n const match = /\\w+/.exec(token.args)\n this.block = match ? match[0] : ''\n\n this.tpls = []\n const stream = liquid.parser.parseStream(remainTokens)\n .on('tag:endblock', () => stream.stop())\n .on('template', tpl => this.tpls.push(tpl))\n .on('end', () => {\n throw new Error(`tag ${token.raw} not closed`)\n })\n stream.start()\n },\n render: async function (scope) {\n const childDefined = scope.opts.blocks[this.block]\n const html = childDefined !== undefined\n ? childDefined\n : await liquid.renderer.renderTemplates(this.tpls, scope)\n\n if (scope.opts.blockMode === 'store') {\n scope.opts.blocks[this.block] = html\n return ''\n }\n return html\n }\n })\n}\n","export default function (liquid) {\n liquid.registerTag('raw', {\n parse: function (tagToken, remainTokens) {\n this.tokens = []\n\n const stream = liquid.parser.parseStream(remainTokens)\n stream\n .on('token', token => {\n if (token.name === 'endraw') stream.stop()\n else this.tokens.push(token)\n })\n .on('end', () => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n stream.start()\n },\n render: function (scope, hash) {\n return this.tokens.map(token => token.raw).join('')\n }\n })\n}\n","import {mapSeries} from '../util/promise.js'\nimport assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const re = new RegExp(`^(${lexical.identifier.source})\\\\s+in\\\\s+` +\n `(${lexical.value.source})` +\n `(?:\\\\s+${lexical.hash.source})*$`)\n\n liquid.registerTag('tablerow', {\n\n parse: function (tagToken, remainTokens) {\n const match = re.exec(tagToken.args)\n assert(match, `illegal tag: ${tagToken.raw}`)\n\n this.variable = match[1]\n this.collection = match[2]\n this.templates = []\n\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', () => (p = this.templates))\n .on('tag:endtablerow', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', () => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: async function (scope, hash) {\n let collection = Liquid.evalExp(this.collection, scope) || []\n const offset = hash.offset || 0\n const limit = (hash.limit === undefined) ? collection.length : hash.limit\n\n collection = collection.slice(offset, offset + limit)\n const cols = hash.cols || collection.length\n const contexts = collection.map((item, i) => {\n const ctx = {}\n ctx[this.variable] = item\n return ctx\n })\n\n let row\n let html = ''\n await mapSeries(contexts, async (context, idx) => {\n row = Math.floor(idx / cols) + 1\n const col = (idx % cols) + 1\n if (col === 1) {\n if (row !== 1) {\n html += ''\n }\n html += ``\n }\n\n html += ``\n scope.push(context)\n html += await liquid.renderer.renderTemplates(this.templates, scope)\n html += ''\n scope.pop(context)\n return html\n })\n if (row > 0) {\n html += ''\n }\n return html\n }\n })\n}\n","export default function (liquid, Liquid) {\n liquid.registerTag('unless', {\n parse: function (tagToken, remainTokens) {\n this.templates = []\n this.elseTemplates = []\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', x => {\n p = this.templates\n this.cond = tagToken.args\n })\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endunless', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: function (scope, hash) {\n const cond = Liquid.evalExp(this.cond, scope)\n return Liquid.isFalsy(cond)\n ? liquid.renderer.renderTemplates(this.templates, scope)\n : liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n })\n}\n","import For from './for.js'\nimport Assign from './assign.js'\nimport Capture from './capture.js'\nimport Case from './case.js'\nimport Comment from './comment.js'\nimport Include from './include.js'\nimport Decrement from './decrement.js'\nimport Cycle from './cycle.js'\nimport If from './if.js'\nimport Increment from './increment.js'\nimport Layout from './layout.js'\nimport Raw from './raw.js'\nimport Tablerow from './tablerow.js'\nimport Unless from './unless.js'\n\nexport default function (engine, Liquid) {\n Assign(engine, Liquid)\n Capture(engine, Liquid)\n Case(engine, Liquid)\n Comment(engine, Liquid)\n Cycle(engine, Liquid)\n Decrement(engine, Liquid)\n For(engine, Liquid)\n If(engine, Liquid)\n Include(engine, Liquid)\n Increment(engine, Liquid)\n Layout(engine, Liquid)\n Raw(engine, Liquid)\n Tablerow(engine, Liquid)\n Unless(engine, Liquid)\n}\n","const monthNames = [\n 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',\n 'September', 'October', 'November', 'December'\n]\nconst monthNamesShort = [\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',\n 'Nov', 'Dec'\n]\nconst dayNames = [\n 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'\n]\nconst dayNamesShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']\nconst suffixes = {\n 1: 'st',\n 2: 'nd',\n 3: 'rd',\n 'default': 'th'\n}\n\n// prototype extensions\nconst _date = {\n daysInMonth: function (d) {\n const feb = _date.isLeapYear(d) ? 29 : 28\n return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\n },\n\n getDayOfYear: function (d) {\n let num = 0\n for (let i = 0; i < d.getMonth(); ++i) {\n num += _date.daysInMonth(d)[i]\n }\n return num + d.getDate()\n },\n\n // Startday is an integer of which day to start the week measuring from\n // TODO: that comment was retarted. fix it.\n getWeekOfYear: function (d, startDay) {\n // Skip to startDay of this week\n const now = this.getDayOfYear(d) + (startDay - d.getDay())\n // Find the first startDay of the year\n const jan1 = new Date(d.getFullYear(), 0, 1)\n const then = (7 - jan1.getDay() + startDay)\n return _number.pad(Math.floor((now - then) / 7) + 1, 2)\n },\n\n isLeapYear: function (d) {\n const year = d.getFullYear()\n return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)))\n },\n\n getSuffix: function (d) {\n const str = d.getDate().toString()\n const index = parseInt(str.slice(-1))\n return suffixes[index] || suffixes['default']\n },\n\n century: function (d) {\n return parseInt(d.getFullYear().toString().substring(0, 2), 10)\n }\n}\n\nconst _number = {\n pad: function (value, size, ch) {\n if (!ch) ch = '0'\n let result = value.toString()\n let pad = size - result.length\n\n while (pad-- > 0) {\n result = ch + result\n }\n\n return result\n }\n}\n\nconst formatCodes = {\n a: function (d) {\n return dayNamesShort[d.getDay()]\n },\n A: function (d) {\n return dayNames[d.getDay()]\n },\n b: function (d) {\n return monthNamesShort[d.getMonth()]\n },\n B: function (d) {\n return monthNames[d.getMonth()]\n },\n c: function (d) {\n return d.toLocaleString()\n },\n C: function (d) {\n return _date.century(d)\n },\n d: function (d) {\n return _number.pad(d.getDate(), 2)\n },\n e: function (d) {\n return _number.pad(d.getDate(), 2, ' ')\n },\n H: function (d) {\n return _number.pad(d.getHours(), 2)\n },\n I: function (d) {\n return _number.pad(d.getHours() % 12 || 12, 2)\n },\n j: function (d) {\n return _number.pad(_date.getDayOfYear(d), 3)\n },\n k: function (d) {\n return _number.pad(d.getHours(), 2, ' ')\n },\n l: function (d) {\n return _number.pad(d.getHours() % 12 || 12, 2, ' ')\n },\n L: function (d) {\n return _number.pad(d.getMilliseconds(), 3)\n },\n m: function (d) {\n return _number.pad(d.getMonth() + 1, 2)\n },\n M: function (d) {\n return _number.pad(d.getMinutes(), 2)\n },\n p: function (d) {\n return (d.getHours() < 12 ? 'AM' : 'PM')\n },\n P: function (d) {\n return (d.getHours() < 12 ? 'am' : 'pm')\n },\n q: function (d) {\n return _date.getSuffix(d)\n },\n s: function (d) {\n return Math.round(d.valueOf() / 1000)\n },\n S: function (d) {\n return _number.pad(d.getSeconds(), 2)\n },\n u: function (d) {\n return d.getDay() || 7\n },\n U: function (d) {\n return _date.getWeekOfYear(d, 0)\n },\n w: function (d) {\n return d.getDay()\n },\n W: function (d) {\n return _date.getWeekOfYear(d, 1)\n },\n x: function (d) {\n return d.toLocaleDateString()\n },\n X: function (d) {\n return d.toLocaleTimeString()\n },\n y: function (d) {\n return d.getFullYear().toString().substring(2, 4)\n },\n Y: function (d) {\n return d.getFullYear()\n },\n z: function (d) {\n const tz = d.getTimezoneOffset() / 60 * 100\n return (tz > 0 ? '-' : '+') + _number.pad(Math.abs(tz), 4)\n },\n '%': function () {\n return '%'\n }\n}\nformatCodes.h = formatCodes.b\nformatCodes.N = formatCodes.L\n\nexport default function (d, format) {\n let output = ''\n let remaining = format\n\n while (true) {\n const r = /%./g\n const results = r.exec(remaining)\n\n // No more format codes. Add the remaining text and return\n if (!results) {\n return output + remaining\n }\n\n // Add the preceding text\n output += remaining.slice(0, r.lastIndex - 2)\n remaining = remaining.slice(r.lastIndex)\n\n // Add the format code\n const ch = results[0].charAt(1)\n const func = formatCodes[ch]\n output += func ? func.call(this, d) : '%' + ch\n }\n}\n","import strftime from './util/strftime.js'\nimport * as _ from './util/underscore.js'\nimport {isTruthy} from './syntax.js'\n\nconst escapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n}\nconst unescapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\"\n}\n\nconst filters = {\n 'abs': v => Math.abs(v),\n 'append': (v, arg) => v + arg,\n 'capitalize': str => stringify(str).charAt(0).toUpperCase() + str.slice(1),\n 'ceil': v => Math.ceil(v),\n 'concat': (v, arg) => Array.prototype.concat.call(v, arg),\n 'date': (v, arg) => {\n let date = v\n if (v === 'now') {\n date = new Date()\n } else if (_.isString(v)) {\n date = new Date(v)\n }\n return isValidDate(date) ? strftime(date, arg) : v\n },\n 'default': (v, arg) => isTruthy(v) ? v : arg,\n 'divided_by': (v, arg) => v / arg,\n 'downcase': v => v.toLowerCase(),\n 'escape': escape,\n\n 'escape_once': str => escape(unescape(str)),\n 'first': v => v[0],\n 'floor': v => Math.floor(v),\n 'join': (v, arg) => v.join(arg),\n 'last': v => _.last(v),\n 'lstrip': v => stringify(v).replace(/^\\s+/, ''),\n 'map': (arr, arg) => arr.map(v => v[arg]),\n 'minus': bindFixed((v, arg) => v - arg),\n 'modulo': bindFixed((v, arg) => v % arg),\n 'newline_to_br': v => v.replace(/\\n/g, '
'),\n 'plus': bindFixed((v, arg) => Number(v) + Number(arg)),\n 'prepend': (v, arg) => arg + v,\n 'remove': (v, arg) => v.split(arg).join(''),\n 'remove_first': (v, l) => v.replace(l, ''),\n 'replace': (v, pattern, replacement) =>\n stringify(v).split(pattern).join(replacement),\n 'replace_first': (v, arg1, arg2) => stringify(v).replace(arg1, arg2),\n 'reverse': v => v.reverse(),\n 'round': (v, arg) => {\n const amp = Math.pow(10, arg || 0)\n return Math.round(v * amp, arg) / amp\n },\n 'rstrip': str => stringify(str).replace(/\\s+$/, ''),\n 'size': v => v.length,\n 'slice': (v, begin, length) =>\n v.substr(begin, length === undefined ? 1 : length),\n 'sort': (v, arg) => v.sort(arg),\n 'split': (v, arg) => stringify(v).split(arg),\n 'strip': (v) => stringify(v).trim(),\n 'strip_html': v => stringify(v).replace(/|||<.*?>/g, ''),\n 'strip_newlines': v => stringify(v).replace(/\\n/g, ''),\n 'times': (v, arg) => v * arg,\n 'truncate': (v, l, o) => {\n v = stringify(v)\n o = (o === undefined) ? '...' : o\n l = l || 16\n if (v.length <= l) return v\n return v.substr(0, l - o.length) + o\n },\n 'truncatewords': (v, l, o) => {\n if (o === undefined) o = '...'\n const arr = v.split(' ')\n let ret = arr.slice(0, l).join(' ')\n if (arr.length > l) ret += o\n return ret\n },\n 'uniq': function (arr) {\n const u = {}\n return (arr || []).filter(val => {\n if (u.hasOwnProperty(val)) {\n return false\n }\n u[val] = true\n return true\n })\n },\n 'upcase': str => stringify(str).toUpperCase(),\n 'url_encode': encodeURIComponent\n}\n\nfunction escape (str) {\n return stringify(str).replace(/&|<|>|\"|'/g, m => escapeMap[m])\n}\n\nfunction unescape (str) {\n return stringify(str).replace(/&(amp|lt|gt|#34|#39);/g, m => unescapeMap[m])\n}\n\nfunction getFixed (v) {\n const p = (v + '').split('.')\n return (p.length > 1) ? p[1].length : 0\n}\n\nfunction getMaxFixed (l, r) {\n return Math.max(getFixed(l), getFixed(r))\n}\n\nfunction stringify (obj) {\n return obj + ''\n}\n\nfunction bindFixed (cb) {\n return (l, r) => {\n const f = getMaxFixed(l, r)\n return cb(l, r).toFixed(f)\n }\n}\n\nfunction isValidDate (date) {\n return date instanceof Date && !isNaN(date.getTime())\n}\n\nexport default function registerAll (liquid) {\n return _.forOwn(filters, (func, name) => liquid.registerFilter(name, func))\n}\n\nregisterAll.filters = filters\n","import 'regenerator-runtime/runtime'\nimport * as Scope from './scope'\nimport {get as httpGet} from './util/http.js'\nimport * as _ from './util/underscore.js'\nimport assert from './util/assert.js'\nimport * as tokenizer from './tokenizer.js'\nimport {statFileAsync, readFileAsync} from './util/fs.js'\nimport path from 'path'\nimport {valid as isValidUrl, extname, resolve} from './util/url.js'\nimport * as lexical from './lexical.js'\nimport Render from './render.js'\nimport Tag from './tag.js'\nimport Filter from './filter.js'\nimport Parser from './parser'\nimport {isTruthy, isFalsy, evalExp, evalValue} from './syntax.js'\nimport {anySeries} from './util/promise.js'\nimport {ParseError, TokenizationError, RenderBreakError, AssertionError} from './util/error.js'\nimport tags from './tags/index.js'\nimport filters from './filters.js'\n\nconst _engine = {\n init: function (tag, filter, options) {\n if (options.cache) {\n this.cache = {}\n }\n this.options = options\n this.tag = tag\n this.filter = filter\n this.parser = Parser(tag, filter)\n this.renderer = Render()\n\n tags(this, Liquid)\n filters(this, Liquid)\n\n return this\n },\n parse: function (html, filepath) {\n const tokens = tokenizer.parse(html, filepath, this.options)\n return this.parser.parse(tokens)\n },\n render: function (tpl, ctx, opts) {\n opts = _.assign({}, this.options, opts)\n const scope = Scope.factory(ctx, opts)\n return this.renderer.renderTemplates(tpl, scope)\n },\n parseAndRender: async function (html, ctx, opts) {\n const tpl = await this.parse(html)\n return this.render(tpl, ctx, opts)\n },\n renderFile: async function (filepath, ctx, opts) {\n opts = _.assign({}, opts)\n const templates = await this.getTemplate(filepath, opts.root)\n return this.render(templates, ctx, opts)\n },\n evalValue: function (str, scope) {\n const tpl = this.parser.parseValue(str.trim())\n return this.renderer.evalValue(tpl, scope)\n },\n registerFilter: function (name, filter) {\n return this.filter.register(name, filter)\n },\n registerTag: function (name, tag) {\n return this.tag.register(name, tag)\n },\n lookup: function (filepath, root) {\n root = this.options.root.concat(root || [])\n root = _.uniq(root)\n const paths = root.map(root => path.resolve(root, filepath))\n return anySeries(paths, async path => {\n try {\n await statFileAsync(path)\n return path\n } catch (e) {\n e.message = `${e.code}: Failed to lookup ${filepath} in: ${root}`\n throw e\n }\n })\n },\n getTemplate: function (filepath, root) {\n return typeof XMLHttpRequest === 'undefined'\n ? this.getTemplateFromFile(filepath, root)\n : this.getTemplateFromUrl(filepath, root)\n },\n getTemplateFromFile: async function (filepath, root) {\n if (!path.extname(filepath)) {\n filepath += this.options.extname\n }\n filepath = await this.lookup(filepath, root)\n return this.respectCache(filepath, async () => {\n const str = await readFileAsync(filepath)\n return this.parse(str, filepath)\n })\n },\n getTemplateFromUrl: async function (filepath, root) {\n let fullUrl\n if (isValidUrl(filepath)) {\n fullUrl = filepath\n } else {\n if (!extname(filepath)) {\n filepath += this.options.extname\n }\n fullUrl = resolve(root || this.options.root, filepath)\n }\n return this.respectCache(\n filepath,\n async () => this.parse(await httpGet(fullUrl))\n )\n },\n respectCache: async function (key, getter) {\n const cacheEnabled = this.options.cache\n if (cacheEnabled && this.cache[key]) {\n return this.cache[key]\n }\n const value = await getter()\n if (cacheEnabled) {\n this.cache[key] = value\n }\n return value\n },\n express: function (opts) {\n opts = opts || {}\n const self = this\n return function (filePath, ctx, cb) {\n assert(Array.isArray(this.root) || _.isString(this.root),\n 'illegal views root, are you using express.js?')\n opts.root = this.root\n self.renderFile(filePath, ctx, opts).then(html => cb(null, html), cb)\n }\n }\n}\n\nfunction normalizeStringArray (value) {\n if (Array.isArray(value)) return value\n if (_.isString(value)) return [value]\n return []\n}\n\nexport default function Liquid (options) {\n options = _.assign({\n root: ['.'],\n cache: false,\n extname: '',\n dynamicPartials: true,\n trim_tag_right: false,\n trim_tag_left: false,\n trim_value_right: false,\n trim_value_left: false,\n greedy: true,\n strict_filters: false,\n strict_variables: false\n }, options)\n options.root = normalizeStringArray(options.root)\n\n const engine = Object.create(_engine)\n engine.init(Tag(), Filter(options), options)\n return engine\n}\n\nLiquid.isTruthy = isTruthy\nLiquid.isFalsy = isFalsy\nLiquid.evalExp = evalExp\nLiquid.evalValue = evalValue\nLiquid.Types = {\n ParseError,\n TokenizationError,\n RenderBreakError,\n AssertionError,\n AssignScope: Object.create(null),\n CaptureScope: Object.create(null),\n IncrementScope: Object.create(null),\n DecrementScope: Object.create(null)\n}\nLiquid.lexical = lexical\n"],"names":["global","Op","Object","prototype","hasOwn","hasOwnProperty","undefined","$Symbol","Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","toStringTag","inModule","module","runtime","regeneratorRuntime","exports","wrap","innerFn","outerFn","self","tryLocsList","protoGenerator","Generator","generator","create","context","Context","_invoke","makeInvokeMethod","tryCatch","fn","obj","arg","type","call","err","GenStateSuspendedStart","GenStateSuspendedYield","GenStateExecuting","GenStateCompleted","ContinueSentinel","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","getProto","getPrototypeOf","NativeIteratorPrototype","values","Gp","constructor","displayName","defineIteratorMethods","forEach","method","isGeneratorFunction","genFun","ctor","name","mark","setPrototypeOf","__proto__","awrap","__await","AsyncIterator","invoke","resolve","reject","record","result","value","Promise","then","unwrapped","error","previousPromise","enqueue","callInvokeWithMethodAndArg","async","iter","next","done","state","Error","doneResult","delegate","delegateResult","maybeInvokeDelegate","sent","_sent","dispatchException","abrupt","return","TypeError","info","resultName","nextLoc","toString","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","push","resetTryEntry","completion","reset","keys","object","key","reverse","length","pop","iterable","iteratorMethod","isNaN","i","skipTempReset","prev","charAt","slice","stop","rootEntry","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","finish","thrown","delegateYield","Function","toStr","isString","stringify","isNil","String","to_liquid","toLiquid","cache","JSON","isObject","indexOf","isArray","forOwn","iteratee","k","assign","srcs","Array","arguments","src","last","arr","uniq","u","a","l","range","start","step","singleQuoted","doubleQuoted","quoted","RegExp","source","quoteBalanced","integer","number","bool","identifier","subscript","literal","variable","rangeLimit","rangeCapture","hash","hashCapture","tagLine","literalLine","variableLine","numberLine","boolLine","quotedLine","rangeLine","integerLine","valueDeclaration","valueList","filter","filterCapture","filterLine","operators","isInteger","str","test","isLiteral","isRange","isVariable","matchValue","exec","parseLiteral","res","match","Number","toLowerCase","initError","captureStackTrace","initLiquidError","token","input","line","file","mkContext","message","mkMessage","stack","TokenizationError","ParseError","e","_","originalError","RenderError","tpl","RenderBreakError","AssertionError","lines","split","begin","Math","max","end","min","map","align","join","n","blank","msg","predicate","Scope","getAll","contexts","reduce","ctx","val","get","path","paths","propertyAccessSeq","scope","findContextFor","readProperty","set","v","some","unshift","findIndex","splice","candidate","opts","strict_variables","seq","j","delemiter","assert","matchRightBracket","lexical","factory","defaultOptions","dynamicPartials","strict_filters","blocks","root","url","xhr","XMLHttpRequest","onload","status","responseText","statusText","onerror","open","send","whiteSpaceCtrl","tokens","options","greedy","inRaw","shouldTrimLeft","trimLeft","shouldTrimRight","trimRight","trim_left","trim_tag_left","trim_value_left","trim_right","trim_tag_right","trim_value_right","rLeft","replace","rRight","parse","rLiquid","currIndent","lineNumber","LineNumber","lastMatchEnd","lastIndex","index","parseHTMLToken","parseTagToken","trim","parseValueToken","raw","pos","indent","args","htmlFragment","html","parsedLinesCount","lastMatchBegin","readFileAsync","filepath","fs","readFile","content","statFileAsync","stat","splitPathRe","urlRe","extname","valid","resolveUrl","base","document","createElement","href","head","getElementsByTagName","insertBefore","firstChild","resolved","removeChild","isTruthy","r","Operators","evalExp","exp","operatorREs","operatorRE","expRE","op","low","evalValue","high","isFalsy","render","renderTemplates","templates","template","renderTag","partial","renderValue","renderTemplate","resolvedHTML","filters","initial","instance","markup","tagImpls","_tagInstance","impl","tagImpl","register","tag","construct","clear","valueRE","_filterInstance","output","apply","argList","x","re","keyMatch","currentMatchIsKey","Tag","Filter","stream","init","handlers","on","cb","trigger","event","h","stopRequested","shift","parseToken","parseTag","parseValue","substr","parseStream","s","anySeries","ret","item","idx","catch","mapSeries","liquid","Liquid","collection","renderer","elseTemplates","offset","limit","reversed","forloop","first","index0","rindex","rindex0","finished","Types","registerTag","tagToken","remainTokens","p","parser","rIdentifier","AssignScope","CaptureScope","cond","cases","branch","staticFileRE","withRE","staticValue","with","parseAndRender","originBlocks","originBlockMode","blockMode","getTemplate","DecrementScope","rValue","groupRE","candidatesRE","group","candidates","fingerprint","groups","branches","IncrementScope","staticLayout","layout","tpls","block","childDefined","cols","row","floor","col","engine","Assign","Capture","Case","Comment","Cycle","Decrement","For","If","Include","Increment","Layout","Raw","Tablerow","Unless","monthNames","monthNamesShort","dayNames","dayNamesShort","suffixes","_date","daysInMonth","d","feb","isLeapYear","getDayOfYear","num","getMonth","getDate","getWeekOfYear","startDay","now","getDay","jan1","Date","getFullYear","_number","pad","year","getSuffix","parseInt","century","substring","size","ch","formatCodes","A","b","B","c","toLocaleString","C","H","getHours","I","L","getMilliseconds","m","M","getMinutes","P","q","round","valueOf","S","getSeconds","U","w","W","toLocaleDateString","X","toLocaleTimeString","y","Y","z","tz","getTimezoneOffset","abs","N","format","remaining","results","func","escapeMap","unescapeMap","toUpperCase","ceil","concat","date","isValidDate","strftime","escape","unescape","bindFixed","pattern","replacement","arg1","arg2","amp","pow","sort","o","encodeURIComponent","getFixed","getMaxFixed","f","toFixed","getTime","registerAll","registerFilter","_engine","Parser","Render","tags","tokenizer","renderFile","lookup","code","getTemplateFromFile","getTemplateFromUrl","respectCache","fullUrl","isValidUrl","httpGet","getter","cacheEnabled","express","filePath","normalizeStringArray"],"mappings":"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"} \ No newline at end of file diff --git a/dist/liquid.min.js b/dist/liquid.min.js index 955049101..be1ba50c1 100644 --- a/dist/liquid.min.js +++ b/dist/liquid.min.js @@ -1 +1,2 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Liquid=e()}}(function(){return function i(o,u,a){function c(t,e){if(!u[t]){if(!o[t]){var r="function"==typeof require&&require;if(!e&&r)return r(t,!0);if(l)return l(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var s=u[t]={exports:{}};o[t][0].call(s.exports,function(e){return c(o[t][1][e]||e)},s,s.exports,i,o,u,a)}return u[t].exports}for(var l="function"==typeof require&&require,e=0;e":">",'"':""","'":"'"},u={"&":"&","<":"<",">":">",""":'"',"'":"'"},a={abs:function(e){return Math.abs(e)},append:function(e,t){return e+t},capitalize:function(e){return f(e).charAt(0).toUpperCase()+e.slice(1)},ceil:function(e){return Math.ceil(e)},concat:function(e,t){return Array.prototype.concat.call(e,t)},date:function(e,t){var r,n=e;return"now"===e?n=new Date:i.isString(e)&&(n=new Date(e)),(r=n)instanceof Date&&!isNaN(r.getTime())?s(n,t):e},default:function(e,t){return n(e)?e:t},divided_by:function(e,t){return e/t},downcase:function(e){return e.toLowerCase()},escape:c,escape_once:function(e){return c(f(e).replace(/&(amp|lt|gt|#34|#39);/g,function(e){return u[e]}))},first:function(e){return e[0]},floor:function(e){return Math.floor(e)},join:function(e,t){return e.join(t)},last:function(e){return i.last(e)},lstrip:function(e){return f(e).replace(/^\s+/,"")},map:function(e,t){return e.map(function(e){return e[t]})},minus:p(function(e,t){return e-t}),modulo:p(function(e,t){return e%t}),newline_to_br:function(e){return e.replace(/\n/g,"
")},plus:p(function(e,t){return Number(e)+Number(t)}),prepend:function(e,t){return t+e},remove:function(e,t){return e.split(t).join("")},remove_first:function(e,t){return e.replace(t,"")},replace:function(e,t,r){return f(e).split(t).join(r)},replace_first:function(e,t,r){return f(e).replace(t,r)},reverse:function(e){return e.reverse()},round:function(e,t){var r=Math.pow(10,t||0);return Math.round(e*r,t)/r},rstrip:function(e){return f(e).replace(/\s+$/,"")},size:function(e){return e.length},slice:function(e,t,r){return e.substr(t,void 0===r?1:r)},sort:function(e,t){return e.sort(t)},split:function(e,t){return f(e).split(t)},strip:function(e){return f(e).trim()},strip_html:function(e){return f(e).replace(/|||<.*?>/g,"")},strip_newlines:function(e){return f(e).replace(/\n/g,"")},times:function(e,t){return e*t},truncate:function(e,t,r){return r=void 0===r?"...":r,t=t||16,(e=f(e)).length<=t?e:e.substr(0,t-r.length)+r},truncatewords:function(e,t,r){void 0===r&&(r="...");var n=e.split(" "),s=n.slice(0,t).join(" ");return n.length>t&&(s+=r),s},uniq:function(e){var t={};return(e||[]).filter(function(e){return!t.hasOwnProperty(e)&&(t[e]=!0)})},upcase:function(e){return f(e).toUpperCase()},url_encode:encodeURIComponent};function c(e){return f(e).replace(/&|<|>|"|'/g,function(e){return o[e]})}function l(e){var t=(e+"").split(".");return 1=|<|>|\s+contains\s+/],quotedLine:E,numberLine:w,boolLine:b,rangeLine:T,literalLine:j,filterLine:R,tagLine:y,isLiteral:function(e){return j.test(e)},isVariable:function(e){return x.test(e)},parseLiteral:function(e){var t=e.match(w);if(t)return Number(e);if(t=e.match(b))return"true"===e.toLowerCase();if(t=e.match(E))return e.slice(1,-1);throw new TypeError("cannot parse '"+e+"' as literal")},isRange:function(e){return T.test(e)},matchValue:function(e){return g.exec(e)},isInteger:function(e){return S.test(e)}}},{}],8:[function(e,t,r){"use strict";t.exports=function(r){return{"==":function(e,t){return e===t},"!=":function(e,t){return e!==t},">":function(e,t){return null!==e&&null!==t&&t=":function(e,t){return null!==e&&null!==t&&t<=e},"<=":function(e,t){return null!==e&&null!==t&&e<=t},contains:function(e,t){return!!e&&("function"==typeof e.indexOf&&-1"),s+=''),s+='',r.push(t),f.renderer.renderTemplates(n.templates,r).then(function(e){return r.pop(t),s+=e,s+=""})}).then(function(){return 0"),s})}})}},{"..":6,"../util/assert.js":30,"../util/promise.js":33}],28:[function(e,t,r){"use strict";var n,s=e("../index"),o=(n=s)&&n.__esModule?n:{default:n};t.exports=function(i){i.registerTag("unless",{parse:function(t,e){var r=this;this.templates=[],this.elseTemplates=[];var n=void 0,s=i.parser.parseStream(e).on("start",function(e){n=r.templates,r.cond=t.args}).on("tag:else",function(){return n=r.elseTemplates}).on("tag:endunless",function(e){return s.stop()}).on("template",function(e){return n.push(e)}).on("end",function(e){throw new Error("tag "+t.raw+" not closed")});s.start()},render:function(e,t){var r=o.default.evalExp(this.cond,e);return o.default.isFalsy(r)?i.renderer.renderTemplates(this.templates,e):i.renderer.renderTemplates(this.elseTemplates,e)}})}},{"../index":6}],29:[function(e,t,r){"use strict";var m=e("./lexical.js"),y=e("./util/error.js").TokenizationError,j=e("./util/underscore.js"),x=e("./whitespace-ctrl.js"),w=e("./util/assert.js");r.parse=function(i,o,e){w(j.isString(i),"illegal input");for(var r,n,s,t,u,a,c,l=/({%-?([\s\S]*?)-?%})|({{-?([\s\S]*?)-?}})/g,f=0,p=(r=i,n=0,s=-1,{get:function(e){var t=r.slice(s+1,e).split("\n");return n+=t.length-1,s=e,n+1}}),h=0,d=[];t=l.exec(i);h=l.lastIndex)t.index>h&&d.push(v(h,t.index)),d.push(t[1]?g(t[1],t[2].trim(),t.index):(u=t[3],a=t[4].trim(),c=t.index,{type:"value",line:p.get(c),trim_left:"{{-"===u.slice(0,3),trim_right:"-}}"===u.slice(-3),raw:u,value:a,input:i,file:o}));return i.length>h&&d.push(v(h,i.length)),x(d,e),d;function g(e,t,r){var n=t.match(m.tagLine),s={type:"tag",indent:f,line:p.get(r),trim_left:"{%-"===e.slice(0,3),trim_right:"-%}"===e.slice(-3),raw:e,value:t,input:i,file:o};if(!n)throw new y("illegal tag syntax",s);return s.name=n[1],s.args=n[2],s}function v(e,t){var r=i.slice(e,t);return f=j.last(r.split("\n")).length,{type:"html",raw:r,value:r}}},r.whiteSpaceCtrl=x},{"./lexical.js":7,"./util/assert.js":30,"./util/error.js":31,"./util/underscore.js":35,"./whitespace-ctrl.js":37}],30:[function(e,t,r){"use strict";var n=e("./error.js").AssertionError;t.exports=function(e,t){if(!e)throw new n(t=t||"expect "+e+" to be true")}},{"./error.js":31}],31:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.TokenizationError=o,r.ParseError=u,r.RenderError=l,r.RenderBreakError=f,r.AssertionError=p;var n,s=e("./underscore.js"),a=(n=s)&&n.__esModule?n:{default:n};function c(){this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}function i(e,t){c.call(this),this.input=t.input,this.line=t.line,this.file=t.file;var r,s,i,n,o,u=(r=t.input,s=t.line,i=r.split("\n"),n=Math.max(s-2,1),o=Math.min(s+3,i.length),a.default.range(n,o+1).map(function(e){return[e===s?">> ":" ",(t=e,r=o,n=t+"",Array((r+"").length-n.length).join(" ")+n),"| ",i[e-1]].join("");var t,r,n}).join("\n"));this.message=function(e,t){e=e||"",t.file&&(e+=", file:"+t.file);t.line&&(e+=", line:"+t.line);return e}(e.message,t),this.stack=u+"\n"+(this.stack||this.message)+(e.stack?"\nFrom "+e.stack:"")}function o(e,t){i.call(this,{message:e},t)}function u(e,t){a.default.assign(this,e),this.originalError=e,i.call(this,e,t)}function l(e,t){if(e instanceof l)return e;a.default.assign(this,e),this.originalError=e,i.call(this,e,t.token)}function f(e){c.call(this),this.message=e+""}function p(e){c.call(this),this.message=e+""}(o.prototype=Object.create(Error.prototype)).constructor=o,(u.prototype=Object.create(Error.prototype)).constructor=u,(l.prototype=Object.create(Error.prototype)).constructor=l,(f.prototype=Object.create(Error.prototype)).constructor=f,(p.prototype=Object.create(Error.prototype)).constructor=p},{"./underscore.js":35}],32:[function(e,t,r){"use strict";var s=e("fs");t.exports={readFileAsync:function(e){return new Promise(function(r,n){s.readFile(e,"utf8",function(e,t){e?n(e):r(t)})})},statFileAsync:function(e){return new Promise(function(r,n){s.stat(e,function(e,t){return e?n(e):r(t)})})}}},{fs:1}],33:[function(e,t,r){"use strict";r.anySeries=function(n,s){var e=Promise.reject(new Error("init"));return n.forEach(function(t,r){e=e.catch(function(e){return s(t,r,n)})}),e},r.mapSeries=function(r,n){var s=Promise.resolve("init"),i=[];return r.forEach(function(e,t){s=s.then(function(){return n(e,t,r)}).then(function(e){return i.push(e)})}),s.then(function(){return i})}},{}],34:[function(e,t,r){"use strict";var n=["January","February","March","April","May","June","July","August","September","October","November","December"],s=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],i=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],o=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],u={1:"st",2:"nd",3:"rd",default:"th"},a={daysInMonth:function(e){return[31,a.isLeapYear(e)?29:28,31,30,31,30,31,31,30,31,30,31]},getDayOfYear:function(e){for(var t=0,r=0;r=|<|>|\s+contains\s+/];function C(e){return O.test(e)}function D(e){return k.test(e)}function I(e){return E.test(e)}function V(e){return v.exec(e)}function N(e){var t=e.match(T);if(t)return Number(e);if(t=e.match(R))return"true"===e.toLowerCase();if(t=e.match(S))return e.slice(1,-1);throw new TypeError("cannot parse '"+e+"' as literal")}var $={quoted:e,quoteBalanced:p,integer:r,number:o,bool:u,identifier:s,subscript:c,literal:l,variable:f,rangeLimit:h,range:g,rangeCapture:d,value:v,hash:w,hashCapture:x,tagLine:b,literalLine:k,variableLine:E,numberLine:T,boolLine:R,quotedLine:S,rangeLine:L,integerLine:O,valueDeclaration:j,valueList:_,filter:M,filterCapture:A,filterLine:P,operators:q,isInteger:C,isLiteral:D,isRange:function(e){return L.test(e)},isVariable:I,matchValue:V,parseLiteral:N};function Y(){this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}function H(e,t){Y.call(this),this.input=t.input,this.line=t.line,this.file=t.file;var r,i,a,n,o,u=(r=t.input,i=t.line,a=r.split("\n"),n=Math.max(i-2,1),o=Math.min(i+3,a.length),function(e,t,r){1===arguments.length&&(t=e,e=0),r=r||1;for(var n=[],i=e;i> ":" ",(t=e,r=o,n=t+"",Array((r+"").length-n.length).join(" ")+n),"| ",a[e-1]].join("");var t,r,n}).join("\n"));this.message=function(e,t){e=e||"",t.file&&(e+=", file:"+t.file);t.line&&(e+=", line:"+t.line);return e}(e.message,t),this.stack=u+"\n"+(this.stack||this.message)+(e.stack?"\nFrom "+e.stack:"")}function G(e,t){H.call(this,{message:e},t)}function J(e,t){m(this,e),this.originalError=e,H.call(this,e,t)}function z(e,t){if(e instanceof z)return e;m(this,e),this.originalError=e,H.call(this,e,t.token)}function B(e){Y.call(this),this.message=e+""}function U(e){Y.call(this),this.message=e+""}function pe(e,t){if(!e)throw new U(t=t||"expect "+e+" to be true")}(G.prototype=Object.create(Error.prototype)).constructor=G,(J.prototype=Object.create(Error.prototype)).constructor=J,(z.prototype=Object.create(Error.prototype)).constructor=z,(B.prototype=Object.create(Error.prototype)).constructor=B,(U.prototype=Object.create(Error.prototype)).constructor=U;var W={getAll:function(){return this.contexts.reduce(function(e,t){return Object.assign(e,t)},Object.create(null))},get:function(e){var r=this,t=this.propertyAccessSeq(e),n=this.findContextFor(t[0])||y(this.contexts);return t.reduce(function(e,t){return r.readProperty(e,t)},n)},set:function(e,r){var n=this.propertyAccessSeq(e),i=this.findContextFor(n[0])||y(this.contexts);n.some(function(e,t){return!fe(i)||(t===n.length-1?(i[e]=r,!0):(void 0===i[e]&&(i[e]={}),void(i=i[e])))})},unshift:function(e){return this.contexts.unshift(e)},push:function(e){return this.contexts.push(e)},pop:function(t){if(!arguments.length)return this.contexts.pop();var e=this.contexts.findIndex(function(e){return e===t});if(-1===e)throw new TypeError("scope not found, cannot pop");return this.contexts.splice(e,1)[0]},findContextFor:function(e,t){t=t||function(){return!0};for(var r=this.contexts.length-1;0<=r;r--){var n=this.contexts[r];if(t(n)&&e in n)return n}return null},readProperty:function(e,t){var r=void 0;if(n(e)?r=void 0:("function"==typeof e.to_liquid?e=e.to_liquid():"function"==typeof e.toLiquid&&(e=e.toLiquid()),r="size"===t&&(a(e)||le(e))?e.length:e[t]),n(r)&&this.opts.strict_variables)throw new TypeError("undefined variable: "+t);return r},propertyAccessSeq:function(e){e=String(e);for(var t=[],r="",n=void 0,i=0;ih&&g.push(v(h,t.index)),g.push(t[1]?d(t[1],t[2].trim(),t.index):(u=t[3],s=t[4].trim(),c=t.index,{type:"value",line:p.get(c),trim_left:"{{-"===u.slice(0,3),trim_right:"-}}"===u.slice(-3),raw:u,value:s,input:a,file:o}));return a.length>h&&g.push(v(h,a.length)),function(o,u){u=m({greedy:!0},u);var s=!1;o.forEach(function(e,t){var r,n,i,a;i=e,a=u,!s&&("tag"===i.type?i.trim_left||a.trim_tag_left:"value"===i.type?i.trim_left||a.trim_value_left:void 0)&&function(e,t){if(e&&"html"===e.type){var r=t?/\s+$/g:/[\t\r ]*$/g;e.value=e.value.replace(r,"")}}(o[t-1],u.greedy),"tag"===e.type&&"raw"===e.name&&(s=!0),"tag"===e.type&&"endraw"===e.name&&(s=!1),r=e,n=u,!s&&("tag"===r.type?r.trim_right||n.trim_tag_right:"value"===r.type?r.trim_right||n.trim_value_right:void 0)&&function(e,t){if(e&&"html"===e.type){var r=t?/^\s+/g:/^[\t\r ]*\n?/g;e.value=e.value.replace(r,"")}}(o[t+1],u.greedy)})}(g,e),g;function d(e,t,r){var n=t.match(b),i={type:"tag",indent:f,line:p.get(r),trim_left:"{%-"===e.slice(0,3),trim_right:"-%}"===e.slice(-3),raw:e,value:t,input:a,file:o};if(!n)throw new G("illegal tag syntax",i);return i.name=n[1],i.args=n[2],i}function v(e,t){var r=a.slice(e,t);return f=y(r.split("\n")).length,{type:"html",raw:r,value:r}}}var Z={};function ee(e){return new Promise(function(r,n){Z.readFile(e,"utf8",function(e,t){e?n(e):r(t)})})}function te(e){return new Promise(function(r,n){Z.stat(e,function(e,t){return e?n(e):r(t)})})}var re={},ne=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/,ie=/^(?:\w+:)?\/\/([^\s.]+\.\S{2}|localhost[:?\d]*)\S*$/;function ae(e,t){return a(e)&&(e=e[0]),e&&"/"!==y(e)&&(e+="/"),function(e,t){var r=document.createElement("base");r.href=e;var n=document.getElementsByTagName("head")[0];n.insertBefore(r,n.firstChild);var i=document.createElement("a");i.href=t;var a=i.href;return r.href=a,n.removeChild(r),a}(e,t)}var oe,ue=(oe=ge,{"==":function(e,t){return e===t},"!=":function(e,t){return e!==t},">":function(e,t){return null!==e&&null!==t&&t=":function(e,t){return null!==e&&null!==t&&t<=e},"<=":function(e,t){return null!==e&&null!==t&&e<=t},contains:function(e,t){return!!e&&"function"==typeof e.indexOf&&-1"),c+=''),c+='',i.push(t),e.next=7,re.renderer.renderTemplates(l.templates,i);case 7:return c+=e.sent,c+="",i.pop(t),e.abrupt("return",c);case 11:case"end":return e.stop()}},e,l)}));return function(e,t){return r.apply(this,arguments)}}());case 10:return 0"),e.abrupt("return",c);case 12:case"end":return e.stop()}},e,this)})),function(e,t){return ie.apply(this,arguments)})}),se=t,(ue=e).registerTag("unless",{parse:function(t,e){var r=this;this.templates=[],this.elseTemplates=[];var n=void 0,i=ue.parser.parseStream(e).on("start",function(e){n=r.templates,r.cond=t.args}).on("tag:else",function(){return n=r.elseTemplates}).on("tag:endunless",function(e){return i.stop()}).on("template",function(e){return n.push(e)}).on("end",function(e){throw new Error("tag "+t.raw+" not closed")});i.start()},render:function(e,t){var r=se.evalExp(this.cond,e);return se.isFalsy(r)?ue.renderer.renderTemplates(this.templates,e):ue.renderer.renderTemplates(this.elseTemplates,e)}})}var Re=["January","February","March","April","May","June","July","August","September","October","November","December"],Se=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Le=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],Oe=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],je={1:"st",2:"nd",3:"rd",default:"th"},_e={daysInMonth:function(e){return[31,_e.isLeapYear(e)?29:28,31,30,31,30,31,31,30,31,30,31]},getDayOfYear:function(e){for(var t=0,r=0;r":">",'"':""","'":"'"},Pe={"&":"&","<":"<",">":">",""":'"',"'":"'"},qe={abs:function(e){return Math.abs(e)},append:function(e,t){return e+t},capitalize:function(e){return Ie(e).charAt(0).toUpperCase()+e.slice(1)},ceil:function(e){return Math.ceil(e)},concat:function(e,t){return Array.prototype.concat.call(e,t)},date:function(e,t){var r,n=e;return"now"===e?n=new Date:le(e)&&(n=new Date(e)),(r=n)instanceof Date&&!isNaN(r.getTime())?function(e,t){for(var r="",n=t;;){var i=/%./g,a=i.exec(n);if(!a)return r+n;r+=n.slice(0,i.lastIndex-2),n=n.slice(i.lastIndex);var o=a[0].charAt(1),u=Fe[o];r+=u?u.call(this,e):"%"+o}}(n,t):e},default:function(e,t){return ge(e)?e:t},divided_by:function(e,t){return e/t},downcase:function(e){return e.toLowerCase()},escape:Ce,escape_once:function(e){return Ce(Ie(e).replace(/&(amp|lt|gt|#34|#39);/g,function(e){return Pe[e]}))},first:function(e){return e[0]},floor:function(e){return Math.floor(e)},join:function(e,t){return e.join(t)},last:function(e){return y(e)},lstrip:function(e){return Ie(e).replace(/^\s+/,"")},map:function(e,t){return e.map(function(e){return e[t]})},minus:Ve(function(e,t){return e-t}),modulo:Ve(function(e,t){return e%t}),newline_to_br:function(e){return e.replace(/\n/g,"
")},plus:Ve(function(e,t){return Number(e)+Number(t)}),prepend:function(e,t){return t+e},remove:function(e,t){return e.split(t).join("")},remove_first:function(e,t){return e.replace(t,"")},replace:function(e,t,r){return Ie(e).split(t).join(r)},replace_first:function(e,t,r){return Ie(e).replace(t,r)},reverse:function(e){return e.reverse()},round:function(e,t){var r=Math.pow(10,t||0);return Math.round(e*r,t)/r},rstrip:function(e){return Ie(e).replace(/\s+$/,"")},size:function(e){return e.length},slice:function(e,t,r){return e.substr(t,void 0===r?1:r)},sort:function(e,t){return e.sort(t)},split:function(e,t){return Ie(e).split(t)},strip:function(e){return Ie(e).trim()},strip_html:function(e){return Ie(e).replace(/|||<.*?>/g,"")},strip_newlines:function(e){return Ie(e).replace(/\n/g,"")},times:function(e,t){return e*t},truncate:function(e,t,r){return r=void 0===r?"...":r,t=t||16,(e=Ie(e)).length<=t?e:e.substr(0,t-r.length)+r},truncatewords:function(e,t,r){void 0===r&&(r="...");var n=e.split(" "),i=n.slice(0,t).join(" ");return n.length>t&&(i+=r),i},uniq:function(e){var t={};return(e||[]).filter(function(e){return!t.hasOwnProperty(e)&&(t[e]=!0)})},upcase:function(e){return Ie(e).toUpperCase()},url_encode:encodeURIComponent};function Ce(e){return Ie(e).replace(/&|<|>|"|'/g,function(e){return Ae[e]})}function De(e){var t=(e+"").split(".");return 1 result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new Promise(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n AsyncIterator.prototype[asyncIteratorSymbol] = function () {\n return this;\n };\n runtime.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n runtime.async = function(innerFn, outerFn, self, tryLocsList) {\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList)\n );\n\n return runtime.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === \"throw\") {\n if (delegate.iterator.return) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n Gp[toStringTagSymbol] = \"Generator\";\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n Gp[iteratorSymbol] = function() {\n return this;\n };\n\n Gp.toString = function() {\n return \"[object Generator]\";\n };\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n runtime.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n runtime.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n})(\n // In sloppy mode, unbound `this` refers to the global object, fallback to\n // Function constructor if we're in global strict mode. That is sadly a form\n // of indirect eval which violates Content Security Policy.\n (function() {\n return this || (typeof self === \"object\" && self);\n })() || Function(\"return this\")()\n);\n","const toStr = Object.prototype.toString\n\n/*\n * Checks if value is classified as a String primitive or object.\n * @param {any} value The value to check.\n * @return {Boolean} Returns true if value is a string, else false.\n */\nexport function isString (value) {\n return toStr.call(value) === '[object String]'\n}\n\nexport function stringify (value) {\n if (isNil(value)) {\n return String(value)\n }\n if (typeof value.to_liquid === 'function') {\n return stringify(value.to_liquid())\n }\n if (typeof value.toLiquid === 'function') {\n return stringify(value.toLiquid())\n }\n if (isString(value)) {\n return value\n }\n\n const cache = []\n return JSON.stringify(value, (key, value) => {\n if (isObject(value)) {\n if (cache.indexOf(value) !== -1) {\n return\n }\n cache.push(value)\n }\n return value\n })\n}\n\nexport function isNil (value) {\n return value === null || value === undefined\n}\n\nexport function isArray (value) {\n // be compatible with IE 8\n return toStr.call(value) === '[object Array]'\n}\n\nexport function isError (value) {\n const signature = Object.prototype.toString.call(value)\n // [object XXXError]\n return signature.substr(-6, 5) === 'Error' ||\n (typeof value.message === 'string' && typeof value.name === 'string')\n}\n\n/*\n * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property.\n * The iteratee is invoked with three arguments: (value, key, object).\n * Iteratee functions may exit iteration early by explicitly returning false.\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @return {Object} Returns object.\n */\nexport function forOwn (object, iteratee) {\n object = object || {}\n for (const k in object) {\n if (object.hasOwnProperty(k)) {\n if (iteratee(object[k], k, object) === false) break\n }\n }\n return object\n}\n\n/*\n * Assigns own enumerable string keyed properties of source objects to the destination object.\n * Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * Note: This method mutates object and is loosely based on Object.assign.\n *\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @return {Object} Returns object.\n */\nexport function assign (object) {\n object = isObject(object) ? object : {}\n const srcs = Array.prototype.slice.call(arguments, 1)\n srcs.forEach((src) => Object.assign(object, src))\n return object\n}\n\nexport function last (arr) {\n return arr[arr.length - 1]\n}\n\nexport function uniq (arr) {\n const u = {}\n const a = []\n for (let i = 0, l = arr.length; i < l; ++i) {\n if (u.hasOwnProperty(arr[i])) {\n continue\n }\n a.push(arr[i])\n u[arr[i]] = 1\n }\n return a\n}\n\n/*\n * Checks if value is the language type of Object.\n * (e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))\n * @param {any} value The value to check.\n * @return {Boolean} Returns true if value is an object, else false.\n */\nexport function isObject (value) {\n const type = typeof value\n return value != null && (type === 'object' || type === 'function')\n}\n\n/*\n * A function to create flexibly-numbered lists of integers,\n * handy for each and map loops. start, if omitted, defaults to 0; step defaults to 1.\n * Returns a list of integers from start (inclusive) to stop (exclusive),\n * incremented (or decremented) by step, exclusive.\n * Note that ranges that stop before they start are considered to be zero-length instead of\n * negative — if you'd like a negative range, use a negative step.\n */\nexport function range (start, stop, step) {\n if (arguments.length === 1) {\n stop = start\n start = 0\n }\n step = step || 1\n\n const arr = []\n for (let i = start; i < stop; i += step) {\n arr.push(i)\n }\n return arr\n}\n","// quote related\nconst singleQuoted = /'[^']*'/\nconst doubleQuoted = /\"[^\"]*\"/\nexport const quoted = new RegExp(`${singleQuoted.source}|${doubleQuoted.source}`)\nexport const quoteBalanced = new RegExp(`(?:${quoted.source}|[^'\"])*`)\n\n// basic types\nexport const integer = /-?\\d+/\nexport const number = /-?\\d+\\.?\\d*|\\.?\\d+/\nexport const bool = /true|false/\n\n// peoperty access\nexport const identifier = /[\\w-]+[?]?/\nexport const subscript = new RegExp(`\\\\[(?:${quoted.source}|[\\\\w-\\\\.]+)\\\\]`)\nexport const literal = new RegExp(`(?:${quoted.source}|${bool.source}|${number.source})`)\nexport const variable = new RegExp(`${identifier.source}(?:\\\\.${identifier.source}|${subscript.source})*`)\n\n// range related\nexport const rangeLimit = new RegExp(`(?:${variable.source}|${number.source})`)\nexport const range = new RegExp(`\\\\(${rangeLimit.source}\\\\.\\\\.${rangeLimit.source}\\\\)`)\nexport const rangeCapture = new RegExp(`\\\\((${rangeLimit.source})\\\\.\\\\.(${rangeLimit.source})\\\\)`)\n\nexport const value = new RegExp(`(?:${variable.source}|${literal.source}|${range.source})`)\n\n// hash related\nexport const hash = new RegExp(`(?:${identifier.source})\\\\s*:\\\\s*(?:${value.source})`)\nexport const hashCapture = new RegExp(`(${identifier.source})\\\\s*:\\\\s*(${value.source})`, 'g')\n\n// full match\nexport const tagLine = new RegExp(`^\\\\s*(${identifier.source})\\\\s*([\\\\s\\\\S]*)\\\\s*$`)\nexport const literalLine = new RegExp(`^${literal.source}$`, 'i')\nexport const variableLine = new RegExp(`^${variable.source}$`)\nexport const numberLine = new RegExp(`^${number.source}$`)\nexport const boolLine = new RegExp(`^${bool.source}$`, 'i')\nexport const quotedLine = new RegExp(`^${quoted.source}$`)\nexport const rangeLine = new RegExp(`^${rangeCapture.source}$`)\nexport const integerLine = new RegExp(`^${integer.source}$`)\n\n// filter related\nexport const valueDeclaration = new RegExp(`(?:${identifier.source}\\\\s*:\\\\s*)?${value.source}`)\nexport const valueList = new RegExp(`${valueDeclaration.source}(\\\\s*,\\\\s*${valueDeclaration.source})*`)\nexport const filter = new RegExp(`${identifier.source}(?:\\\\s*:\\\\s*${valueList.source})?`, 'g')\nexport const filterCapture = new RegExp(`(${identifier.source})(?:\\\\s*:\\\\s*(${valueList.source}))?`)\nexport const filterLine = new RegExp(`^${filterCapture.source}$`)\n\nexport const operators = [\n /\\s+or\\s+/,\n /\\s+and\\s+/,\n /==|!=|<=|>=|<|>|\\s+contains\\s+/\n]\n\nexport function isInteger (str) {\n return integerLine.test(str)\n}\n\nexport function isLiteral (str) {\n return literalLine.test(str)\n}\n\nexport function isRange (str) {\n return rangeLine.test(str)\n}\n\nexport function isVariable (str) {\n return variableLine.test(str)\n}\n\nexport function matchValue (str) {\n return value.exec(str)\n}\n\nexport function parseLiteral (str) {\n let res = str.match(numberLine)\n if (res) {\n return Number(str)\n }\n res = str.match(boolLine)\n if (res) {\n return str.toLowerCase() === 'true'\n }\n res = str.match(quotedLine)\n if (res) {\n return str.slice(1, -1)\n }\n throw new TypeError(`cannot parse '${str}' as literal`)\n}\n","import * as _ from './underscore.js'\n\nfunction initError () {\n this.name = this.constructor.name\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor)\n }\n}\n\nfunction initLiquidError (err, token) {\n initError.call(this)\n\n this.input = token.input\n this.line = token.line\n this.file = token.file\n\n const context = mkContext(token.input, token.line)\n this.message = mkMessage(err.message, token)\n this.stack = context +\n '\\n' + (this.stack || this.message) +\n (err.stack ? '\\nFrom ' + err.stack : '')\n}\n\nexport function TokenizationError (message, token) {\n initLiquidError.call(this, {message: message}, token)\n}\nTokenizationError.prototype = Object.create(Error.prototype)\nTokenizationError.prototype.constructor = TokenizationError\n\nexport function ParseError (e, token) {\n _.assign(this, e)\n this.originalError = e\n\n initLiquidError.call(this, e, token)\n}\nParseError.prototype = Object.create(Error.prototype)\nParseError.prototype.constructor = ParseError\n\nexport function RenderError (e, tpl) {\n // return the original render error\n if (e instanceof RenderError) {\n return e\n }\n _.assign(this, e)\n this.originalError = e\n\n initLiquidError.call(this, e, tpl.token)\n}\nRenderError.prototype = Object.create(Error.prototype)\nRenderError.prototype.constructor = RenderError\n\nexport function RenderBreakError (message) {\n initError.call(this)\n this.message = message + ''\n}\nRenderBreakError.prototype = Object.create(Error.prototype)\nRenderBreakError.prototype.constructor = RenderBreakError\n\nexport function AssertionError (message) {\n initError.call(this)\n this.message = message + ''\n}\nAssertionError.prototype = Object.create(Error.prototype)\nAssertionError.prototype.constructor = AssertionError\n\nfunction mkContext (input, line) {\n const lines = input.split('\\n')\n const begin = Math.max(line - 2, 1)\n const end = Math.min(line + 3, lines.length)\n\n const context = _\n .range(begin, end + 1)\n .map(l => [\n (l === line) ? '>> ' : ' ',\n align(l, end),\n '| ',\n lines[l - 1]\n ].join(''))\n .join('\\n')\n\n return context\n}\n\nfunction align (n, max) {\n const length = (max + '').length\n const str = n + ''\n const blank = Array(length - str.length).join(' ')\n return blank + str\n}\n\nfunction mkMessage (msg, token) {\n msg = msg || ''\n if (token.file) {\n msg += ', file:' + token.file\n }\n if (token.line) {\n msg += ', line:' + token.line\n }\n return msg\n}\n","import {AssertionError} from './error.js'\n\nexport default function (predicate, message) {\n if (!predicate) {\n message = message || `expect ${predicate} to be true`\n throw new AssertionError(message)\n }\n}\n","import * as _ from './util/underscore.js'\nimport * as lexical from './lexical.js'\nimport assert from './util/assert.js'\n\nconst Scope = {\n getAll: function () {\n return this.contexts.reduce((ctx, val) => Object.assign(ctx, val), Object.create(null))\n },\n get: function (path) {\n const paths = this.propertyAccessSeq(path)\n const scope = this.findContextFor(paths[0]) || _.last(this.contexts)\n return paths.reduce((value, key) => this.readProperty(value, key), scope)\n },\n set: function (path, v) {\n const paths = this.propertyAccessSeq(path)\n let scope = this.findContextFor(paths[0]) || _.last(this.contexts)\n paths.some((key, i) => {\n if (!_.isObject(scope)) {\n return true\n }\n if (i === paths.length - 1) {\n scope[key] = v\n return true\n }\n if (undefined === scope[key]) {\n scope[key] = {}\n }\n scope = scope[key]\n })\n },\n unshift: function (ctx) {\n return this.contexts.unshift(ctx)\n },\n push: function (ctx) {\n return this.contexts.push(ctx)\n },\n pop: function (ctx) {\n if (!arguments.length) {\n return this.contexts.pop()\n }\n const i = this.contexts.findIndex(scope => scope === ctx)\n if (i === -1) {\n throw new TypeError('scope not found, cannot pop')\n }\n return this.contexts.splice(i, 1)[0]\n },\n findContextFor: function (key, filter) {\n filter = filter || (() => true)\n for (let i = this.contexts.length - 1; i >= 0; i--) {\n const candidate = this.contexts[i]\n if (!filter(candidate)) continue\n if (key in candidate) {\n return candidate\n }\n }\n return null\n },\n readProperty: function (obj, key) {\n let val\n if (_.isNil(obj)) {\n val = undefined\n } else {\n if (typeof obj.to_liquid === 'function') {\n obj = obj.to_liquid()\n } else if (typeof obj.toLiquid === 'function') {\n obj = obj.toLiquid()\n }\n\n if (key === 'size' && (_.isArray(obj) || _.isString(obj))) {\n val = obj.length\n } else {\n val = obj[key]\n }\n }\n if (_.isNil(val) && this.opts.strict_variables) {\n throw new TypeError(`undefined variable: ${key}`)\n }\n return val\n },\n\n /*\n * Parse property access sequence from access string\n * @example\n * accessSeq(\"foo.bar\") // ['foo', 'bar']\n * accessSeq(\"foo['bar']\") // ['foo', 'bar']\n * accessSeq(\"foo['b]r']\") // ['foo', 'b]r']\n * accessSeq(\"foo[bar.coo]\") // ['foo', 'bar'], for bar.coo == 'bar'\n */\n propertyAccessSeq: function (str) {\n str = String(str)\n const seq = []\n let name = ''\n let j\n let i = 0\n while (i < str.length) {\n switch (str[i]) {\n case '[':\n push()\n\n const delemiter = str[i + 1]\n if (/['\"]/.test(delemiter)) { // foo[\"bar\"]\n j = str.indexOf(delemiter, i + 2)\n assert(j !== -1, `unbalanced ${delemiter}: ${str}`)\n name = str.slice(i + 2, j)\n push()\n i = j + 2\n } else { // foo[bar.coo]\n j = matchRightBracket(str, i + 1)\n assert(j !== -1, `unbalanced []: ${str}`)\n name = str.slice(i + 1, j)\n if (!lexical.isInteger(name)) { // foo[bar] vs. foo[1]\n name = this.get(name)\n }\n push()\n i = j + 1\n }\n break\n case '.':// foo.bar, foo[0].bar\n push()\n i++\n break\n default:// foo.bar\n name += str[i]\n i++\n }\n }\n push()\n\n if (!seq.length) {\n throw new TypeError(`invalid path:\"${str}\"`)\n }\n return seq\n\n function push () {\n if (name.length) seq.push(name)\n name = ''\n }\n }\n}\n\nfunction matchRightBracket (str, begin) {\n let stack = 1 // count of '[' - count of ']'\n for (let i = begin; i < str.length; i++) {\n if (str[i] === '[') {\n stack++\n }\n if (str[i] === ']') {\n stack--\n if (stack === 0) {\n return i\n }\n }\n }\n return -1\n}\n\nexport function factory (ctx, opts) {\n const defaultOptions = {\n dynamicPartials: true,\n strict_variables: false,\n strict_filters: false,\n blocks: {},\n root: []\n }\n const scope = Object.create(Scope)\n scope.opts = _.assign(defaultOptions, opts)\n scope.contexts = [ctx || {}]\n return scope\n}\n","export function get (url) {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest()\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve(xhr.responseText)\n } else {\n reject(new Error(xhr.statusText))\n }\n }\n xhr.onerror = () => {\n reject(new Error('An error occurred whilst sending the response.'))\n }\n xhr.open('GET', url)\n xhr.send()\n })\n}\n","import * as lexical from './lexical.js'\nimport {TokenizationError} from './util/error.js'\nimport * as _ from './util/underscore.js'\nimport assert from './util/assert.js'\nimport whiteSpaceCtrl from './whitespace-ctrl.js'\n\nexport {default as whiteSpaceCtrl} from './whitespace-ctrl.js'\n\nexport function parse (input, file, options) {\n assert(_.isString(input), 'illegal input')\n\n const rLiquid = /({%-?([\\s\\S]*?)-?%})|({{-?([\\s\\S]*?)-?}})/g\n let currIndent = 0\n const lineNumber = LineNumber(input)\n let lastMatchEnd = 0\n const tokens = []\n\n for (let match; (match = rLiquid.exec(input)); lastMatchEnd = rLiquid.lastIndex) {\n if (match.index > lastMatchEnd) {\n tokens.push(parseHTMLToken(lastMatchEnd, match.index))\n }\n tokens.push(match[1]\n ? parseTagToken(match[1], match[2].trim(), match.index)\n : parseValueToken(match[3], match[4].trim(), match.index))\n }\n if (input.length > lastMatchEnd) {\n tokens.push(parseHTMLToken(lastMatchEnd, input.length))\n }\n whiteSpaceCtrl(tokens, options)\n return tokens\n\n function parseTagToken (raw, value, pos) {\n const match = value.match(lexical.tagLine)\n const token = {\n type: 'tag',\n indent: currIndent,\n line: lineNumber.get(pos),\n trim_left: raw.slice(0, 3) === '{%-',\n trim_right: raw.slice(-3) === '-%}',\n raw,\n value,\n input,\n file\n }\n if (!match) {\n throw new TokenizationError(`illegal tag syntax`, token)\n }\n token.name = match[1]\n token.args = match[2]\n return token\n }\n\n function parseValueToken (raw, value, pos) {\n return {\n type: 'value',\n line: lineNumber.get(pos),\n trim_left: raw.slice(0, 3) === '{{-',\n trim_right: raw.slice(-3) === '-}}',\n raw,\n value,\n input,\n file\n }\n }\n\n function parseHTMLToken (begin, end) {\n const htmlFragment = input.slice(begin, end)\n currIndent = _.last((htmlFragment).split('\\n')).length\n\n return {\n type: 'html',\n raw: htmlFragment,\n value: htmlFragment\n }\n }\n}\n\nfunction LineNumber (html) {\n let parsedLinesCount = 0\n let lastMatchBegin = -1\n\n return {\n get: function (pos) {\n const lines = html.slice(lastMatchBegin + 1, pos).split('\\n')\n parsedLinesCount += lines.length - 1\n lastMatchBegin = pos\n return parsedLinesCount + 1\n }\n }\n}\n","import {assign} from './util/underscore.js'\n\nexport default function whiteSpaceCtrl (tokens, options) {\n options = assign({ greedy: true }, options)\n let inRaw = false\n\n tokens.forEach((token, i) => {\n if (shouldTrimLeft(token, inRaw, options)) {\n trimLeft(tokens[i - 1], options.greedy)\n }\n\n if (token.type === 'tag' && token.name === 'raw') inRaw = true\n if (token.type === 'tag' && token.name === 'endraw') inRaw = false\n\n if (shouldTrimRight(token, inRaw, options)) {\n trimRight(tokens[i + 1], options.greedy)\n }\n })\n}\n\nfunction shouldTrimLeft (token, inRaw, options) {\n if (inRaw) return false\n if (token.type === 'tag') return token.trim_left || options.trim_tag_left\n if (token.type === 'value') return token.trim_left || options.trim_value_left\n}\n\nfunction shouldTrimRight (token, inRaw, options) {\n if (inRaw) return false\n if (token.type === 'tag') return token.trim_right || options.trim_tag_right\n if (token.type === 'value') return token.trim_right || options.trim_value_right\n}\n\nfunction trimLeft (token, greedy) {\n if (!token || token.type !== 'html') return\n\n const rLeft = greedy ? /\\s+$/g : /[\\t\\r ]*$/g\n token.value = token.value.replace(rLeft, '')\n}\n\nfunction trimRight (token, greedy) {\n if (!token || token.type !== 'html') return\n\n const rRight = greedy ? /^\\s+/g : /^[\\t\\r ]*\\n?/g\n token.value = token.value.replace(rRight, '')\n}\n","import fs from 'fs'\n\nexport function readFileAsync (filepath) {\n return new Promise(function (resolve, reject) {\n fs.readFile(filepath, 'utf8', function (err, content) {\n err ? reject(err) : resolve(content)\n })\n })\n};\n\nexport function statFileAsync (path) {\n return new Promise(function (resolve, reject) {\n fs.stat(path, (err, stat) => err ? reject(err) : resolve(stat))\n })\n};\n","import {last, isArray} from './underscore'\n\nconst splitPathRe = /^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^/]+?|)(\\.[^./]*|))(?:[/]*)$/\nconst urlRe = /^(?:\\w+:)?\\/\\/([^\\s.]+\\.\\S{2}|localhost[:?\\d]*)\\S*$/\n\n// https://github.com/jinder/path/blob/master/path.js#L567\nexport function extname (path) {\n return splitPathRe.exec(path).slice(1)[3]\n}\n\n// https://www.npmjs.com/package/is-url\nexport function valid (path) {\n return urlRe.test(path)\n}\n\nexport function resolve (root, path) {\n if (isArray(root)) {\n root = root[0]\n }\n if (root && last(root) !== '/') {\n root += '/'\n }\n return resolveUrl(root, path)\n}\n\nfunction resolveUrl (root, path) {\n const base = document.createElement('base')\n base.href = arguments[0]\n\n const head = document.getElementsByTagName('head')[0]\n head.insertBefore(base, head.firstChild)\n\n const a = document.createElement('a')\n a.href = path\n const resolved = a.href\n base.href = resolved\n\n head.removeChild(base)\n\n return resolved\n}\n","import Operators from './operators.js'\nimport * as lexical from './lexical.js'\nimport assert from './util/assert.js'\n\nconst operators = Operators(isTruthy)\n\nexport function evalExp (exp, scope) {\n assert(scope, 'unable to evalExp: scope undefined')\n const operatorREs = lexical.operators\n let match\n for (let i = 0; i < operatorREs.length; i++) {\n const operatorRE = operatorREs[i]\n const expRE = new RegExp(`^(${lexical.quoteBalanced.source})(${operatorRE.source})(${lexical.quoteBalanced.source})$`)\n if ((match = exp.match(expRE))) {\n const l = evalExp(match[1], scope)\n const op = operators[match[2].trim()]\n const r = evalExp(match[3], scope)\n return op(l, r)\n }\n }\n\n if ((match = exp.match(lexical.rangeLine))) {\n const low = evalValue(match[1], scope)\n const high = evalValue(match[2], scope)\n const range = []\n for (let j = low; j <= high; j++) {\n range.push(j)\n }\n return range\n }\n\n return evalValue(exp, scope)\n}\n\nexport function evalValue (str, scope) {\n str = str && str.trim()\n if (!str) return undefined\n\n if (lexical.isLiteral(str)) {\n return lexical.parseLiteral(str)\n }\n if (lexical.isVariable(str)) {\n return scope.get(str)\n }\n throw new TypeError(`cannot eval '${str}' as value`)\n}\n\nexport function isTruthy (val) {\n return !isFalsy(val)\n}\n\nexport function isFalsy (val) {\n return val === false || undefined === val || val === null\n}\n","export default function (isTruthy) {\n return {\n '==': (l, r) => l === r,\n '!=': (l, r) => l !== r,\n '>': (l, r) => l !== null && r !== null && l > r,\n '<': (l, r) => l !== null && r !== null && l < r,\n '>=': (l, r) => l !== null && r !== null && l >= r,\n '<=': (l, r) => l !== null && r !== null && l <= r,\n 'contains': (l, r) => {\n if (!l) return false\n if (typeof l.indexOf !== 'function') return false\n return l.indexOf(r) > -1\n },\n 'and': (l, r) => isTruthy(l) && isTruthy(r),\n 'or': (l, r) => isTruthy(l) || isTruthy(r)\n }\n}\n","import {evalExp} from './syntax.js'\nimport {RenderBreakError, RenderError} from './util/error.js'\nimport {stringify} from './util/underscore.js'\nimport assert from './util/assert.js'\n\nconst render = {\n renderTemplates: async function (templates, scope) {\n assert(scope, 'unable to evalTemplates: scope undefined')\n\n let html = ''\n for (const tpl of templates) {\n try {\n html += await renderTemplate.call(this, tpl)\n } catch (e) {\n if (e instanceof RenderBreakError) {\n e.resolvedHTML = html\n throw e\n }\n throw new RenderError(e, tpl)\n }\n }\n return html\n\n async function renderTemplate (template) {\n if (template.type === 'tag') {\n const partial = await this.renderTag(template, scope)\n return partial === undefined ? '' : partial\n }\n if (template.type === 'value') {\n return this.renderValue(template, scope)\n }\n return template.value\n }\n },\n\n renderTag: async function (template, scope) {\n if (template.name === 'continue') {\n throw new RenderBreakError('continue')\n }\n if (template.name === 'break') {\n throw new RenderBreakError('break')\n }\n return template.render(scope)\n },\n\n renderValue: async function (template, scope) {\n const partial = this.evalValue(template, scope)\n return partial === undefined ? '' : stringify(partial)\n },\n\n evalValue: function (template, scope) {\n assert(scope, 'unable to evalValue: scope undefined')\n return template.filters.reduce(\n (prev, filter) => filter.render(prev, scope),\n evalExp(template.initial, scope))\n }\n}\n\nexport default function () {\n const instance = Object.create(render)\n return instance\n}\n","import {hashCapture} from './lexical.js'\nimport {evalValue} from './syntax.js'\nimport assert from './util/assert.js'\n\nfunction hash (markup, scope) {\n const obj = {}\n let match\n hashCapture.lastIndex = 0\n while ((match = hashCapture.exec(markup))) {\n const k = match[1]\n const v = match[2]\n obj[k] = evalValue(v, scope)\n }\n return obj\n}\n\nexport default function () {\n let tagImpls = {}\n\n const _tagInstance = {\n render: async function (scope) {\n const obj = hash(this.token.args, scope)\n const impl = this.tagImpl\n if (typeof impl.render !== 'function') {\n return ''\n }\n return impl.render(scope, obj)\n },\n parse: function (token, tokens) {\n this.type = 'tag'\n this.token = token\n this.name = token.name\n\n const tagImpl = tagImpls[this.name]\n assert(tagImpl, `tag ${this.name} not found`)\n this.tagImpl = Object.create(tagImpl)\n if (this.tagImpl.parse) {\n this.tagImpl.parse(token, tokens)\n }\n }\n }\n\n function register (name, tag) {\n tagImpls[name] = tag\n }\n\n function construct (token, tokens) {\n const instance = Object.create(_tagInstance)\n instance.parse(token, tokens)\n return instance\n }\n\n function clear () {\n tagImpls = {}\n }\n\n return {\n construct,\n register,\n clear\n }\n}\n","import * as lexical from './lexical.js'\nimport {evalValue} from './syntax.js'\nimport assert from './util/assert.js'\nimport {assign} from './util/underscore.js'\n\nconst valueRE = new RegExp(`${lexical.value.source}`, 'g')\n\nexport default function (options) {\n options = assign({}, options)\n let filters = {}\n\n const _filterInstance = {\n render: function (output, scope) {\n const args = this.args.map(arg => evalValue(arg, scope))\n args.unshift(output)\n return this.filter.apply(null, args)\n },\n parse: function (str) {\n let match = lexical.filterLine.exec(str)\n assert(match, 'illegal filter: ' + str)\n\n const name = match[1]\n const argList = match[2] || ''\n const filter = filters[name]\n if (typeof filter !== 'function') {\n if (options.strict_filters) {\n throw new TypeError(`undefined filter: ${name}`)\n }\n this.name = name\n this.filter = x => x\n this.args = []\n return this\n }\n\n const args = []\n while ((match = valueRE.exec(argList.trim()))) {\n const v = match[0]\n const re = new RegExp(`${v}\\\\s*:`, 'g')\n const keyMatch = re.exec(match.input)\n const currentMatchIsKey = keyMatch && keyMatch.index === match.index\n currentMatchIsKey ? args.push(`'${v}'`) : args.push(v)\n }\n\n this.name = name\n this.filter = filter\n this.args = args\n\n return this\n }\n }\n\n function construct (str) {\n const instance = Object.create(_filterInstance)\n return instance.parse(str)\n }\n\n function register (name, filter) {\n filters[name] = filter\n }\n\n function clear () {\n filters = {}\n }\n\n return {\n construct, register, clear\n }\n}\n","/*\n * Call functions in serial until someone resolved.\n * @param {Array} iterable the array to iterate with.\n * @param {Array} iteratee returns a new promise.\n * The iteratee is invoked with three arguments: (value, index, iterable).\n */\nexport function anySeries (iterable, iteratee) {\n let ret = Promise.reject(new Error('init'))\n iterable.forEach(function (item, idx) {\n ret = ret.catch(e => iteratee(item, idx, iterable))\n })\n return ret\n}\n\n/*\n * Call functions in serial until someone rejected.\n * @param {Array} iterable the array to iterate with.\n * @param {Array} iteratee returns a new promise.\n * The iteratee is invoked with three arguments: (value, index, iterable).\n */\nexport function mapSeries (iterable, iteratee) {\n let ret = Promise.resolve('init')\n const result = []\n iterable.forEach(function (item, idx) {\n ret = ret\n .then(() => iteratee(item, idx, iterable))\n .then(x => result.push(x))\n })\n return ret.then(() => result)\n}\n","import assert from '../util/assert.js'\n\nconst staticFileRE = /[^\\s,]+/\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const withRE = new RegExp(`with\\\\s+(${lexical.value.source})`)\n\n liquid.registerTag('include', {\n parse: function (token) {\n let match = staticFileRE.exec(token.args)\n if (match) {\n this.staticValue = match[0]\n }\n\n match = lexical.value.exec(token.args)\n if (match) {\n this.value = match[0]\n }\n\n match = withRE.exec(token.args)\n if (match) {\n this.with = match[1]\n }\n },\n render: async function (scope, hash) {\n let filepath\n if (scope.opts.dynamicPartials) {\n if (lexical.quotedLine.exec(this.value)) {\n const template = this.value.slice(1, -1)\n filepath = await liquid.parseAndRender(template, scope.getAll(), scope.opts)\n } else {\n filepath = Liquid.evalValue(this.value, scope)\n }\n } else {\n filepath = this.staticValue\n }\n assert(filepath, `cannot include with empty filename`)\n\n const originBlocks = scope.opts.blocks\n const originBlockMode = scope.opts.blockMode\n\n scope.opts.blocks = {}\n scope.opts.blockMode = 'output'\n if (this.with) {\n hash[filepath] = Liquid.evalValue(this.with, scope)\n }\n const templates = await liquid.getTemplate(filepath, scope.opts.root)\n scope.push(hash)\n const html = await liquid.renderer.renderTemplates(templates, scope)\n scope.pop(hash)\n scope.opts.blocks = originBlocks\n scope.opts.blockMode = originBlockMode\n return html\n }\n })\n}\n","import For from './for.js'\nimport Assign from './assign.js'\nimport Capture from './capture.js'\nimport Case from './case.js'\nimport Comment from './comment.js'\nimport Include from './include.js'\nimport Decrement from './decrement.js'\nimport Cycle from './cycle.js'\nimport If from './if.js'\nimport Increment from './increment.js'\nimport Layout from './layout.js'\nimport Raw from './raw.js'\nimport Tablerow from './tablerow.js'\nimport Unless from './unless.js'\n\nexport default function (engine, Liquid) {\n Assign(engine, Liquid)\n Capture(engine, Liquid)\n Case(engine, Liquid)\n Comment(engine, Liquid)\n Cycle(engine, Liquid)\n Decrement(engine, Liquid)\n For(engine, Liquid)\n If(engine, Liquid)\n Include(engine, Liquid)\n Increment(engine, Liquid)\n Layout(engine, Liquid)\n Raw(engine, Liquid)\n Tablerow(engine, Liquid)\n Unless(engine, Liquid)\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const rIdentifier = Liquid.lexical.identifier\n const re = new RegExp(`(${rIdentifier.source})\\\\s*=(.*)`)\n const {AssignScope} = Liquid.Types\n\n liquid.registerTag('assign', {\n parse: function (token) {\n const match = token.args.match(re)\n assert(match, `illegal token ${token.raw}`)\n this.key = match[1]\n this.value = match[2]\n },\n render: function (scope) {\n const ctx = Object.create(AssignScope)\n ctx[this.key] = liquid.evalValue(this.value, scope)\n scope.push(ctx)\n return Promise.resolve('')\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const rIdentifier = Liquid.lexical.identifier\n const re = new RegExp(`(${rIdentifier.source})`)\n const {CaptureScope} = Liquid.Types\n\n liquid.registerTag('capture', {\n parse: function (tagToken, remainTokens) {\n const match = tagToken.args.match(re)\n assert(match, `${tagToken.args} not valid identifier`)\n\n this.variable = match[1]\n this.templates = []\n\n const stream = liquid.parser.parseStream(remainTokens)\n stream.on('tag:endcapture', token => stream.stop())\n .on('template', tpl => this.templates.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n stream.start()\n },\n render: async function (scope, hash) {\n const html = await liquid.renderer.renderTemplates(this.templates, scope)\n const ctx = Object.create(CaptureScope)\n ctx[this.variable] = html\n scope.push(ctx)\n }\n })\n}\n","export default function (liquid, Liquid) {\n liquid.registerTag('case', {\n\n parse: function (tagToken, remainTokens) {\n this.cond = tagToken.args\n this.cases = []\n this.elseTemplates = []\n\n let p = []\n const stream = liquid.parser.parseStream(remainTokens)\n .on('tag:when', token => {\n this.cases.push({\n val: token.args,\n templates: p = []\n })\n })\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endcase', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: function (scope, hash) {\n for (let i = 0; i < this.cases.length; i++) {\n const branch = this.cases[i]\n const val = Liquid.evalExp(branch.val, scope)\n const cond = Liquid.evalExp(this.cond, scope)\n if (val === cond) {\n return liquid.renderer.renderTemplates(branch.templates, scope)\n }\n }\n return liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n })\n}\n","export default function (liquid) {\n liquid.registerTag('comment', {\n parse: function (tagToken, remainTokens) {\n const stream = liquid.parser.parseStream(remainTokens)\n stream\n .on('token', token => {\n if (token.name === 'endcomment') stream.stop()\n })\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n stream.start()\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const rValue = Liquid.lexical.value\n const groupRE = new RegExp(`^(?:(${rValue.source})\\\\s*:\\\\s*)?(.*)$`)\n const candidatesRE = new RegExp(rValue.source, 'g')\n\n liquid.registerTag('cycle', {\n\n parse: function (tagToken, remainTokens) {\n let match = groupRE.exec(tagToken.args)\n assert(match, `illegal tag: ${tagToken.raw}`)\n\n this.group = match[1] || ''\n const candidates = match[2]\n\n this.candidates = []\n\n while ((match = candidatesRE.exec(candidates))) {\n this.candidates.push(match[0])\n }\n assert(this.candidates.length, `empty candidates: ${tagToken.raw}`)\n },\n\n render: function (scope, hash) {\n const group = Liquid.evalValue(this.group, scope)\n const fingerprint = `cycle:${group}:` + this.candidates.join(',')\n\n const groups = scope.opts.groups = scope.opts.groups || {}\n let idx = groups[fingerprint]\n\n if (idx === undefined) {\n idx = groups[fingerprint] = 0\n }\n\n const candidate = this.candidates[idx]\n idx = (idx + 1) % this.candidates.length\n groups[fingerprint] = idx\n\n return Liquid.evalValue(candidate, scope)\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const {CaptureScope, AssignScope, DecrementScope} = Liquid.Types\n\n liquid.registerTag('decrement', {\n parse: function (token) {\n const match = token.args.match(lexical.identifier)\n assert(match, `illegal identifier ${token.args}`)\n this.variable = match[0]\n },\n render: function (scope, hash) {\n let context = scope.findContextFor(\n this.variable,\n ctx => {\n return Object.getPrototypeOf(ctx) !== CaptureScope &&\n Object.getPrototypeOf(ctx) !== AssignScope\n }\n )\n if (!context) {\n context = Object.create(DecrementScope)\n scope.unshift(context)\n }\n if (typeof context[this.variable] !== 'number') {\n context[this.variable] = 0\n }\n return --context[this.variable]\n }\n })\n}\n","import {mapSeries} from '../util/promise.js'\nimport {isString, isObject} from '../util/underscore.js'\nimport assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const RenderBreakError = Liquid.Types.RenderBreakError\n const lexical = Liquid.lexical\n const re = new RegExp(`^(${lexical.identifier.source})\\\\s+in\\\\s+` +\n `(${lexical.value.source})` +\n `(?:\\\\s+${lexical.hash.source})*` +\n `(?:\\\\s+(reversed))?` +\n `(?:\\\\s+${lexical.hash.source})*$`)\n\n liquid.registerTag('for', {parse, render})\n\n function parse (tagToken, remainTokens) {\n const match = re.exec(tagToken.args)\n assert(match, `illegal tag: ${tagToken.raw}`)\n this.variable = match[1]\n this.collection = match[2]\n this.reversed = !!match[3]\n\n this.templates = []\n this.elseTemplates = []\n\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', () => (p = this.templates))\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endfor', () => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', () => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n }\n async function render (scope, hash) {\n let collection = Liquid.evalExp(this.collection, scope)\n\n if (!Array.isArray(collection)) {\n if (isString(collection) && collection.length > 0) {\n collection = [collection]\n } else if (isObject(collection)) {\n collection = Object.keys(collection).map((key) => [key, collection[key]])\n }\n }\n if (!Array.isArray(collection) || !collection.length) {\n return liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n\n const offset = hash.offset || 0\n const limit = (hash.limit === undefined) ? collection.length : hash.limit\n\n collection = collection.slice(offset, offset + limit)\n if (this.reversed) collection.reverse()\n\n const contexts = collection.map((item, i) => {\n const ctx = {}\n ctx[this.variable] = item\n ctx.forloop = {\n first: i === 0,\n index: i + 1,\n index0: i,\n last: i === collection.length - 1,\n length: collection.length,\n rindex: collection.length - i,\n rindex0: collection.length - i - 1\n }\n return ctx\n })\n\n let html = ''\n let finished = false\n await mapSeries(contexts, async context => {\n if (finished) return\n\n scope.push(context)\n try {\n html += await liquid.renderer.renderTemplates(this.templates, scope)\n } catch (e) {\n if (e instanceof RenderBreakError) {\n html += e.resolvedHTML\n if (e.message === 'break') {\n finished = true\n }\n } else throw e\n }\n scope.pop(context)\n })\n return html\n }\n}\n","export default function (liquid, Liquid) {\n liquid.registerTag('if', {\n\n parse: function (tagToken, remainTokens) {\n this.branches = []\n this.elseTemplates = []\n\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', () => this.branches.push({\n cond: tagToken.args,\n templates: (p = [])\n }))\n .on('tag:elsif', token => {\n this.branches.push({\n cond: token.args,\n templates: p = []\n })\n })\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endif', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: function (scope, hash) {\n for (const branch of this.branches) {\n const cond = Liquid.evalExp(branch.cond, scope)\n if (Liquid.isTruthy(cond)) {\n return liquid.renderer.renderTemplates(branch.templates, scope)\n }\n }\n return liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n })\n}\n","import assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const {CaptureScope, AssignScope, IncrementScope} = Liquid.Types\n\n liquid.registerTag('increment', {\n parse: function (token) {\n const match = token.args.match(lexical.identifier)\n assert(match, `illegal identifier ${token.args}`)\n this.variable = match[0]\n },\n render: function (scope, hash) {\n let context = scope.findContextFor(\n this.variable,\n ctx => {\n return Object.getPrototypeOf(ctx) !== CaptureScope &&\n Object.getPrototypeOf(ctx) !== AssignScope\n }\n )\n if (!context) {\n context = Object.create(IncrementScope)\n scope.unshift(context)\n }\n if (typeof context[this.variable] !== 'number') {\n context[this.variable] = 0\n }\n const val = context[this.variable]\n context[this.variable]++\n return val\n }\n })\n}\n","import assert from '../util/assert.js'\n\n/*\n * blockMode:\n * * \"store\": store rendered html into blocks\n * * \"output\": output rendered html\n */\n\nexport default function (liquid, Liquid) {\n const rValue = Liquid.lexical.value\n const staticFileRE = /\\S+/\n\n liquid.registerTag('layout', {\n parse: function (token, remainTokens) {\n let match = staticFileRE.exec(token.args)\n if (match) {\n this.staticLayout = match[0]\n }\n\n match = rValue.exec(token.args)\n if (match) {\n this.layout = match[0]\n }\n\n this.tpls = liquid.parser.parse(remainTokens)\n },\n render: async function (scope, hash) {\n const layout = scope.opts.dynamicPartials\n ? Liquid.evalValue(this.layout, scope)\n : this.staticLayout\n assert(layout, `cannot apply layout with empty filename`)\n\n // render the remaining tokens immediately\n scope.opts.blockMode = 'store'\n const html = await liquid.renderer.renderTemplates(this.tpls, scope)\n if (scope.opts.blocks[''] === undefined) {\n scope.opts.blocks[''] = html\n }\n const templates = await liquid.getTemplate(layout, scope.opts.root)\n scope.push(hash)\n scope.opts.blockMode = 'output'\n const partial = await liquid.renderer.renderTemplates(templates, scope)\n scope.pop(hash)\n return partial\n }\n })\n\n liquid.registerTag('block', {\n parse: function (token, remainTokens) {\n const match = /\\w+/.exec(token.args)\n this.block = match ? match[0] : ''\n\n this.tpls = []\n const stream = liquid.parser.parseStream(remainTokens)\n .on('tag:endblock', () => stream.stop())\n .on('template', tpl => this.tpls.push(tpl))\n .on('end', () => {\n throw new Error(`tag ${token.raw} not closed`)\n })\n stream.start()\n },\n render: async function (scope) {\n const childDefined = scope.opts.blocks[this.block]\n const html = childDefined !== undefined\n ? childDefined\n : await liquid.renderer.renderTemplates(this.tpls, scope)\n\n if (scope.opts.blockMode === 'store') {\n scope.opts.blocks[this.block] = html\n return ''\n }\n return html\n }\n })\n}\n","export default function (liquid) {\n liquid.registerTag('raw', {\n parse: function (tagToken, remainTokens) {\n this.tokens = []\n\n const stream = liquid.parser.parseStream(remainTokens)\n stream\n .on('token', token => {\n if (token.name === 'endraw') stream.stop()\n else this.tokens.push(token)\n })\n .on('end', () => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n stream.start()\n },\n render: function (scope, hash) {\n return this.tokens.map(token => token.raw).join('')\n }\n })\n}\n","import {mapSeries} from '../util/promise.js'\nimport assert from '../util/assert.js'\n\nexport default function (liquid, Liquid) {\n const lexical = Liquid.lexical\n const re = new RegExp(`^(${lexical.identifier.source})\\\\s+in\\\\s+` +\n `(${lexical.value.source})` +\n `(?:\\\\s+${lexical.hash.source})*$`)\n\n liquid.registerTag('tablerow', {\n\n parse: function (tagToken, remainTokens) {\n const match = re.exec(tagToken.args)\n assert(match, `illegal tag: ${tagToken.raw}`)\n\n this.variable = match[1]\n this.collection = match[2]\n this.templates = []\n\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', () => (p = this.templates))\n .on('tag:endtablerow', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', () => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: async function (scope, hash) {\n let collection = Liquid.evalExp(this.collection, scope) || []\n const offset = hash.offset || 0\n const limit = (hash.limit === undefined) ? collection.length : hash.limit\n\n collection = collection.slice(offset, offset + limit)\n const cols = hash.cols || collection.length\n const contexts = collection.map((item, i) => {\n const ctx = {}\n ctx[this.variable] = item\n return ctx\n })\n\n let row\n let html = ''\n await mapSeries(contexts, async (context, idx) => {\n row = Math.floor(idx / cols) + 1\n const col = (idx % cols) + 1\n if (col === 1) {\n if (row !== 1) {\n html += ''\n }\n html += ``\n }\n\n html += ``\n scope.push(context)\n html += await liquid.renderer.renderTemplates(this.templates, scope)\n html += ''\n scope.pop(context)\n return html\n })\n if (row > 0) {\n html += ''\n }\n return html\n }\n })\n}\n","export default function (liquid, Liquid) {\n liquid.registerTag('unless', {\n parse: function (tagToken, remainTokens) {\n this.templates = []\n this.elseTemplates = []\n let p\n const stream = liquid.parser.parseStream(remainTokens)\n .on('start', x => {\n p = this.templates\n this.cond = tagToken.args\n })\n .on('tag:else', () => (p = this.elseTemplates))\n .on('tag:endunless', token => stream.stop())\n .on('template', tpl => p.push(tpl))\n .on('end', x => {\n throw new Error(`tag ${tagToken.raw} not closed`)\n })\n\n stream.start()\n },\n\n render: function (scope, hash) {\n const cond = Liquid.evalExp(this.cond, scope)\n return Liquid.isFalsy(cond)\n ? liquid.renderer.renderTemplates(this.templates, scope)\n : liquid.renderer.renderTemplates(this.elseTemplates, scope)\n }\n })\n}\n","const monthNames = [\n 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',\n 'September', 'October', 'November', 'December'\n]\nconst monthNamesShort = [\n 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',\n 'Nov', 'Dec'\n]\nconst dayNames = [\n 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'\n]\nconst dayNamesShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']\nconst suffixes = {\n 1: 'st',\n 2: 'nd',\n 3: 'rd',\n 'default': 'th'\n}\n\n// prototype extensions\nconst _date = {\n daysInMonth: function (d) {\n const feb = _date.isLeapYear(d) ? 29 : 28\n return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\n },\n\n getDayOfYear: function (d) {\n let num = 0\n for (let i = 0; i < d.getMonth(); ++i) {\n num += _date.daysInMonth(d)[i]\n }\n return num + d.getDate()\n },\n\n // Startday is an integer of which day to start the week measuring from\n // TODO: that comment was retarted. fix it.\n getWeekOfYear: function (d, startDay) {\n // Skip to startDay of this week\n const now = this.getDayOfYear(d) + (startDay - d.getDay())\n // Find the first startDay of the year\n const jan1 = new Date(d.getFullYear(), 0, 1)\n const then = (7 - jan1.getDay() + startDay)\n return _number.pad(Math.floor((now - then) / 7) + 1, 2)\n },\n\n isLeapYear: function (d) {\n const year = d.getFullYear()\n return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)))\n },\n\n getSuffix: function (d) {\n const str = d.getDate().toString()\n const index = parseInt(str.slice(-1))\n return suffixes[index] || suffixes['default']\n },\n\n century: function (d) {\n return parseInt(d.getFullYear().toString().substring(0, 2), 10)\n }\n}\n\nconst _number = {\n pad: function (value, size, ch) {\n if (!ch) ch = '0'\n let result = value.toString()\n let pad = size - result.length\n\n while (pad-- > 0) {\n result = ch + result\n }\n\n return result\n }\n}\n\nconst formatCodes = {\n a: function (d) {\n return dayNamesShort[d.getDay()]\n },\n A: function (d) {\n return dayNames[d.getDay()]\n },\n b: function (d) {\n return monthNamesShort[d.getMonth()]\n },\n B: function (d) {\n return monthNames[d.getMonth()]\n },\n c: function (d) {\n return d.toLocaleString()\n },\n C: function (d) {\n return _date.century(d)\n },\n d: function (d) {\n return _number.pad(d.getDate(), 2)\n },\n e: function (d) {\n return _number.pad(d.getDate(), 2, ' ')\n },\n H: function (d) {\n return _number.pad(d.getHours(), 2)\n },\n I: function (d) {\n return _number.pad(d.getHours() % 12 || 12, 2)\n },\n j: function (d) {\n return _number.pad(_date.getDayOfYear(d), 3)\n },\n k: function (d) {\n return _number.pad(d.getHours(), 2, ' ')\n },\n l: function (d) {\n return _number.pad(d.getHours() % 12 || 12, 2, ' ')\n },\n L: function (d) {\n return _number.pad(d.getMilliseconds(), 3)\n },\n m: function (d) {\n return _number.pad(d.getMonth() + 1, 2)\n },\n M: function (d) {\n return _number.pad(d.getMinutes(), 2)\n },\n p: function (d) {\n return (d.getHours() < 12 ? 'AM' : 'PM')\n },\n P: function (d) {\n return (d.getHours() < 12 ? 'am' : 'pm')\n },\n q: function (d) {\n return _date.getSuffix(d)\n },\n s: function (d) {\n return Math.round(d.valueOf() / 1000)\n },\n S: function (d) {\n return _number.pad(d.getSeconds(), 2)\n },\n u: function (d) {\n return d.getDay() || 7\n },\n U: function (d) {\n return _date.getWeekOfYear(d, 0)\n },\n w: function (d) {\n return d.getDay()\n },\n W: function (d) {\n return _date.getWeekOfYear(d, 1)\n },\n x: function (d) {\n return d.toLocaleDateString()\n },\n X: function (d) {\n return d.toLocaleTimeString()\n },\n y: function (d) {\n return d.getFullYear().toString().substring(2, 4)\n },\n Y: function (d) {\n return d.getFullYear()\n },\n z: function (d) {\n const tz = d.getTimezoneOffset() / 60 * 100\n return (tz > 0 ? '-' : '+') + _number.pad(Math.abs(tz), 4)\n },\n '%': function () {\n return '%'\n }\n}\nformatCodes.h = formatCodes.b\nformatCodes.N = formatCodes.L\n\nexport default function (d, format) {\n let output = ''\n let remaining = format\n\n while (true) {\n const r = /%./g\n const results = r.exec(remaining)\n\n // No more format codes. Add the remaining text and return\n if (!results) {\n return output + remaining\n }\n\n // Add the preceding text\n output += remaining.slice(0, r.lastIndex - 2)\n remaining = remaining.slice(r.lastIndex)\n\n // Add the format code\n const ch = results[0].charAt(1)\n const func = formatCodes[ch]\n output += func ? func.call(this, d) : '%' + ch\n }\n}\n","import strftime from './util/strftime.js'\nimport * as _ from './util/underscore.js'\nimport {isTruthy} from './syntax.js'\n\nconst escapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n}\nconst unescapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\"\n}\n\nconst filters = {\n 'abs': v => Math.abs(v),\n 'append': (v, arg) => v + arg,\n 'capitalize': str => stringify(str).charAt(0).toUpperCase() + str.slice(1),\n 'ceil': v => Math.ceil(v),\n 'concat': (v, arg) => Array.prototype.concat.call(v, arg),\n 'date': (v, arg) => {\n let date = v\n if (v === 'now') {\n date = new Date()\n } else if (_.isString(v)) {\n date = new Date(v)\n }\n return isValidDate(date) ? strftime(date, arg) : v\n },\n 'default': (v, arg) => isTruthy(v) ? v : arg,\n 'divided_by': (v, arg) => v / arg,\n 'downcase': v => v.toLowerCase(),\n 'escape': escape,\n\n 'escape_once': str => escape(unescape(str)),\n 'first': v => v[0],\n 'floor': v => Math.floor(v),\n 'join': (v, arg) => v.join(arg),\n 'last': v => _.last(v),\n 'lstrip': v => stringify(v).replace(/^\\s+/, ''),\n 'map': (arr, arg) => arr.map(v => v[arg]),\n 'minus': bindFixed((v, arg) => v - arg),\n 'modulo': bindFixed((v, arg) => v % arg),\n 'newline_to_br': v => v.replace(/\\n/g, '
'),\n 'plus': bindFixed((v, arg) => Number(v) + Number(arg)),\n 'prepend': (v, arg) => arg + v,\n 'remove': (v, arg) => v.split(arg).join(''),\n 'remove_first': (v, l) => v.replace(l, ''),\n 'replace': (v, pattern, replacement) =>\n stringify(v).split(pattern).join(replacement),\n 'replace_first': (v, arg1, arg2) => stringify(v).replace(arg1, arg2),\n 'reverse': v => v.reverse(),\n 'round': (v, arg) => {\n const amp = Math.pow(10, arg || 0)\n return Math.round(v * amp, arg) / amp\n },\n 'rstrip': str => stringify(str).replace(/\\s+$/, ''),\n 'size': v => v.length,\n 'slice': (v, begin, length) =>\n v.substr(begin, length === undefined ? 1 : length),\n 'sort': (v, arg) => v.sort(arg),\n 'split': (v, arg) => stringify(v).split(arg),\n 'strip': (v) => stringify(v).trim(),\n 'strip_html': v => stringify(v).replace(/|||<.*?>/g, ''),\n 'strip_newlines': v => stringify(v).replace(/\\n/g, ''),\n 'times': (v, arg) => v * arg,\n 'truncate': (v, l, o) => {\n v = stringify(v)\n o = (o === undefined) ? '...' : o\n l = l || 16\n if (v.length <= l) return v\n return v.substr(0, l - o.length) + o\n },\n 'truncatewords': (v, l, o) => {\n if (o === undefined) o = '...'\n const arr = v.split(' ')\n let ret = arr.slice(0, l).join(' ')\n if (arr.length > l) ret += o\n return ret\n },\n 'uniq': function (arr) {\n const u = {}\n return (arr || []).filter(val => {\n if (u.hasOwnProperty(val)) {\n return false\n }\n u[val] = true\n return true\n })\n },\n 'upcase': str => stringify(str).toUpperCase(),\n 'url_encode': encodeURIComponent\n}\n\nfunction escape (str) {\n return stringify(str).replace(/&|<|>|\"|'/g, m => escapeMap[m])\n}\n\nfunction unescape (str) {\n return stringify(str).replace(/&(amp|lt|gt|#34|#39);/g, m => unescapeMap[m])\n}\n\nfunction getFixed (v) {\n const p = (v + '').split('.')\n return (p.length > 1) ? p[1].length : 0\n}\n\nfunction getMaxFixed (l, r) {\n return Math.max(getFixed(l), getFixed(r))\n}\n\nfunction stringify (obj) {\n return obj + ''\n}\n\nfunction bindFixed (cb) {\n return (l, r) => {\n const f = getMaxFixed(l, r)\n return cb(l, r).toFixed(f)\n }\n}\n\nfunction isValidDate (date) {\n return date instanceof Date && !isNaN(date.getTime())\n}\n\nexport default function registerAll (liquid) {\n return _.forOwn(filters, (func, name) => liquid.registerFilter(name, func))\n}\n\nregisterAll.filters = filters\n","import 'regenerator-runtime/runtime'\nimport * as Scope from './scope'\nimport {get as httpGet} from './util/http.js'\nimport * as _ from './util/underscore.js'\nimport assert from './util/assert.js'\nimport * as tokenizer from './tokenizer.js'\nimport {statFileAsync, readFileAsync} from './util/fs.js'\nimport path from 'path'\nimport {valid as isValidUrl, extname, resolve} from './util/url.js'\nimport * as lexical from './lexical.js'\nimport Render from './render.js'\nimport Tag from './tag.js'\nimport Filter from './filter.js'\nimport Parser from './parser'\nimport {isTruthy, isFalsy, evalExp, evalValue} from './syntax.js'\nimport {anySeries} from './util/promise.js'\nimport {ParseError, TokenizationError, RenderBreakError, AssertionError} from './util/error.js'\nimport tags from './tags/index.js'\nimport filters from './filters.js'\n\nconst _engine = {\n init: function (tag, filter, options) {\n if (options.cache) {\n this.cache = {}\n }\n this.options = options\n this.tag = tag\n this.filter = filter\n this.parser = Parser(tag, filter)\n this.renderer = Render()\n\n tags(this, Liquid)\n filters(this, Liquid)\n\n return this\n },\n parse: function (html, filepath) {\n const tokens = tokenizer.parse(html, filepath, this.options)\n return this.parser.parse(tokens)\n },\n render: function (tpl, ctx, opts) {\n opts = _.assign({}, this.options, opts)\n const scope = Scope.factory(ctx, opts)\n return this.renderer.renderTemplates(tpl, scope)\n },\n parseAndRender: async function (html, ctx, opts) {\n const tpl = await this.parse(html)\n return this.render(tpl, ctx, opts)\n },\n renderFile: async function (filepath, ctx, opts) {\n opts = _.assign({}, opts)\n const templates = await this.getTemplate(filepath, opts.root)\n return this.render(templates, ctx, opts)\n },\n evalValue: function (str, scope) {\n const tpl = this.parser.parseValue(str.trim())\n return this.renderer.evalValue(tpl, scope)\n },\n registerFilter: function (name, filter) {\n return this.filter.register(name, filter)\n },\n registerTag: function (name, tag) {\n return this.tag.register(name, tag)\n },\n lookup: function (filepath, root) {\n root = this.options.root.concat(root || [])\n root = _.uniq(root)\n const paths = root.map(root => path.resolve(root, filepath))\n return anySeries(paths, async path => {\n try {\n await statFileAsync(path)\n return path\n } catch (e) {\n e.message = `${e.code}: Failed to lookup ${filepath} in: ${root}`\n throw e\n }\n })\n },\n getTemplate: function (filepath, root) {\n return typeof XMLHttpRequest === 'undefined'\n ? this.getTemplateFromFile(filepath, root)\n : this.getTemplateFromUrl(filepath, root)\n },\n getTemplateFromFile: async function (filepath, root) {\n if (!path.extname(filepath)) {\n filepath += this.options.extname\n }\n filepath = await this.lookup(filepath, root)\n return this.respectCache(filepath, async () => {\n const str = await readFileAsync(filepath)\n return this.parse(str, filepath)\n })\n },\n getTemplateFromUrl: async function (filepath, root) {\n let fullUrl\n if (isValidUrl(filepath)) {\n fullUrl = filepath\n } else {\n if (!extname(filepath)) {\n filepath += this.options.extname\n }\n fullUrl = resolve(root || this.options.root, filepath)\n }\n return this.respectCache(\n filepath,\n async () => this.parse(await httpGet(fullUrl))\n )\n },\n respectCache: async function (key, getter) {\n const cacheEnabled = this.options.cache\n if (cacheEnabled && this.cache[key]) {\n return this.cache[key]\n }\n const value = await getter()\n if (cacheEnabled) {\n this.cache[key] = value\n }\n return value\n },\n express: function (opts) {\n opts = opts || {}\n const self = this\n return function (filePath, ctx, cb) {\n assert(Array.isArray(this.root) || _.isString(this.root),\n 'illegal views root, are you using express.js?')\n opts.root = this.root\n self.renderFile(filePath, ctx, opts).then(html => cb(null, html), cb)\n }\n }\n}\n\nfunction normalizeStringArray (value) {\n if (Array.isArray(value)) return value\n if (_.isString(value)) return [value]\n return []\n}\n\nexport default function Liquid (options) {\n options = _.assign({\n root: ['.'],\n cache: false,\n extname: '',\n dynamicPartials: true,\n trim_tag_right: false,\n trim_tag_left: false,\n trim_value_right: false,\n trim_value_left: false,\n greedy: true,\n strict_filters: false,\n strict_variables: false\n }, options)\n options.root = normalizeStringArray(options.root)\n\n const engine = Object.create(_engine)\n engine.init(Tag(), Filter(options), options)\n return engine\n}\n\nLiquid.isTruthy = isTruthy\nLiquid.isFalsy = isFalsy\nLiquid.evalExp = evalExp\nLiquid.evalValue = evalValue\nLiquid.Types = {\n ParseError,\n TokenizationError,\n RenderBreakError,\n AssertionError,\n AssignScope: Object.create(null),\n CaptureScope: Object.create(null),\n IncrementScope: Object.create(null),\n DecrementScope: Object.create(null)\n}\nLiquid.lexical = lexical\n","import * as lexical from './lexical.js'\nimport {ParseError} from './util/error.js'\nimport assert from './util/assert.js'\n\nexport default function (Tag, Filter) {\n const stream = {\n init: function (tokens) {\n this.tokens = tokens\n this.handlers = {}\n return this\n },\n on: function (name, cb) {\n this.handlers[name] = cb\n return this\n },\n trigger: function (event, arg) {\n const h = this.handlers[event]\n if (typeof h === 'function') {\n h(arg)\n return true\n }\n },\n start: function () {\n this.trigger('start')\n let token\n while (!this.stopRequested && (token = this.tokens.shift())) {\n if (this.trigger('token', token)) continue\n if (token.type === 'tag' &&\n this.trigger(`tag:${token.name}`, token)) {\n continue\n }\n const template = parseToken(token, this.tokens)\n this.trigger('template', template)\n }\n if (!this.stopRequested) this.trigger('end')\n return this\n },\n stop: function () {\n this.stopRequested = true\n return this\n }\n }\n\n function parse (tokens) {\n let token\n const templates = []\n while ((token = tokens.shift())) {\n templates.push(parseToken(token, tokens))\n }\n return templates\n }\n\n function parseToken (token, tokens) {\n try {\n let tpl = null\n if (token.type === 'tag') {\n tpl = parseTag(token, tokens)\n } else if (token.type === 'value') {\n tpl = parseValue(token.value)\n } else { // token.type === 'html'\n tpl = token\n }\n tpl.token = token\n return tpl\n } catch (e) {\n throw new ParseError(e, token)\n }\n }\n\n function parseTag (token, tokens) {\n if (token.name === 'continue' || token.name === 'break') return token\n return Tag.construct(token, tokens)\n }\n\n function parseValue (str) {\n let match = lexical.matchValue(str)\n assert(match, `illegal value string: ${str}`)\n\n const initial = match[0]\n str = str.substr(match.index + match[0].length)\n\n const filters = []\n while ((match = lexical.filter.exec(str))) {\n filters.push([match[0].trim()])\n }\n\n return {\n type: 'value',\n initial: initial,\n filters: filters.map(str => Filter.construct(str))\n }\n }\n\n function parseStream (tokens) {\n const s = Object.create(stream)\n return s.init(tokens)\n }\n\n return {\n parse,\n parseTag,\n parseStream,\n parseValue\n }\n}\n"],"names":["global","undefined","Op","Object","prototype","hasOwn","hasOwnProperty","$Symbol","Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","toStringTag","inModule","module","runtime","regeneratorRuntime","exports","wrap","GenStateSuspendedStart","GenStateSuspendedYield","GenStateExecuting","GenStateCompleted","ContinueSentinel","IteratorPrototype","this","getProto","getPrototypeOf","NativeIteratorPrototype","values","call","Gp","GeneratorFunctionPrototype","Generator","create","constructor","GeneratorFunction","displayName","isGeneratorFunction","genFun","ctor","name","mark","setPrototypeOf","__proto__","awrap","arg","__await","AsyncIterator","async","innerFn","outerFn","self","tryLocsList","iter","next","then","result","done","value","toString","keys","object","key","push","reverse","length","pop","Context","skipTempReset","prev","sent","_sent","delegate","method","tryEntries","forEach","resetTryEntry","charAt","isNaN","slice","rootRecord","completion","type","rval","exception","context","handle","loc","caught","i","entry","record","tryLoc","hasCatch","hasFinally","catchLoc","finallyLoc","Error","finallyEntry","complete","afterLoc","thrown","iterable","resultName","nextLoc","state","protoGenerator","generator","_invoke","doneResult","delegateResult","maybeInvokeDelegate","dispatchException","abrupt","tryCatch","fn","obj","err","defineIteratorMethods","previousPromise","callInvokeWithMethodAndArg","Promise","resolve","reject","invoke","unwrapped","error","return","TypeError","info","pushTryEntry","locs","reset","iteratorMethod","Function","toStr","isString","stringify","isNil","String","to_liquid","toLiquid","cache","JSON","isObject","indexOf","isArray","assign","Array","arguments","src","last","arr","quoted","RegExp","source","quoteBalanced","integer","number","bool","identifier","subscript","literal","variable","rangeLimit","range","rangeCapture","hash","hashCapture","tagLine","literalLine","variableLine","numberLine","boolLine","quotedLine","rangeLine","integerLine","valueDeclaration","valueList","filter","filterCapture","filterLine","operators","isInteger","str","test","isLiteral","isVariable","matchValue","exec","parseLiteral","res","match","Number","toLowerCase","initError","captureStackTrace","initLiquidError","token","input","line","file","lines","begin","end","split","Math","max","min","start","stop","step","_","map","l","n","join","message","msg","mkMessage","stack","TokenizationError","ParseError","e","originalError","RenderError","tpl","RenderBreakError","AssertionError","predicate","Scope","contexts","reduce","ctx","val","path","paths","propertyAccessSeq","scope","findContextFor","_this","readProperty","v","some","unshift","findIndex","splice","candidate","opts","strict_variables","seq","j","delemiter","matchRightBracket","lexical","get","url","xhr","XMLHttpRequest","onload","status","responseText","statusText","onerror","open","send","parse","options","html","parsedLinesCount","lastMatchBegin","raw","pos","rLiquid","currIndent","lineNumber","lastMatchEnd","tokens","lastIndex","index","parseHTMLToken","parseTagToken","trim","greedy","inRaw","trim_left","trim_tag_left","trim_value_left","rLeft","replace","trim_right","trim_tag_right","trim_value_right","rRight","args","htmlFragment","readFileAsync","filepath","readFile","content","statFileAsync","stat","splitPathRe","urlRe","root","base","document","createElement","href","head","getElementsByTagName","insertBefore","firstChild","a","resolved","removeChild","resolveUrl","isTruthy","r","evalExp","exp","operatorREs","operatorRE","expRE","op","low","evalValue","high","isFalsy","render","templates","template","renderTag","partial","renderValue","renderTemplate","_context2","resolvedHTML","filters","initial","markup","k","valueRE","mapSeries","iteratee","ret","item","idx","x","staticFileRE","engine","Liquid","liquid","rIdentifier","re","AssignScope","CaptureScope","rValue","groupRE","candidatesRE","DecrementScope","withRE","IncrementScope","Types","registerTag","tagToken","remainTokens","stream","parser","parseStream","on","renderer","renderTemplates","cond","cases","elseTemplates","p","branch","group","candidates","fingerprint","groups","collection","offset","limit","reversed","_this2","forloop","finished","_context","branches","staticValue","with","dynamicPartials","parseAndRender","getAll","blocks","blockMode","getTemplate","originBlocks","originBlockMode","staticLayout","layout","tpls","block","childDefined","cols","floor","row","col","monthNames","monthNamesShort","dayNames","dayNamesShort","suffixes","_date","d","isLeapYear","num","getMonth","daysInMonth","getDate","startDay","now","getDayOfYear","getDay","Date","getFullYear","_number","pad","year","parseInt","substring","size","ch","formatCodes","toLocaleString","century","getHours","getMilliseconds","getMinutes","getSuffix","round","valueOf","getSeconds","getWeekOfYear","toLocaleDateString","toLocaleTimeString","tz","getTimezoneOffset","abs","h","b","N","L","escapeMap","unescapeMap","toUpperCase","ceil","concat","date","getTime","format","output","remaining","results","func","strftime","escape","m","bindFixed","pattern","replacement","arg1","arg2","amp","pow","substr","sort","o","u","encodeURIComponent","getFixed","cb","f","toFixed","registerAll","registerFilter","_engine","tag","Tag","Filter","handlers","event","trigger","stopRequested","shift","parseToken","parseTag","parseValue","construct","init","Parser","tokenizer","register","_context3","code","catch","getTemplateFromFile","getTemplateFromUrl","extname","lookup","respectCache","_this3","httpGet","fullUrl","getter","cacheEnabled","filePath","renderFile","tagImpls","_tagInstance","tagImpl","impl","instance","_filterInstance","apply","argList","strict_filters","keyMatch","clear"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index 55e88739b..c7393675c 100644 --- a/package.json +++ b/package.json @@ -2,16 +2,14 @@ "name": "liquidjs", "version": "5.3.0-0", "description": "Liquid template engine by pure JavaScript: compatible to shopify, easy to extend.", - "main": "build/index.js", + "main": "dist/liquid.common.js", + "module": "src/index.js", "scripts": { - "lint": "eslint .", + "lint": "eslint src/ test/", "test": "mocha --require babel-core/register --recursive", "coverage": "nyc report --require babel-core/register mocha test/ --recursive ", "coveralls": "nyc report --reporter=text-lcov --require babel-core/register mocha test/ --recursive | coveralls", - "dist": "npm run babelify && npm run browserify && npm run uglify", - "babelify": "babel src -d build", - "browserify": "browserify src/index.js -s Liquid --ignore path -t [ babelify --presets [ es2015 ] ] > dist/liquid.js", - "uglify": "uglifyjs dist/liquid.js --compress warnings=false --mangle toplevel --output dist/liquid.min.js", + "dist": "rollup -c && ls -lh dist", "demo:browser": "echo open http://localhost:8080/demo/browser && http-server -c-1", "demo:nodejs": "node ./demo/nodejs/index.js", "demo:express": "cd ./demo/express/ && npm start", @@ -39,21 +37,15 @@ "url": "https://github.com/harttle/liquidjs/issues" }, "homepage": "https://github.com/harttle/liquidjs#readme", - "dependencies": { - "resolve-url": "^0.2.1" - }, - "browser": { - "fs": false - }, "devDependencies": { "babel-core": "^6.26.3", + "babel-plugin-external-helpers": "^6.22.0", + "babel-plugin-transform-runtime": "^6.23.0", + "babel-preset-env": "^1.7.0", "babel-preset-es2015": "^6.24.1", - "babelify": "^8.0.0", - "browserify": "^16.2.2", "chai": "^4.1.2", "chai-as-promised": "^7.1.1", "coveralls": "^3.0.0", - "cross-env": "^5.1.3", "eslint": "^5.2.0", "eslint-config-standard": "^11.0.0", "eslint-plugin-import": "^2.7.0", @@ -63,14 +55,18 @@ "eslint-plugin-standard": "^3.0.1", "express": "^4.16.1", "http-server": "^0.11.1", - "istanbul": "^0.4.5", "jsdom": "^11.5.1", "mocha": "^5.2.0", "mock-fs": "^4.4.1", "nyc": "^12.0.2", + "regenerator-runtime": "^0.12.1", + "rollup": "^0.64.1", + "rollup-plugin-babel": "^3.0.7", + "rollup-plugin-node-resolve": "^3.3.0", + "rollup-plugin-shim": "^1.0.0", + "rollup-plugin-uglify": "^4.0.0", "sinon": "^6.1.4", "sinon-chai": "^3.2.0", - "supertest": "^3.0.0", - "uglify-js": "^3.4.5" + "supertest": "^3.0.0" } } diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 000000000..995214cb5 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,71 @@ +import shim from 'rollup-plugin-shim' +import babel from 'rollup-plugin-babel' +import {uglify} from 'rollup-plugin-uglify' +import pkg from './package.json' +import nodeResolve from 'rollup-plugin-node-resolve' + +const fake = {fs: `export default {}`, path: `export default {}`} +const version = process.env.VERSION || pkg.version +const sourcemap = true +const banner = `/* + * liquidjs@${version}, https://github.com/liquidjs + * (c) 2016-${new Date().getFullYear()} harttle + * Released under the MIT License. + */` +const treeshake = { + propertyReadSideEffects: false +} +const input = 'src/index.js' + +const babelConf = { + babelrc: false, + 'presets': [['env', {'modules': false}]], + 'plugins': ['external-helpers'] +} + +export default [{ + output: [{ + file: 'dist/liquid.common.js', + name: 'Liquid', + format: 'cjs', + sourcemap, + banner + }], + external: ['path', 'fs'], + plugins: [ + nodeResolve(), + babel(babelConf) + ], + treeshake, + input +}, { + output: [{ + file: 'dist/liquid.js', + name: 'Liquid', + format: 'umd', + sourcemap, + banner + }], + plugins: [ + shim(fake), + nodeResolve(), + babel(babelConf) + ], + treeshake, + input +}, { + output: [{ + file: 'dist/liquid.min.js', + name: 'Liquid', + format: 'umd', + sourcemap + }], + plugins: [ + shim(fake), + nodeResolve(), + babel(babelConf), + uglify() + ], + treeshake, + input +}] diff --git a/src/filter.js b/src/filter.js index 45f5ee9cf..5644b7cea 100644 --- a/src/filter.js +++ b/src/filter.js @@ -1,17 +1,17 @@ -const lexical = require('./lexical.js') -const Syntax = require('./syntax.js') -const assert = require('./util/assert.js') -const _ = require('./util/underscore.js') +import * as lexical from './lexical.js' +import {evalValue} from './syntax.js' +import assert from './util/assert.js' +import {assign} from './util/underscore.js' -let valueRE = new RegExp(`${lexical.value.source}`, 'g') +const valueRE = new RegExp(`${lexical.value.source}`, 'g') -module.exports = function (options) { - options = _.assign({}, options) +export default function (options) { + options = assign({}, options) let filters = {} - let _filterInstance = { + const _filterInstance = { render: function (output, scope) { - let args = this.args.map(arg => Syntax.evalValue(arg, scope)) + const args = this.args.map(arg => evalValue(arg, scope)) args.unshift(output) return this.filter.apply(null, args) }, @@ -19,9 +19,9 @@ module.exports = function (options) { let match = lexical.filterLine.exec(str) assert(match, 'illegal filter: ' + str) - let name = match[1] - let argList = match[2] || '' - let filter = filters[name] + const name = match[1] + const argList = match[2] || '' + const filter = filters[name] if (typeof filter !== 'function') { if (options.strict_filters) { throw new TypeError(`undefined filter: ${name}`) @@ -32,12 +32,12 @@ module.exports = function (options) { return this } - let args = [] + const args = [] while ((match = valueRE.exec(argList.trim()))) { - let v = match[0] - let re = new RegExp(`${v}\\s*:`, 'g') - let keyMatch = re.exec(match.input) - let currentMatchIsKey = keyMatch && keyMatch.index === match.index + const v = match[0] + const re = new RegExp(`${v}\\s*:`, 'g') + const keyMatch = re.exec(match.input) + const currentMatchIsKey = keyMatch && keyMatch.index === match.index currentMatchIsKey ? args.push(`'${v}'`) : args.push(v) } @@ -50,7 +50,7 @@ module.exports = function (options) { } function construct (str) { - let instance = Object.create(_filterInstance) + const instance = Object.create(_filterInstance) return instance.parse(str) } diff --git a/src/filters.js b/src/filters.js index 2bac7a072..50aeb167c 100644 --- a/src/filters.js +++ b/src/filters.js @@ -1,16 +1,15 @@ -'use strict' -const strftime = require('./util/strftime.js') -const _ = require('./util/underscore.js') -const isTruthy = require('./syntax.js').isTruthy +import strftime from './util/strftime.js' +import * as _ from './util/underscore.js' +import {isTruthy} from './syntax.js' -let escapeMap = { +const escapeMap = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' } -let unescapeMap = { +const unescapeMap = { '&': '&', '<': '<', '>': '>', @@ -18,7 +17,7 @@ let unescapeMap = { ''': "'" } -let filters = { +const filters = { 'abs': v => Math.abs(v), 'append': (v, arg) => v + arg, 'capitalize': str => stringify(str).charAt(0).toUpperCase() + str.slice(1), @@ -57,7 +56,7 @@ let filters = { 'replace_first': (v, arg1, arg2) => stringify(v).replace(arg1, arg2), 'reverse': v => v.reverse(), 'round': (v, arg) => { - let amp = Math.pow(10, arg || 0) + const amp = Math.pow(10, arg || 0) return Math.round(v * amp, arg) / amp }, 'rstrip': str => stringify(str).replace(/\s+$/, ''), @@ -79,13 +78,13 @@ let filters = { }, 'truncatewords': (v, l, o) => { if (o === undefined) o = '...' - let arr = v.split(' ') + const arr = v.split(' ') let ret = arr.slice(0, l).join(' ') if (arr.length > l) ret += o return ret }, 'uniq': function (arr) { - let u = {} + const u = {} return (arr || []).filter(val => { if (u.hasOwnProperty(val)) { return false @@ -107,7 +106,7 @@ function unescape (str) { } function getFixed (v) { - let p = (v + '').split('.') + const p = (v + '').split('.') return (p.length > 1) ? p[1].length : 0 } @@ -121,18 +120,17 @@ function stringify (obj) { function bindFixed (cb) { return (l, r) => { - let f = getMaxFixed(l, r) + const f = getMaxFixed(l, r) return cb(l, r).toFixed(f) } } -function registerAll (liquid) { - return _.forOwn(filters, (func, name) => liquid.registerFilter(name, func)) -} - function isValidDate (date) { return date instanceof Date && !isNaN(date.getTime()) } +export default function registerAll (liquid) { + return _.forOwn(filters, (func, name) => liquid.registerFilter(name, func)) +} + registerAll.filters = filters -module.exports = registerAll diff --git a/src/index.js b/src/index.js index 7304a2350..80b357260 100644 --- a/src/index.js +++ b/src/index.js @@ -1,22 +1,24 @@ -import Scope from './scope' -import _ from './util/underscore.js' +import 'regenerator-runtime/runtime' +import * as Scope from './scope' +import {get as httpGet} from './util/http.js' +import * as _ from './util/underscore.js' import assert from './util/assert.js' -import tokenizer from './tokenizer.js' +import * as tokenizer from './tokenizer.js' import {statFileAsync, readFileAsync} from './util/fs.js' import path from 'path' import {valid as isValidUrl, extname, resolve} from './util/url.js' -import lexical from './lexical.js' +import * as lexical from './lexical.js' import Render from './render.js' import Tag from './tag.js' import Filter from './filter.js' import Parser from './parser' import {isTruthy, isFalsy, evalExp, evalValue} from './syntax.js' -import tags from './tags' -import filters from './filters' import {anySeries} from './util/promise.js' -import {ParseError, TokenizationEroor, RenderBreakError, AssertionError} from './util/error.js' +import {ParseError, TokenizationError, RenderBreakError, AssertionError} from './util/error.js' +import tags from './tags/index.js' +import filters from './filters.js' -let _engine = { +const _engine = { init: function (tag, filter, options) { if (options.cache) { this.cache = {} @@ -27,32 +29,31 @@ let _engine = { this.parser = Parser(tag, filter) this.renderer = Render() - tags(this) - filters(this) + tags(this, Liquid) + filters(this, Liquid) return this }, parse: function (html, filepath) { - let tokens = tokenizer.parse(html, filepath, this.options) + const tokens = tokenizer.parse(html, filepath, this.options) return this.parser.parse(tokens) }, render: function (tpl, ctx, opts) { opts = _.assign({}, this.options, opts) - let scope = Scope.factory(ctx, opts) + const scope = Scope.factory(ctx, opts) return this.renderer.renderTemplates(tpl, scope) }, - parseAndRender: function (html, ctx, opts) { - return Promise.resolve() - .then(() => this.parse(html)) - .then(tpl => this.render(tpl, ctx, opts)) + parseAndRender: async function (html, ctx, opts) { + const tpl = await this.parse(html) + return this.render(tpl, ctx, opts) }, - renderFile: function (filepath, ctx, opts) { + renderFile: async function (filepath, ctx, opts) { opts = _.assign({}, opts) - return this.getTemplate(filepath, opts.root) - .then(templates => this.render(templates, ctx, opts)) + const templates = await this.getTemplate(filepath, opts.root) + return this.render(templates, ctx, opts) }, evalValue: function (str, scope) { - let tpl = this.parser.parseValue(str.trim()) + const tpl = this.parser.parseValue(str.trim()) return this.renderer.evalValue(tpl, scope) }, registerFilter: function (name, filter) { @@ -64,39 +65,33 @@ let _engine = { lookup: function (filepath, root) { root = this.options.root.concat(root || []) root = _.uniq(root) - let paths = root.map(root => path.resolve(root, filepath)) - return anySeries(paths, path => statFileAsync(path).then(() => path)) - .catch((e) => { + const paths = root.map(root => path.resolve(root, filepath)) + return anySeries(paths, async path => { + try { + await statFileAsync(path) + return path + } catch (e) { e.message = `${e.code}: Failed to lookup ${filepath} in: ${root}` throw e - }) + } + }) }, getTemplate: function (filepath, root) { return typeof XMLHttpRequest === 'undefined' ? this.getTemplateFromFile(filepath, root) : this.getTemplateFromUrl(filepath, root) }, - getTemplateFromFile: function (filepath, root) { + getTemplateFromFile: async function (filepath, root) { if (!path.extname(filepath)) { filepath += this.options.extname } - return this - .lookup(filepath, root) - .then(filepath => { - if (this.options.cache) { - let tpl = this.cache[filepath] - if (tpl) { - return Promise.resolve(tpl) - } - return readFileAsync(filepath) - .then(str => this.parse(str)) - .then(tpl => (this.cache[filepath] = tpl)) - } else { - return readFileAsync(filepath).then(str => this.parse(str, filepath)) - } - }) + filepath = await this.lookup(filepath, root) + return this.respectCache(filepath, async () => { + const str = await readFileAsync(filepath) + return this.parse(str, filepath) + }) }, - getTemplateFromUrl: function (filepath, root) { + getTemplateFromUrl: async function (filepath, root) { let fullUrl if (isValidUrl(filepath)) { fullUrl = filepath @@ -106,47 +101,41 @@ let _engine = { } fullUrl = resolve(root || this.options.root, filepath) } - if (this.options.cache) { - let tpl = this.cache[filepath] - if (tpl) { - return Promise.resolve(tpl) - } + return this.respectCache( + filepath, + async () => this.parse(await httpGet(fullUrl)) + ) + }, + respectCache: async function (key, getter) { + const cacheEnabled = this.options.cache + if (cacheEnabled && this.cache[key]) { + return this.cache[key] } - return new Promise((resolve, reject) => { - let xhr = new XMLHttpRequest() - xhr.onload = () => { - if (xhr.status >= 200 && xhr.status < 300) { - let tpl = this.parse(xhr.responseText) - if (this.options.cache) { - this.cache[filepath] = tpl - } - resolve(tpl) - } else { - reject(new Error(xhr.statusText)) - } - } - xhr.onerror = () => { - reject(new Error('An error occurred whilst sending the response.')) - } - xhr.open('GET', fullUrl) - xhr.send() - }) + const value = await getter() + if (cacheEnabled) { + this.cache[key] = value + } + return value }, express: function (opts) { opts = opts || {} - let self = this - return function (filePath, ctx, callback) { + const self = this + return function (filePath, ctx, cb) { assert(Array.isArray(this.root) || _.isString(this.root), 'illegal views root, are you using express.js?') opts.root = this.root - self.renderFile(filePath, ctx, opts) - .then(html => callback(null, html)) - .catch(e => callback(e)) + self.renderFile(filePath, ctx, opts).then(html => cb(null, html), cb) } } } -function factory (options) { +function normalizeStringArray (value) { + if (Array.isArray(value)) return value + if (_.isString(value)) return [value] + return [] +} + +export default function Liquid (options) { options = _.assign({ root: ['.'], cache: false, @@ -162,29 +151,23 @@ function factory (options) { }, options) options.root = normalizeStringArray(options.root) - let engine = Object.create(_engine) + const engine = Object.create(_engine) engine.init(Tag(), Filter(options), options) return engine } -function normalizeStringArray (value) { - if (Array.isArray(value)) return value - if (_.isString(value)) return [value] - return [] -} - -const Types = { +Liquid.isTruthy = isTruthy +Liquid.isFalsy = isFalsy +Liquid.evalExp = evalExp +Liquid.evalValue = evalValue +Liquid.Types = { ParseError, - TokenizationEroor, + TokenizationError, RenderBreakError, - AssertionError + AssertionError, + AssignScope: Object.create(null), + CaptureScope: Object.create(null), + IncrementScope: Object.create(null), + DecrementScope: Object.create(null) } - -factory.isTruthy = isTruthy -factory.isFalsy = isFalsy -factory.evalExp = evalExp -factory.evalValue = evalValue -factory.Types = Types -factory.lexical = lexical - -module.exports = factory +Liquid.lexical = lexical diff --git a/src/lexical.js b/src/lexical.js index 2a10c1b9e..649576dee 100644 --- a/src/lexical.js +++ b/src/lexical.js @@ -1,75 +1,75 @@ // quote related -let singleQuoted = /'[^']*'/ -let doubleQuoted = /"[^"]*"/ -let quoted = new RegExp(`${singleQuoted.source}|${doubleQuoted.source}`) -let quoteBalanced = new RegExp(`(?:${quoted.source}|[^'"])*`) +const singleQuoted = /'[^']*'/ +const doubleQuoted = /"[^"]*"/ +export const quoted = new RegExp(`${singleQuoted.source}|${doubleQuoted.source}`) +export const quoteBalanced = new RegExp(`(?:${quoted.source}|[^'"])*`) // basic types -let integer = /-?\d+/ -let number = /-?\d+\.?\d*|\.?\d+/ -let bool = /true|false/ +export const integer = /-?\d+/ +export const number = /-?\d+\.?\d*|\.?\d+/ +export const bool = /true|false/ // peoperty access -let identifier = /[\w-]+[?]?/ -let subscript = new RegExp(`\\[(?:${quoted.source}|[\\w-\\.]+)\\]`) -let literal = new RegExp(`(?:${quoted.source}|${bool.source}|${number.source})`) -let variable = new RegExp(`${identifier.source}(?:\\.${identifier.source}|${subscript.source})*`) +export const identifier = /[\w-]+[?]?/ +export const subscript = new RegExp(`\\[(?:${quoted.source}|[\\w-\\.]+)\\]`) +export const literal = new RegExp(`(?:${quoted.source}|${bool.source}|${number.source})`) +export const variable = new RegExp(`${identifier.source}(?:\\.${identifier.source}|${subscript.source})*`) // range related -let rangeLimit = new RegExp(`(?:${variable.source}|${number.source})`) -let range = new RegExp(`\\(${rangeLimit.source}\\.\\.${rangeLimit.source}\\)`) -let rangeCapture = new RegExp(`\\((${rangeLimit.source})\\.\\.(${rangeLimit.source})\\)`) +export const rangeLimit = new RegExp(`(?:${variable.source}|${number.source})`) +export const range = new RegExp(`\\(${rangeLimit.source}\\.\\.${rangeLimit.source}\\)`) +export const rangeCapture = new RegExp(`\\((${rangeLimit.source})\\.\\.(${rangeLimit.source})\\)`) -let value = new RegExp(`(?:${variable.source}|${literal.source}|${range.source})`) +export const value = new RegExp(`(?:${variable.source}|${literal.source}|${range.source})`) // hash related -let hash = new RegExp(`(?:${identifier.source})\\s*:\\s*(?:${value.source})`) -let hashCapture = new RegExp(`(${identifier.source})\\s*:\\s*(${value.source})`, 'g') +export const hash = new RegExp(`(?:${identifier.source})\\s*:\\s*(?:${value.source})`) +export const hashCapture = new RegExp(`(${identifier.source})\\s*:\\s*(${value.source})`, 'g') // full match -let tagLine = new RegExp(`^\\s*(${identifier.source})\\s*([\\s\\S]*)\\s*$`) -let literalLine = new RegExp(`^${literal.source}$`, 'i') -let variableLine = new RegExp(`^${variable.source}$`) -let numberLine = new RegExp(`^${number.source}$`) -let boolLine = new RegExp(`^${bool.source}$`, 'i') -let quotedLine = new RegExp(`^${quoted.source}$`) -let rangeLine = new RegExp(`^${rangeCapture.source}$`) -let integerLine = new RegExp(`^${integer.source}$`) +export const tagLine = new RegExp(`^\\s*(${identifier.source})\\s*([\\s\\S]*)\\s*$`) +export const literalLine = new RegExp(`^${literal.source}$`, 'i') +export const variableLine = new RegExp(`^${variable.source}$`) +export const numberLine = new RegExp(`^${number.source}$`) +export const boolLine = new RegExp(`^${bool.source}$`, 'i') +export const quotedLine = new RegExp(`^${quoted.source}$`) +export const rangeLine = new RegExp(`^${rangeCapture.source}$`) +export const integerLine = new RegExp(`^${integer.source}$`) // filter related -let valueDeclaration = new RegExp(`(?:${identifier.source}\\s*:\\s*)?${value.source}`) -let valueList = new RegExp(`${valueDeclaration.source}(\\s*,\\s*${valueDeclaration.source})*`) -let filter = new RegExp(`${identifier.source}(?:\\s*:\\s*${valueList.source})?`, 'g') -let filterCapture = new RegExp(`(${identifier.source})(?:\\s*:\\s*(${valueList.source}))?`) -let filterLine = new RegExp(`^${filterCapture.source}$`) +export const valueDeclaration = new RegExp(`(?:${identifier.source}\\s*:\\s*)?${value.source}`) +export const valueList = new RegExp(`${valueDeclaration.source}(\\s*,\\s*${valueDeclaration.source})*`) +export const filter = new RegExp(`${identifier.source}(?:\\s*:\\s*${valueList.source})?`, 'g') +export const filterCapture = new RegExp(`(${identifier.source})(?:\\s*:\\s*(${valueList.source}))?`) +export const filterLine = new RegExp(`^${filterCapture.source}$`) -let operators = [ +export const operators = [ /\s+or\s+/, /\s+and\s+/, /==|!=|<=|>=|<|>|\s+contains\s+/ ] -function isInteger (str) { +export function isInteger (str) { return integerLine.test(str) } -function isLiteral (str) { +export function isLiteral (str) { return literalLine.test(str) } -function isRange (str) { +export function isRange (str) { return rangeLine.test(str) } -function isVariable (str) { +export function isVariable (str) { return variableLine.test(str) } -function matchValue (str) { +export function matchValue (str) { return value.exec(str) } -function parseLiteral (str) { +export function parseLiteral (str) { let res = str.match(numberLine) if (res) { return Number(str) @@ -84,33 +84,3 @@ function parseLiteral (str) { } throw new TypeError(`cannot parse '${str}' as literal`) } - -module.exports = { - quoted, - number, - bool, - literal, - filter, - integer, - hash, - hashCapture, - range, - rangeCapture, - identifier, - value, - quoteBalanced, - operators, - quotedLine, - numberLine, - boolLine, - rangeLine, - literalLine, - filterLine, - tagLine, - isLiteral, - isVariable, - parseLiteral, - isRange, - matchValue, - isInteger -} diff --git a/src/operators.js b/src/operators.js index 646710f32..cff09fe43 100644 --- a/src/operators.js +++ b/src/operators.js @@ -1,4 +1,4 @@ -module.exports = function (isTruthy) { +export default function (isTruthy) { return { '==': (l, r) => l === r, '!=': (l, r) => l !== r, diff --git a/src/parser.js b/src/parser.js index 38da3782f..3bcab6e19 100644 --- a/src/parser.js +++ b/src/parser.js @@ -1,9 +1,9 @@ -const lexical = require('./lexical.js') -const ParseError = require('./util/error.js').ParseError -const assert = require('./util/assert.js') +import * as lexical from './lexical.js' +import {ParseError} from './util/error.js' +import assert from './util/assert.js' -module.exports = function (Tag, Filter) { - let stream = { +export default function (Tag, Filter) { + const stream = { init: function (tokens) { this.tokens = tokens this.handlers = {} @@ -14,7 +14,7 @@ module.exports = function (Tag, Filter) { return this }, trigger: function (event, arg) { - let h = this.handlers[event] + const h = this.handlers[event] if (typeof h === 'function') { h(arg) return true @@ -29,7 +29,7 @@ module.exports = function (Tag, Filter) { this.trigger(`tag:${token.name}`, token)) { continue } - let template = parseToken(token, this.tokens) + const template = parseToken(token, this.tokens) this.trigger('template', template) } if (!this.stopRequested) this.trigger('end') @@ -43,7 +43,7 @@ module.exports = function (Tag, Filter) { function parse (tokens) { let token - let templates = [] + const templates = [] while ((token = tokens.shift())) { templates.push(parseToken(token, tokens)) } @@ -76,10 +76,10 @@ module.exports = function (Tag, Filter) { let match = lexical.matchValue(str) assert(match, `illegal value string: ${str}`) - let initial = match[0] + const initial = match[0] str = str.substr(match.index + match[0].length) - let filters = [] + const filters = [] while ((match = lexical.filter.exec(str))) { filters.push([match[0].trim()]) } @@ -92,7 +92,7 @@ module.exports = function (Tag, Filter) { } function parseStream (tokens) { - let s = Object.create(stream) + const s = Object.create(stream) return s.init(tokens) } diff --git a/src/render.js b/src/render.js index b7c1e818a..87977e62f 100644 --- a/src/render.js +++ b/src/render.js @@ -1,67 +1,62 @@ -const Syntax = require('./syntax.js') -const mapSeries = require('./util/promise.js').mapSeries -const RenderBreakError = require('./util/error.js').RenderBreakError -const _ = require('./util/underscore.js') -const RenderError = require('./util/error.js').RenderError -const assert = require('./util/assert.js') +import {evalExp} from './syntax.js' +import {RenderBreakError, RenderError} from './util/error.js' +import {stringify} from './util/underscore.js' +import assert from './util/assert.js' -let render = { - - renderTemplates: function (templates, scope) { +const render = { + renderTemplates: async function (templates, scope) { assert(scope, 'unable to evalTemplates: scope undefined') let html = '' - return mapSeries(templates, (tpl) => { - return renderTemplate.call(this, tpl) - .then(partial => (html += partial)) - .catch(e => { - if (e instanceof RenderBreakError) { - e.resolvedHTML = html - throw e - } - throw new RenderError(e, tpl) - }) - }).then(() => html) - - function renderTemplate (template) { - if (template.type === 'tag') { - return this.renderTag(template, scope) - .then(partial => partial === undefined ? '' : partial) - } else if (template.type === 'value') { - return this.renderValue(template, scope) - } else { // template.type === 'html' - return Promise.resolve(template.value) + for (const tpl of templates) { + try { + html += await renderTemplate.call(this, tpl) + } catch (e) { + if (e instanceof RenderBreakError) { + e.resolvedHTML = html + throw e + } + throw new RenderError(e, tpl) } } + return html + + async function renderTemplate (template) { + if (template.type === 'tag') { + const partial = await this.renderTag(template, scope) + return partial === undefined ? '' : partial + } + if (template.type === 'value') { + return this.renderValue(template, scope) + } + return template.value + } }, - renderTag: function (template, scope) { + renderTag: async function (template, scope) { if (template.name === 'continue') { - return Promise.reject(new RenderBreakError('continue')) + throw new RenderBreakError('continue') } if (template.name === 'break') { - return Promise.reject(new RenderBreakError('break')) + throw new RenderBreakError('break') } return template.render(scope) }, - renderValue: function (template, scope) { - return Promise.resolve() - .then(() => this.evalValue(template, scope)) - .then(partial => partial === undefined ? '' : _.stringify(partial)) + renderValue: async function (template, scope) { + const partial = this.evalValue(template, scope) + return partial === undefined ? '' : stringify(partial) }, evalValue: function (template, scope) { assert(scope, 'unable to evalValue: scope undefined') return template.filters.reduce( (prev, filter) => filter.render(prev, scope), - Syntax.evalExp(template.initial, scope)) + evalExp(template.initial, scope)) } } -function factory () { - let instance = Object.create(render) +export default function () { + const instance = Object.create(render) return instance } - -module.exports = factory diff --git a/src/scope.js b/src/scope.js index 989dd7aec..3e3dd1ca2 100644 --- a/src/scope.js +++ b/src/scope.js @@ -1,19 +1,18 @@ -'use strict' -const _ = require('./util/underscore.js') -const lexical = require('./lexical.js') -const assert = require('./util/assert.js') +import * as _ from './util/underscore.js' +import * as lexical from './lexical.js' +import assert from './util/assert.js' -let Scope = { +const Scope = { getAll: function () { return this.contexts.reduce((ctx, val) => Object.assign(ctx, val), Object.create(null)) }, get: function (path) { - let paths = this.propertyAccessSeq(path) - let scope = this.findContextFor(paths[0]) || _.last(this.contexts) + const paths = this.propertyAccessSeq(path) + const scope = this.findContextFor(paths[0]) || _.last(this.contexts) return paths.reduce((value, key) => this.readProperty(value, key), scope) }, set: function (path, v) { - let paths = this.propertyAccessSeq(path) + const paths = this.propertyAccessSeq(path) let scope = this.findContextFor(paths[0]) || _.last(this.contexts) paths.some((key, i) => { if (!_.isObject(scope)) { @@ -39,7 +38,7 @@ let Scope = { if (!arguments.length) { return this.contexts.pop() } - let i = this.contexts.findIndex(scope => scope === ctx) + const i = this.contexts.findIndex(scope => scope === ctx) if (i === -1) { throw new TypeError('scope not found, cannot pop') } @@ -48,7 +47,7 @@ let Scope = { findContextFor: function (key, filter) { filter = filter || (() => true) for (let i = this.contexts.length - 1; i >= 0; i--) { - let candidate = this.contexts[i] + const candidate = this.contexts[i] if (!filter(candidate)) continue if (key in candidate) { return candidate @@ -89,7 +88,7 @@ let Scope = { */ propertyAccessSeq: function (str) { str = String(str) - let seq = [] + const seq = [] let name = '' let j let i = 0 @@ -98,7 +97,7 @@ let Scope = { case '[': push() - let delemiter = str[i + 1] + const delemiter = str[i + 1] if (/['"]/.test(delemiter)) { // foo["bar"] j = str.indexOf(delemiter, i + 2) assert(j !== -1, `unbalanced ${delemiter}: ${str}`) @@ -155,23 +154,16 @@ function matchRightBracket (str, begin) { return -1 } -exports.factory = function (ctx, opts) { - let defaultOptions = { +export function factory (ctx, opts) { + const defaultOptions = { dynamicPartials: true, strict_variables: false, strict_filters: false, blocks: {}, root: [] } - let scope = Object.create(Scope) + const scope = Object.create(Scope) scope.opts = _.assign(defaultOptions, opts) scope.contexts = [ctx || {}] return scope } - -exports.types = { - AssignScope: Object.create(null), - CaptureScope: Object.create(null), - IncrementScope: Object.create(null), - DecrementScope: Object.create(null) -} diff --git a/src/syntax.js b/src/syntax.js index dd8326929..78fd28505 100644 --- a/src/syntax.js +++ b/src/syntax.js @@ -1,26 +1,28 @@ -const operators = require('./operators.js')(isTruthy) -const lexical = require('./lexical.js') -const assert = require('./util/assert.js') +import Operators from './operators.js' +import * as lexical from './lexical.js' +import assert from './util/assert.js' -function evalExp (exp, scope) { +const operators = Operators(isTruthy) + +export function evalExp (exp, scope) { assert(scope, 'unable to evalExp: scope undefined') - let operatorREs = lexical.operators + const operatorREs = lexical.operators let match for (let i = 0; i < operatorREs.length; i++) { - let operatorRE = operatorREs[i] - let expRE = new RegExp(`^(${lexical.quoteBalanced.source})(${operatorRE.source})(${lexical.quoteBalanced.source})$`) + const operatorRE = operatorREs[i] + const expRE = new RegExp(`^(${lexical.quoteBalanced.source})(${operatorRE.source})(${lexical.quoteBalanced.source})$`) if ((match = exp.match(expRE))) { - let l = evalExp(match[1], scope) - let op = operators[match[2].trim()] - let r = evalExp(match[3], scope) + const l = evalExp(match[1], scope) + const op = operators[match[2].trim()] + const r = evalExp(match[3], scope) return op(l, r) } } if ((match = exp.match(lexical.rangeLine))) { - let low = evalValue(match[1], scope) - let high = evalValue(match[2], scope) - let range = [] + const low = evalValue(match[1], scope) + const high = evalValue(match[2], scope) + const range = [] for (let j = low; j <= high; j++) { range.push(j) } @@ -30,7 +32,7 @@ function evalExp (exp, scope) { return evalValue(exp, scope) } -function evalValue (str, scope) { +export function evalValue (str, scope) { str = str && str.trim() if (!str) return undefined @@ -43,14 +45,10 @@ function evalValue (str, scope) { throw new TypeError(`cannot eval '${str}' as value`) } -function isTruthy (val) { +export function isTruthy (val) { return !isFalsy(val) } -function isFalsy (val) { +export function isFalsy (val) { return val === false || undefined === val || val === null } - -module.exports = { - evalExp, evalValue, isTruthy, isFalsy -} diff --git a/src/tag.js b/src/tag.js index d9af6a50f..40600104f 100644 --- a/src/tag.js +++ b/src/tag.js @@ -1,38 +1,37 @@ -'use strict' -const lexical = require('./lexical.js') -const Syntax = require('./syntax.js') -const assert = require('./util/assert.js') +import {hashCapture} from './lexical.js' +import {evalValue} from './syntax.js' +import assert from './util/assert.js' function hash (markup, scope) { - let obj = {} + const obj = {} let match - lexical.hashCapture.lastIndex = 0 - while ((match = lexical.hashCapture.exec(markup))) { - let k = match[1] - let v = match[2] - obj[k] = Syntax.evalValue(v, scope) + hashCapture.lastIndex = 0 + while ((match = hashCapture.exec(markup))) { + const k = match[1] + const v = match[2] + obj[k] = evalValue(v, scope) } return obj } -module.exports = function () { +export default function () { let tagImpls = {} - let _tagInstance = { - render: function (scope) { - let obj = hash(this.token.args, scope) - let impl = this.tagImpl + const _tagInstance = { + render: async function (scope) { + const obj = hash(this.token.args, scope) + const impl = this.tagImpl if (typeof impl.render !== 'function') { - return Promise.resolve('') + return '' } - return Promise.resolve().then(() => impl.render(scope, obj)) + return impl.render(scope, obj) }, parse: function (token, tokens) { this.type = 'tag' this.token = token this.name = token.name - let tagImpl = tagImpls[this.name] + const tagImpl = tagImpls[this.name] assert(tagImpl, `tag ${this.name} not found`) this.tagImpl = Object.create(tagImpl) if (this.tagImpl.parse) { @@ -46,7 +45,7 @@ module.exports = function () { } function construct (token, tokens) { - let instance = Object.create(_tagInstance) + const instance = Object.create(_tagInstance) instance.parse(token, tokens) return instance } diff --git a/src/tags/assign.js b/src/tags/assign.js index 1911aec17..fbd19be66 100644 --- a/src/tags/assign.js +++ b/src/tags/assign.js @@ -1,19 +1,19 @@ -import {lexical} from '../index' import assert from '../util/assert.js' -import {types} from '../scope' -const re = new RegExp(`(${lexical.identifier.source})\\s*=(.*)`) +export default function (liquid, Liquid) { + const rIdentifier = Liquid.lexical.identifier + const re = new RegExp(`(${rIdentifier.source})\\s*=(.*)`) + const {AssignScope} = Liquid.Types -module.exports = function (liquid) { liquid.registerTag('assign', { parse: function (token) { - let match = token.args.match(re) + const match = token.args.match(re) assert(match, `illegal token ${token.raw}`) this.key = match[1] this.value = match[2] }, render: function (scope) { - let ctx = Object.create(types.AssignScope) + const ctx = Object.create(AssignScope) ctx[this.key] = liquid.evalValue(this.value, scope) scope.push(ctx) return Promise.resolve('') diff --git a/src/tags/capture.js b/src/tags/capture.js index c20aaa81a..e5d9ee2a3 100644 --- a/src/tags/capture.js +++ b/src/tags/capture.js @@ -1,20 +1,19 @@ -'use strict' -const Liquid = require('..') -const lexical = Liquid.lexical -const re = new RegExp(`(${lexical.identifier.source})`) -const assert = require('../util/assert.js') -const types = require('../scope.js').types +import assert from '../util/assert.js' + +export default function (liquid, Liquid) { + const rIdentifier = Liquid.lexical.identifier + const re = new RegExp(`(${rIdentifier.source})`) + const {CaptureScope} = Liquid.Types -module.exports = function (liquid) { liquid.registerTag('capture', { parse: function (tagToken, remainTokens) { - let match = tagToken.args.match(re) + const match = tagToken.args.match(re) assert(match, `${tagToken.args} not valid identifier`) this.variable = match[1] this.templates = [] - let stream = liquid.parser.parseStream(remainTokens) + const stream = liquid.parser.parseStream(remainTokens) stream.on('tag:endcapture', token => stream.stop()) .on('template', tpl => this.templates.push(tpl)) .on('end', x => { @@ -22,13 +21,11 @@ module.exports = function (liquid) { }) stream.start() }, - render: function (scope, hash) { - return liquid.renderer.renderTemplates(this.templates, scope) - .then((html) => { - let ctx = Object.create(types.CaptureScope) - ctx[this.variable] = html - scope.push(ctx) - }) + render: async function (scope, hash) { + const html = await liquid.renderer.renderTemplates(this.templates, scope) + const ctx = Object.create(CaptureScope) + ctx[this.variable] = html + scope.push(ctx) } }) } diff --git a/src/tags/case.js b/src/tags/case.js index 1799d1a19..259d56ba9 100644 --- a/src/tags/case.js +++ b/src/tags/case.js @@ -1,6 +1,4 @@ -import Liquid from '..' - -module.exports = function (liquid) { +export default function (liquid, Liquid) { liquid.registerTag('case', { parse: function (tagToken, remainTokens) { @@ -9,7 +7,7 @@ module.exports = function (liquid) { this.elseTemplates = [] let p = [] - let stream = liquid.parser.parseStream(remainTokens) + const stream = liquid.parser.parseStream(remainTokens) .on('tag:when', token => { this.cases.push({ val: token.args, @@ -28,9 +26,9 @@ module.exports = function (liquid) { render: function (scope, hash) { for (let i = 0; i < this.cases.length; i++) { - let branch = this.cases[i] - let val = Liquid.evalExp(branch.val, scope) - let cond = Liquid.evalExp(this.cond, scope) + const branch = this.cases[i] + const val = Liquid.evalExp(branch.val, scope) + const cond = Liquid.evalExp(this.cond, scope) if (val === cond) { return liquid.renderer.renderTemplates(branch.templates, scope) } diff --git a/src/tags/comment.js b/src/tags/comment.js index 713ab12b2..795202831 100644 --- a/src/tags/comment.js +++ b/src/tags/comment.js @@ -1,7 +1,7 @@ -module.exports = function (liquid) { +export default function (liquid) { liquid.registerTag('comment', { parse: function (tagToken, remainTokens) { - let stream = liquid.parser.parseStream(remainTokens) + const stream = liquid.parser.parseStream(remainTokens) stream .on('token', token => { if (token.name === 'endcomment') stream.stop() diff --git a/src/tags/cycle.js b/src/tags/cycle.js index a8b6e80e6..0918d23d4 100644 --- a/src/tags/cycle.js +++ b/src/tags/cycle.js @@ -1,10 +1,10 @@ -const Liquid = require('..') -const lexical = Liquid.lexical -const groupRE = new RegExp(`^(?:(${lexical.value.source})\\s*:\\s*)?(.*)$`) -const candidatesRE = new RegExp(lexical.value.source, 'g') -const assert = require('../util/assert.js') +import assert from '../util/assert.js' + +export default function (liquid, Liquid) { + const rValue = Liquid.lexical.value + const groupRE = new RegExp(`^(?:(${rValue.source})\\s*:\\s*)?(.*)$`) + const candidatesRE = new RegExp(rValue.source, 'g') -module.exports = function (liquid) { liquid.registerTag('cycle', { parse: function (tagToken, remainTokens) { @@ -12,7 +12,7 @@ module.exports = function (liquid) { assert(match, `illegal tag: ${tagToken.raw}`) this.group = match[1] || '' - let candidates = match[2] + const candidates = match[2] this.candidates = [] @@ -23,21 +23,21 @@ module.exports = function (liquid) { }, render: function (scope, hash) { - let group = Liquid.evalValue(this.group, scope) - let fingerprint = `cycle:${group}:` + this.candidates.join(',') + const group = Liquid.evalValue(this.group, scope) + const fingerprint = `cycle:${group}:` + this.candidates.join(',') - let groups = scope.opts.groups = scope.opts.groups || {} + const groups = scope.opts.groups = scope.opts.groups || {} let idx = groups[fingerprint] if (idx === undefined) { idx = groups[fingerprint] = 0 } - let candidate = this.candidates[idx] + const candidate = this.candidates[idx] idx = (idx + 1) % this.candidates.length groups[fingerprint] = idx - return Promise.resolve(Liquid.evalValue(candidate, scope)) + return Liquid.evalValue(candidate, scope) } }) } diff --git a/src/tags/decrement.js b/src/tags/decrement.js index 679844e3a..0055d316d 100644 --- a/src/tags/decrement.js +++ b/src/tags/decrement.js @@ -1,13 +1,12 @@ -'use strict' -const Liquid = require('..') -const lexical = Liquid.lexical -const assert = require('../util/assert.js') -const types = require('../scope').types +import assert from '../util/assert.js' + +export default function (liquid, Liquid) { + const lexical = Liquid.lexical + const {CaptureScope, AssignScope, DecrementScope} = Liquid.Types -module.exports = function (liquid) { liquid.registerTag('decrement', { parse: function (token) { - let match = token.args.match(lexical.identifier) + const match = token.args.match(lexical.identifier) assert(match, `illegal identifier ${token.args}`) this.variable = match[0] }, @@ -15,12 +14,12 @@ module.exports = function (liquid) { let context = scope.findContextFor( this.variable, ctx => { - return Object.getPrototypeOf(ctx) !== types.CaptureScope && - Object.getPrototypeOf(ctx) !== types.AssignScope + return Object.getPrototypeOf(ctx) !== CaptureScope && + Object.getPrototypeOf(ctx) !== AssignScope } ) if (!context) { - context = Object.create(types.DecrementScope) + context = Object.create(DecrementScope) scope.unshift(context) } if (typeof context[this.variable] !== 'number') { diff --git a/src/tags/for.js b/src/tags/for.js index acadf3ec6..ce30f408a 100644 --- a/src/tags/for.js +++ b/src/tags/for.js @@ -1,96 +1,93 @@ -import {default as Liquid, lexical} from '../index' import {mapSeries} from '../util/promise.js' -import _ from '../util/underscore.js' +import {isString, isObject} from '../util/underscore.js' import assert from '../util/assert.js' -const RenderBreakError = Liquid.Types.RenderBreakError -const re = new RegExp(`^(${lexical.identifier.source})\\s+in\\s+` + - `(${lexical.value.source})` + - `(?:\\s+${lexical.hash.source})*` + - `(?:\\s+(reversed))?` + - `(?:\\s+${lexical.hash.source})*$`) +export default function (liquid, Liquid) { + const RenderBreakError = Liquid.Types.RenderBreakError + const lexical = Liquid.lexical + const 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, render}) - parse: function (tagToken, remainTokens) { - let match = re.exec(tagToken.args) - assert(match, `illegal tag: ${tagToken.raw}`) - this.variable = match[1] - this.collection = match[2] - this.reversed = !!match[3] + function parse (tagToken, remainTokens) { + const 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 = [] - let p - let stream = liquid.parser.parseStream(remainTokens) - .on('start', () => (p = this.templates)) - .on('tag:else', () => (p = this.elseTemplates)) - .on('tag:endfor', () => stream.stop()) - .on('template', tpl => p.push(tpl)) - .on('end', () => { - throw new Error(`tag ${tagToken.raw} not closed`) - }) - - stream.start() - }, - - render: function (scope, hash) { - let collection = Liquid.evalExp(this.collection, scope) - - if (!Array.isArray(collection)) { - if (_.isString(collection) && collection.length > 0) { - collection = [collection] - } else if (_.isObject(collection)) { - collection = Object.keys(collection).map((key) => [key, collection[key]]) - } - } - if (!Array.isArray(collection) || !collection.length) { - return liquid.renderer.renderTemplates(this.elseTemplates, scope) - } - - let offset = hash.offset || 0 - let limit = (hash.limit === undefined) ? collection.length : hash.limit - - collection = collection.slice(offset, offset + limit) - if (this.reversed) collection.reverse() - - let contexts = collection.map((item, i) => { - let ctx = {} - ctx[this.variable] = item - ctx.forloop = { - first: i === 0, - index: i + 1, - index0: i, - last: i === collection.length - 1, - length: collection.length, - rindex: collection.length - i, - rindex0: collection.length - i - 1 - } - return ctx + let p + const stream = liquid.parser.parseStream(remainTokens) + .on('start', () => (p = this.templates)) + .on('tag:else', () => (p = this.elseTemplates)) + .on('tag:endfor', () => stream.stop()) + .on('template', tpl => p.push(tpl)) + .on('end', () => { + throw new Error(`tag ${tagToken.raw} not closed`) }) - let html = '' - return mapSeries(contexts, (context) => { - return Promise.resolve() - .then(() => scope.push(context)) - .then(() => liquid.renderer.renderTemplates(this.templates, scope)) - .then(partial => (html += partial)) - .catch(e => { - if (e instanceof RenderBreakError) { - html += e.resolvedHTML - if (e.message === 'continue') return - } - throw e - }) - .then(() => scope.pop(context)) - }).catch((e) => { - if (e instanceof RenderBreakError && e.message === 'break') { - return - } - throw e - }).then(() => html) + stream.start() + } + async function render (scope, hash) { + let collection = Liquid.evalExp(this.collection, scope) + + if (!Array.isArray(collection)) { + if (isString(collection) && collection.length > 0) { + collection = [collection] + } else if (isObject(collection)) { + collection = Object.keys(collection).map((key) => [key, collection[key]]) + } } - }) + if (!Array.isArray(collection) || !collection.length) { + return liquid.renderer.renderTemplates(this.elseTemplates, scope) + } + + const offset = hash.offset || 0 + const limit = (hash.limit === undefined) ? collection.length : hash.limit + + collection = collection.slice(offset, offset + limit) + if (this.reversed) collection.reverse() + + const contexts = collection.map((item, i) => { + const ctx = {} + ctx[this.variable] = item + ctx.forloop = { + first: i === 0, + index: i + 1, + index0: i, + last: i === collection.length - 1, + length: collection.length, + rindex: collection.length - i, + rindex0: collection.length - i - 1 + } + return ctx + }) + + let html = '' + let finished = false + await mapSeries(contexts, async context => { + if (finished) return + + scope.push(context) + try { + html += await liquid.renderer.renderTemplates(this.templates, scope) + } catch (e) { + if (e instanceof RenderBreakError) { + html += e.resolvedHTML + if (e.message === 'break') { + finished = true + } + } else throw e + } + scope.pop(context) + }) + return html + } } diff --git a/src/tags/if.js b/src/tags/if.js index 20b96faa4..716007a87 100644 --- a/src/tags/if.js +++ b/src/tags/if.js @@ -1,6 +1,4 @@ -import Liquid from '..' - -module.exports = function (liquid) { +export default function (liquid, Liquid) { liquid.registerTag('if', { parse: function (tagToken, remainTokens) { @@ -8,7 +6,7 @@ module.exports = function (liquid) { this.elseTemplates = [] let p - let stream = liquid.parser.parseStream(remainTokens) + const stream = liquid.parser.parseStream(remainTokens) .on('start', () => this.branches.push({ cond: tagToken.args, templates: (p = []) @@ -30,9 +28,8 @@ module.exports = function (liquid) { }, render: function (scope, hash) { - for (let i = 0; i < this.branches.length; i++) { - let branch = this.branches[i] - let cond = Liquid.evalExp(branch.cond, scope) + for (const branch of this.branches) { + const cond = Liquid.evalExp(branch.cond, scope) if (Liquid.isTruthy(cond)) { return liquid.renderer.renderTemplates(branch.templates, scope) } diff --git a/src/tags/include.js b/src/tags/include.js index 14ce725ab..d1cff7d30 100644 --- a/src/tags/include.js +++ b/src/tags/include.js @@ -1,11 +1,11 @@ -'use strict' -const Liquid = require('..') -const lexical = Liquid.lexical -const withRE = new RegExp(`with\\s+(${lexical.value.source})`) -const staticFileRE = /[^\s,]+/ -const assert = require('../util/assert.js') +import assert from '../util/assert.js' + +const staticFileRE = /[^\s,]+/ + +export default function (liquid, Liquid) { + const lexical = Liquid.lexical + const withRE = new RegExp(`with\\s+(${lexical.value.source})`) -module.exports = function (liquid) { liquid.registerTag('include', { parse: function (token) { let match = staticFileRE.exec(token.args) @@ -23,42 +23,35 @@ module.exports = function (liquid) { this.with = match[1] } }, - render: function (scope, hash) { - let pFilepath + render: async function (scope, hash) { + let filepath if (scope.opts.dynamicPartials) { if (lexical.quotedLine.exec(this.value)) { - let template = this.value.slice(1, -1) - pFilepath = liquid.parseAndRender(template, scope.getAll(), scope.opts) + const template = this.value.slice(1, -1) + filepath = await liquid.parseAndRender(template, scope.getAll(), scope.opts) } else { - pFilepath = Promise.resolve(Liquid.evalValue(this.value, scope)) + filepath = Liquid.evalValue(this.value, scope) } } else { - pFilepath = Promise.resolve(this.staticValue) + filepath = this.staticValue } + assert(filepath, `cannot include with empty filename`) - let originBlocks = scope.opts.blocks - let originBlockMode = scope.opts.blockMode + const originBlocks = scope.opts.blocks + const originBlockMode = scope.opts.blockMode - return pFilepath - .then(filepath => { - assert(filepath, `cannot include with empty filename`) - scope.opts.blocks = {} - scope.opts.blockMode = 'output' - if (this.with) { - hash[filepath] = Liquid.evalValue(this.with, scope) - } - return liquid.getTemplate(filepath, scope.opts.root) - }) - .then(templates => { - scope.push(hash) - return liquid.renderer.renderTemplates(templates, scope) - }) - .then((html) => { - scope.pop(hash) - scope.opts.blocks = originBlocks - scope.opts.blockMode = originBlockMode - return html - }) + scope.opts.blocks = {} + scope.opts.blockMode = 'output' + if (this.with) { + hash[filepath] = Liquid.evalValue(this.with, scope) + } + const templates = await liquid.getTemplate(filepath, scope.opts.root) + scope.push(hash) + const html = await liquid.renderer.renderTemplates(templates, scope) + scope.pop(hash) + scope.opts.blocks = originBlocks + scope.opts.blockMode = originBlockMode + return html } }) } diff --git a/src/tags/increment.js b/src/tags/increment.js index 7437470d4..0b94b1eb6 100644 --- a/src/tags/increment.js +++ b/src/tags/increment.js @@ -1,12 +1,12 @@ -const Liquid = require('../index') -const assert = require('../util/assert.js') -const lexical = Liquid.lexical -const types = require('../scope').types +import assert from '../util/assert.js' + +export default function (liquid, Liquid) { + const lexical = Liquid.lexical + const {CaptureScope, AssignScope, IncrementScope} = Liquid.Types -module.exports = function (liquid) { liquid.registerTag('increment', { parse: function (token) { - let match = token.args.match(lexical.identifier) + const match = token.args.match(lexical.identifier) assert(match, `illegal identifier ${token.args}`) this.variable = match[0] }, @@ -14,18 +14,18 @@ module.exports = function (liquid) { let context = scope.findContextFor( this.variable, ctx => { - return Object.getPrototypeOf(ctx) !== types.CaptureScope && - Object.getPrototypeOf(ctx) !== types.AssignScope + return Object.getPrototypeOf(ctx) !== CaptureScope && + Object.getPrototypeOf(ctx) !== AssignScope } ) if (!context) { - context = Object.create(types.IncrementScope) + context = Object.create(IncrementScope) scope.unshift(context) } if (typeof context[this.variable] !== 'number') { context[this.variable] = 0 } - let val = context[this.variable] + const val = context[this.variable] context[this.variable]++ return val } diff --git a/src/tags/index.js b/src/tags/index.js index 432b67c14..ee9ed87f0 100644 --- a/src/tags/index.js +++ b/src/tags/index.js @@ -1,16 +1,31 @@ -module.exports = function (engine) { - require('./assign.js')(engine) - require('./capture.js')(engine) - require('./case.js')(engine) - require('./comment.js')(engine) - require('./cycle.js')(engine) - require('./decrement.js')(engine) - require('./for.js')(engine) - require('./if.js')(engine) - require('./include.js')(engine) - require('./increment.js')(engine) - require('./layout.js')(engine) - require('./raw.js')(engine) - require('./tablerow.js')(engine) - require('./unless.js')(engine) +import For from './for.js' +import Assign from './assign.js' +import Capture from './capture.js' +import Case from './case.js' +import Comment from './comment.js' +import Include from './include.js' +import Decrement from './decrement.js' +import Cycle from './cycle.js' +import If from './if.js' +import Increment from './increment.js' +import Layout from './layout.js' +import Raw from './raw.js' +import Tablerow from './tablerow.js' +import Unless from './unless.js' + +export default function (engine, Liquid) { + Assign(engine, Liquid) + Capture(engine, Liquid) + Case(engine, Liquid) + Comment(engine, Liquid) + Cycle(engine, Liquid) + Decrement(engine, Liquid) + For(engine, Liquid) + If(engine, Liquid) + Include(engine, Liquid) + Increment(engine, Liquid) + Layout(engine, Liquid) + Raw(engine, Liquid) + Tablerow(engine, Liquid) + Unless(engine, Liquid) } diff --git a/src/tags/layout.js b/src/tags/layout.js index 5850b6831..1731d42a4 100644 --- a/src/tags/layout.js +++ b/src/tags/layout.js @@ -1,7 +1,4 @@ -const Liquid = require('..') -const lexical = Liquid.lexical -const assert = require('../util/assert.js') -const staticFileRE = /\S+/ +import assert from '../util/assert.js' /* * blockMode: @@ -9,7 +6,10 @@ const staticFileRE = /\S+/ * * "output": output rendered html */ -module.exports = function (liquid) { +export default function (liquid, Liquid) { + const rValue = Liquid.lexical.value + const staticFileRE = /\S+/ + liquid.registerTag('layout', { parse: function (token, remainTokens) { let match = staticFileRE.exec(token.args) @@ -17,45 +17,41 @@ module.exports = function (liquid) { this.staticLayout = match[0] } - match = lexical.value.exec(token.args) + match = rValue.exec(token.args) if (match) { this.layout = match[0] } this.tpls = liquid.parser.parse(remainTokens) }, - render: function (scope, hash) { - let layout = scope.opts.dynamicPartials ? Liquid.evalValue(this.layout, scope) : this.staticLayout + render: async function (scope, hash) { + const layout = scope.opts.dynamicPartials + ? Liquid.evalValue(this.layout, scope) + : this.staticLayout assert(layout, `cannot apply layout with empty filename`) // render the remaining tokens immediately scope.opts.blockMode = 'store' - return liquid.renderer.renderTemplates(this.tpls, scope) - .then(html => { - if (scope.opts.blocks[''] === undefined) { - scope.opts.blocks[''] = html - } - return liquid.getTemplate(layout, scope.opts.root) - }) - .then(templates => { - scope.push(hash) - scope.opts.blockMode = 'output' - return liquid.renderer.renderTemplates(templates, scope) - }) - .then(partial => { - scope.pop(hash) - return partial - }) + const html = await liquid.renderer.renderTemplates(this.tpls, scope) + if (scope.opts.blocks[''] === undefined) { + scope.opts.blocks[''] = html + } + const templates = await liquid.getTemplate(layout, scope.opts.root) + scope.push(hash) + scope.opts.blockMode = 'output' + const partial = await liquid.renderer.renderTemplates(templates, scope) + scope.pop(hash) + return partial } }) liquid.registerTag('block', { parse: function (token, remainTokens) { - let match = /\w+/.exec(token.args) + const match = /\w+/.exec(token.args) this.block = match ? match[0] : '' this.tpls = [] - let stream = liquid.parser.parseStream(remainTokens) + const stream = liquid.parser.parseStream(remainTokens) .on('tag:endblock', () => stream.stop()) .on('template', tpl => this.tpls.push(tpl)) .on('end', () => { @@ -63,20 +59,17 @@ module.exports = function (liquid) { }) stream.start() }, - render: function (scope) { - return Promise.resolve(scope.opts.blocks[this.block]) - .then(html => html === undefined - // render default block - ? liquid.renderer.renderTemplates(this.tpls, scope) - // use child-defined block - : html) - .then(html => { - if (scope.opts.blockMode === 'store') { - scope.opts.blocks[this.block] = html - return '' - } - return html - }) + render: async function (scope) { + const childDefined = scope.opts.blocks[this.block] + const html = childDefined !== undefined + ? childDefined + : await liquid.renderer.renderTemplates(this.tpls, scope) + + if (scope.opts.blockMode === 'store') { + scope.opts.blocks[this.block] = html + return '' + } + return html } }) } diff --git a/src/tags/raw.js b/src/tags/raw.js index 898d9edb4..239c9f63c 100644 --- a/src/tags/raw.js +++ b/src/tags/raw.js @@ -1,9 +1,9 @@ -module.exports = function (liquid) { +export default function (liquid) { liquid.registerTag('raw', { parse: function (tagToken, remainTokens) { this.tokens = [] - let stream = liquid.parser.parseStream(remainTokens) + const stream = liquid.parser.parseStream(remainTokens) stream .on('token', token => { if (token.name === 'endraw') stream.stop() diff --git a/src/tags/tablerow.js b/src/tags/tablerow.js index 9f3a1ef05..df234f050 100644 --- a/src/tags/tablerow.js +++ b/src/tags/tablerow.js @@ -1,17 +1,16 @@ -import Liquid from '..' import {mapSeries} from '../util/promise.js' import assert from '../util/assert.js' -const lexical = Liquid.lexical -const re = new RegExp(`^(${lexical.identifier.source})\\s+in\\s+` + - `(${lexical.value.source})` + - `(?:\\s+${lexical.hash.source})*$`) +export default function (liquid, Liquid) { + const lexical = Liquid.lexical + const re = new RegExp(`^(${lexical.identifier.source})\\s+in\\s+` + + `(${lexical.value.source})` + + `(?:\\s+${lexical.hash.source})*$`) -module.exports = function (liquid) { liquid.registerTag('tablerow', { parse: function (tagToken, remainTokens) { - let match = re.exec(tagToken.args) + const match = re.exec(tagToken.args) assert(match, `illegal tag: ${tagToken.raw}`) this.variable = match[1] @@ -19,7 +18,7 @@ module.exports = function (liquid) { this.templates = [] let p - let stream = liquid.parser.parseStream(remainTokens) + const stream = liquid.parser.parseStream(remainTokens) .on('start', () => (p = this.templates)) .on('tag:endtablerow', token => stream.stop()) .on('template', tpl => p.push(tpl)) @@ -30,54 +29,42 @@ module.exports = function (liquid) { stream.start() }, - render: function (scope, hash) { + render: async function (scope, hash) { let collection = Liquid.evalExp(this.collection, scope) || [] + const offset = hash.offset || 0 + const limit = (hash.limit === undefined) ? collection.length : hash.limit - let html = '' - let offset = hash.offset || 0 - let limit = (hash.limit === undefined) ? collection.length : hash.limit - - let cols = hash.cols - let row - let col - - // build array of arguments to pass to sequential promises... collection = collection.slice(offset, offset + limit) - if (!cols) cols = collection.length - let contexts = collection.map((item, i) => { - let ctx = {} + const cols = hash.cols || collection.length + const contexts = collection.map((item, i) => { + const ctx = {} ctx[this.variable] = item return ctx }) - return mapSeries(contexts, - (context, idx) => { - row = Math.floor(idx / cols) + 1 - col = (idx % cols) + 1 - if (col === 1) { - if (row !== 1) { - html += '' - } - html += `` - } - - html += `` - scope.push(context) - return liquid.renderer - .renderTemplates(this.templates, scope) - .then((partial) => { - scope.pop(context) - html += partial - html += '' - return html - }) - }) - .then(() => { - if (row > 0) { + let row + let html = '' + await mapSeries(contexts, async (context, idx) => { + row = Math.floor(idx / cols) + 1 + const col = (idx % cols) + 1 + if (col === 1) { + if (row !== 1) { html += '' } - return html - }) + html += `` + } + + html += `` + scope.push(context) + html += await liquid.renderer.renderTemplates(this.templates, scope) + html += '' + scope.pop(context) + return html + }) + if (row > 0) { + html += '' + } + return html } }) } diff --git a/src/tags/unless.js b/src/tags/unless.js index 77a1a3de8..11d853651 100644 --- a/src/tags/unless.js +++ b/src/tags/unless.js @@ -1,12 +1,10 @@ -import Liquid from '../index' - -module.exports = function (liquid) { +export default function (liquid, Liquid) { liquid.registerTag('unless', { parse: function (tagToken, remainTokens) { this.templates = [] this.elseTemplates = [] let p - let stream = liquid.parser.parseStream(remainTokens) + const stream = liquid.parser.parseStream(remainTokens) .on('start', x => { p = this.templates this.cond = tagToken.args @@ -22,7 +20,7 @@ module.exports = function (liquid) { }, render: function (scope, hash) { - let cond = Liquid.evalExp(this.cond, scope) + const cond = Liquid.evalExp(this.cond, scope) return Liquid.isFalsy(cond) ? liquid.renderer.renderTemplates(this.templates, scope) : liquid.renderer.renderTemplates(this.elseTemplates, scope) diff --git a/src/tokenizer.js b/src/tokenizer.js index 1f9adc41e..f31cb9fdd 100644 --- a/src/tokenizer.js +++ b/src/tokenizer.js @@ -1,17 +1,19 @@ -const lexical = require('./lexical.js') -const TokenizationError = require('./util/error.js').TokenizationError -const _ = require('./util/underscore.js') -const whiteSpaceCtrl = require('./whitespace-ctrl.js') -const assert = require('./util/assert.js') +import * as lexical from './lexical.js' +import {TokenizationError} from './util/error.js' +import * as _ from './util/underscore.js' +import assert from './util/assert.js' +import whiteSpaceCtrl from './whitespace-ctrl.js' -function parse (input, file, options) { +export {default as whiteSpaceCtrl} from './whitespace-ctrl.js' + +export function parse (input, file, options) { assert(_.isString(input), 'illegal input') - let rLiquid = /({%-?([\s\S]*?)-?%})|({{-?([\s\S]*?)-?}})/g + const rLiquid = /({%-?([\s\S]*?)-?%})|({{-?([\s\S]*?)-?}})/g let currIndent = 0 - let lineNumber = LineNumber(input) + const lineNumber = LineNumber(input) let lastMatchEnd = 0 - let tokens = [] + const tokens = [] for (let match; (match = rLiquid.exec(input)); lastMatchEnd = rLiquid.lastIndex) { if (match.index > lastMatchEnd) { @@ -28,8 +30,8 @@ function parse (input, file, options) { return tokens function parseTagToken (raw, value, pos) { - let match = value.match(lexical.tagLine) - let token = { + const match = value.match(lexical.tagLine) + const token = { type: 'tag', indent: currIndent, line: lineNumber.get(pos), @@ -62,7 +64,7 @@ function parse (input, file, options) { } function parseHTMLToken (begin, end) { - let htmlFragment = input.slice(begin, end) + const htmlFragment = input.slice(begin, end) currIndent = _.last((htmlFragment).split('\n')).length return { @@ -79,13 +81,10 @@ function LineNumber (html) { return { get: function (pos) { - let lines = html.slice(lastMatchBegin + 1, pos).split('\n') + const lines = html.slice(lastMatchBegin + 1, pos).split('\n') parsedLinesCount += lines.length - 1 lastMatchBegin = pos return parsedLinesCount + 1 } } } - -exports.parse = parse -exports.whiteSpaceCtrl = whiteSpaceCtrl diff --git a/src/util/assert.js b/src/util/assert.js index c673a9ca1..33a0bfb09 100644 --- a/src/util/assert.js +++ b/src/util/assert.js @@ -1,10 +1,8 @@ -const AssertionError = require('./error.js').AssertionError +import {AssertionError} from './error.js' -function assert (predicate, message) { +export default function (predicate, message) { if (!predicate) { message = message || `expect ${predicate} to be true` throw new AssertionError(message) } } - -module.exports = assert diff --git a/src/util/error.js b/src/util/error.js index 407cf2995..80a616b0e 100644 --- a/src/util/error.js +++ b/src/util/error.js @@ -1,4 +1,4 @@ -import _ from './underscore.js' +import * as _ from './underscore.js' function initError () { this.name = this.constructor.name @@ -14,7 +14,7 @@ function initLiquidError (err, token) { this.line = token.line this.file = token.file - let context = mkContext(token.input, token.line) + const context = mkContext(token.input, token.line) this.message = mkMessage(err.message, token) this.stack = context + '\n' + (this.stack || this.message) + @@ -64,11 +64,11 @@ AssertionError.prototype = Object.create(Error.prototype) AssertionError.prototype.constructor = AssertionError function mkContext (input, line) { - let lines = input.split('\n') - let begin = Math.max(line - 2, 1) - let end = Math.min(line + 3, lines.length) + const lines = input.split('\n') + const begin = Math.max(line - 2, 1) + const end = Math.min(line + 3, lines.length) - let context = _ + const context = _ .range(begin, end + 1) .map(l => [ (l === line) ? '>> ' : ' ', @@ -82,9 +82,9 @@ function mkContext (input, line) { } function align (n, max) { - let length = (max + '').length - let str = n + '' - let blank = Array(length - str.length).join(' ') + const length = (max + '').length + const str = n + '' + const blank = Array(length - str.length).join(' ') return blank + str } diff --git a/src/util/fs.js b/src/util/fs.js index 05eee0cb4..276824139 100644 --- a/src/util/fs.js +++ b/src/util/fs.js @@ -1,6 +1,6 @@ -const fs = require('fs') +import fs from 'fs' -function readFileAsync (filepath) { +export function readFileAsync (filepath) { return new Promise(function (resolve, reject) { fs.readFile(filepath, 'utf8', function (err, content) { err ? reject(err) : resolve(content) @@ -8,13 +8,8 @@ function readFileAsync (filepath) { }) }; -function statFileAsync (path) { +export function statFileAsync (path) { return new Promise(function (resolve, reject) { fs.stat(path, (err, stat) => err ? reject(err) : resolve(stat)) }) }; - -module.exports = { - readFileAsync, - statFileAsync -} diff --git a/src/util/http.js b/src/util/http.js new file mode 100644 index 000000000..eab76e7c1 --- /dev/null +++ b/src/util/http.js @@ -0,0 +1,17 @@ +export function get (url) { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest() + xhr.onload = () => { + if (xhr.status >= 200 && xhr.status < 300) { + resolve(xhr.responseText) + } else { + reject(new Error(xhr.statusText)) + } + } + xhr.onerror = () => { + reject(new Error('An error occurred whilst sending the response.')) + } + xhr.open('GET', url) + xhr.send() + }) +} diff --git a/src/util/promise.js b/src/util/promise.js index b92ac5365..31b043bc2 100644 --- a/src/util/promise.js +++ b/src/util/promise.js @@ -4,7 +4,7 @@ * @param {Array} iteratee returns a new promise. * The iteratee is invoked with three arguments: (value, index, iterable). */ -function anySeries (iterable, iteratee) { +export function anySeries (iterable, iteratee) { let ret = Promise.reject(new Error('init')) iterable.forEach(function (item, idx) { ret = ret.catch(e => iteratee(item, idx, iterable)) @@ -18,9 +18,9 @@ function anySeries (iterable, iteratee) { * @param {Array} iteratee returns a new promise. * The iteratee is invoked with three arguments: (value, index, iterable). */ -function mapSeries (iterable, iteratee) { +export function mapSeries (iterable, iteratee) { let ret = Promise.resolve('init') - let result = [] + const result = [] iterable.forEach(function (item, idx) { ret = ret .then(() => iteratee(item, idx, iterable)) @@ -28,6 +28,3 @@ function mapSeries (iterable, iteratee) { }) return ret.then(() => result) } - -exports.anySeries = anySeries -exports.mapSeries = mapSeries diff --git a/src/util/strftime.js b/src/util/strftime.js index 51fc8975f..046d7a33e 100644 --- a/src/util/strftime.js +++ b/src/util/strftime.js @@ -1,16 +1,16 @@ -let monthNames = [ +const monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] -let monthNamesShort = [ +const monthNamesShort = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] -let dayNames = [ +const dayNames = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ] -let dayNamesShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] -let suffixes = { +const dayNamesShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] +const suffixes = { 1: 'st', 2: 'nd', 3: 'rd', @@ -18,9 +18,9 @@ let suffixes = { } // prototype extensions -let _date = { +const _date = { daysInMonth: function (d) { - let feb = _date.isLeapYear(d) ? 29 : 28 + const feb = _date.isLeapYear(d) ? 29 : 28 return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] }, @@ -36,21 +36,21 @@ let _date = { // TODO: that comment was retarted. fix it. getWeekOfYear: function (d, startDay) { // Skip to startDay of this week - let now = this.getDayOfYear(d) + (startDay - d.getDay()) + const now = this.getDayOfYear(d) + (startDay - d.getDay()) // Find the first startDay of the year - let jan1 = new Date(d.getFullYear(), 0, 1) - let then = (7 - jan1.getDay() + startDay) + const jan1 = new Date(d.getFullYear(), 0, 1) + const then = (7 - jan1.getDay() + startDay) return _number.pad(Math.floor((now - then) / 7) + 1, 2) }, isLeapYear: function (d) { - let year = d.getFullYear() + const year = d.getFullYear() return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year))) }, getSuffix: function (d) { - let str = d.getDate().toString() - let index = parseInt(str.slice(-1)) + const str = d.getDate().toString() + const index = parseInt(str.slice(-1)) return suffixes[index] || suffixes['default'] }, @@ -59,7 +59,7 @@ let _date = { } } -let _number = { +const _number = { pad: function (value, size, ch) { if (!ch) ch = '0' let result = value.toString() @@ -73,7 +73,7 @@ let _number = { } } -let formatCodes = { +const formatCodes = { a: function (d) { return dayNamesShort[d.getDay()] }, @@ -162,7 +162,7 @@ let formatCodes = { return d.getFullYear() }, z: function (d) { - let tz = d.getTimezoneOffset() / 60 * 100 + const tz = d.getTimezoneOffset() / 60 * 100 return (tz > 0 ? '-' : '+') + _number.pad(Math.abs(tz), 4) }, '%': function () { @@ -172,13 +172,13 @@ let formatCodes = { formatCodes.h = formatCodes.b formatCodes.N = formatCodes.L -let strftime = function (d, format) { +export default function (d, format) { let output = '' let remaining = format while (true) { - let r = /%./g - let results = r.exec(remaining) + const r = /%./g + const results = r.exec(remaining) // No more format codes. Add the remaining text and return if (!results) { @@ -190,10 +190,8 @@ let strftime = function (d, format) { remaining = remaining.slice(r.lastIndex) // Add the format code - let ch = results[0].charAt(1) - let func = formatCodes[ch] + const ch = results[0].charAt(1) + const func = formatCodes[ch] output += func ? func.call(this, d) : '%' + ch } } - -module.exports = strftime diff --git a/src/util/underscore.js b/src/util/underscore.js index cd7a5f442..b25ab45fa 100644 --- a/src/util/underscore.js +++ b/src/util/underscore.js @@ -5,11 +5,11 @@ const toStr = Object.prototype.toString * @param {any} value The value to check. * @return {Boolean} Returns true if value is a string, else false. */ -function isString (value) { +export function isString (value) { return toStr.call(value) === '[object String]' } -function stringify (value) { +export function stringify (value) { if (isNil(value)) { return String(value) } @@ -23,7 +23,7 @@ function stringify (value) { return value } - let cache = [] + const cache = [] return JSON.stringify(value, (key, value) => { if (isObject(value)) { if (cache.indexOf(value) !== -1) { @@ -35,17 +35,17 @@ function stringify (value) { }) } -function isNil (value) { +export function isNil (value) { return value === null || value === undefined } -function isArray (value) { +export function isArray (value) { // be compatible with IE 8 return toStr.call(value) === '[object Array]' } -function isError (value) { - let signature = Object.prototype.toString.call(value) +export function isError (value) { + const signature = Object.prototype.toString.call(value) // [object XXXError] return signature.substr(-6, 5) === 'Error' || (typeof value.message === 'string' && typeof value.name === 'string') @@ -59,9 +59,9 @@ function isError (value) { * @param {Function} iteratee The function invoked per iteration. * @return {Object} Returns object. */ -function forOwn (object, iteratee) { +export function forOwn (object, iteratee) { object = object || {} - for (let k in object) { + for (const k in object) { if (object.hasOwnProperty(k)) { if (iteratee(object[k], k, object) === false) break } @@ -80,20 +80,20 @@ function forOwn (object, iteratee) { * @param {...Object} sources The source objects. * @return {Object} Returns object. */ -function assign (object) { +export function assign (object) { object = isObject(object) ? object : {} - let srcs = Array.prototype.slice.call(arguments, 1) + const srcs = Array.prototype.slice.call(arguments, 1) srcs.forEach((src) => Object.assign(object, src)) return object } -function last (arr) { +export function last (arr) { return arr[arr.length - 1] } -function uniq (arr) { - let u = {} - let a = [] +export function uniq (arr) { + const u = {} + const a = [] for (let i = 0, l = arr.length; i < l; ++i) { if (u.hasOwnProperty(arr[i])) { continue @@ -110,8 +110,8 @@ function uniq (arr) { * @param {any} value The value to check. * @return {Boolean} Returns true if value is an object, else false. */ -function isObject (value) { - let type = typeof value +export function isObject (value) { + const type = typeof value return value != null && (type === 'object' || type === 'function') } @@ -123,33 +123,16 @@ function isObject (value) { * 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) { +export function range (start, stop, step) { if (arguments.length === 1) { stop = start start = 0 } step = step || 1 - let arr = [] + const arr = [] for (let i = start; i < stop; i += step) { arr.push(i) } return arr } - -// lang -exports.isString = isString -exports.isObject = isObject -exports.isArray = isArray -exports.isNil = isNil -exports.isError = isError - -// array -exports.range = range -exports.last = last - -// object -exports.forOwn = forOwn -exports.assign = assign -exports.uniq = uniq -exports.stringify = stringify diff --git a/src/util/url.js b/src/util/url.js index e38240271..37ce52ab9 100644 --- a/src/util/url.js +++ b/src/util/url.js @@ -1,5 +1,4 @@ -import resolveUrl from 'resolve-url' -import _ from './underscore' +import {last, isArray} from './underscore' const splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/ const urlRe = /^(?:\w+:)?\/\/([^\s.]+\.\S{2}|localhost[:?\d]*)\S*$/ @@ -15,11 +14,28 @@ export function valid (path) { } export function resolve (root, path) { - if (Object.prototype.toString.call(root) === '[object Array]') { + if (isArray(root)) { root = root[0] } - if (root && _.last(root) !== '/') { + if (root && last(root) !== '/') { root += '/' } return resolveUrl(root, path) } + +function resolveUrl (root, path) { + const base = document.createElement('base') + base.href = arguments[0] + + const head = document.getElementsByTagName('head')[0] + head.insertBefore(base, head.firstChild) + + const a = document.createElement('a') + a.href = path + const resolved = a.href + base.href = resolved + + head.removeChild(base) + + return resolved +} diff --git a/src/whitespace-ctrl.js b/src/whitespace-ctrl.js index 136f8ce5a..c8f367765 100644 --- a/src/whitespace-ctrl.js +++ b/src/whitespace-ctrl.js @@ -1,7 +1,7 @@ -const _ = require('./util/underscore.js') +import {assign} from './util/underscore.js' -function whiteSpaceCtrl (tokens, options) { - options = _.assign({ greedy: true }, options) +export default function whiteSpaceCtrl (tokens, options) { + options = assign({ greedy: true }, options) let inRaw = false tokens.forEach((token, i) => { @@ -33,15 +33,13 @@ function shouldTrimRight (token, inRaw, options) { function trimLeft (token, greedy) { if (!token || token.type !== 'html') return - let rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g + const rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g token.value = token.value.replace(rLeft, '') } function trimRight (token, greedy) { if (!token || token.type !== 'html') return - let rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g + const rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g token.value = token.value.replace(rRight, '') } - -module.exports = whiteSpaceCtrl diff --git a/test/express.js b/test/express.js index 98d814fd8..54c20a6fe 100644 --- a/test/express.js +++ b/test/express.js @@ -1,9 +1,12 @@ -const chai = require('chai') +import chai from 'chai' +import request from 'supertest' +import express from 'express' +import mock from 'mock-fs' +import Liquid from '../src' +import chaiAsPromised from 'chai-as-promised' + const expect = chai.expect -const mock = require('mock-fs') -const request = require('supertest') -const express = require('express') -const Liquid = require('../src') +chai.use(chaiAsPromised) describe('engine#express()', function () { let app, engine @@ -36,11 +39,11 @@ describe('engine#express()', function () { .expect(200, done) }) it('should pass error when file not found', function (done) { - let view = { + const view = { root: [] } - let file = '/not-exist.html' - let ctx = {} + const file = '/not-exist.html' + const ctx = {} engine.express().call(view, file, ctx, function (err) { try { expect(err.code).to.equal('ENOENT') @@ -82,7 +85,7 @@ describe('engine#express()', function () { .expect(200, done) }) it('should respect express views (Undefined) when lookup', function (done) { - let files = {} + const files = {} files[process.cwd() + '/views/include.html'] = '{% include file %}' files[process.cwd() + '/views/bar.html'] = 'bar' mock(files) diff --git a/test/filter.js b/test/filter.js index 493300f35..513c749d3 100644 --- a/test/filter.js +++ b/test/filter.js @@ -1,21 +1,21 @@ -const chai = require('chai') -const sinon = require('sinon') -const sinonChai = require('sinon-chai') -const expect = chai.expect +import chai from 'chai' +import sinon from 'sinon' +import sinonChai from 'sinon-chai' +import Filter from '../src/filter.js' +import {factory as scopeFactory} from '../src/scope.js' chai.use(sinonChai) - -let filter = require('../src/filter.js')() -let Scope = require('../src/scope.js') +const expect = chai.expect +const filter = Filter() describe('filter', function () { let scope beforeEach(function () { filter.clear() - scope = Scope.factory() + scope = scopeFactory() }) it('should return default filter when not registered', function () { - let result = filter.construct('foo') + const result = filter.construct('foo') expect(result.name).to.equal('foo') }) @@ -27,7 +27,7 @@ describe('filter', function () { it('should parse argument syntax', function () { filter.register('foo', x => x) - let f = filter.construct('foo: a, "b"') + const f = filter.construct('foo: a, "b"') expect(f.name).to.equal('foo') expect(f.args).to.deep.equal(['a', '"b"']) @@ -49,7 +49,7 @@ describe('filter', function () { }) it('should call filter with corrct arguments', function () { - let spy = sinon.spy() + const spy = sinon.spy() filter.register('foo', spy) filter.construct('foo: 33').render('foo', scope) expect(spy).to.have.been.calledWith('foo', 33) @@ -57,35 +57,35 @@ describe('filter', function () { it('should support arguments as named key/values', function () { filter.register('foo', x => x) - let f = filter.construct('foo: key1: "literal1", key2: value2') + const f = filter.construct('foo: key1: "literal1", key2: value2') expect(f.name).to.equal('foo') expect(f.args).to.deep.equal([ '\'key1\'', '"literal1"', '\'key2\'', 'value2' ]) }) it('should support arguments as named key/values with inline literals', function () { filter.register('foo', x => x) - let f = filter.construct('foo: "test0", key1: "literal1", key2: value2') + const f = filter.construct('foo: "test0", key1: "literal1", key2: value2') expect(f.name).to.equal('foo') expect(f.args).to.deep.equal([ '"test0"', '\'key1\'', '"literal1"', '\'key2\'', 'value2' ]) }) it('should support arguments as named key/values with inline values', function () { filter.register('foo', x => x) - let f = filter.construct('foo: test0, key1: "literal1", key2: value2') + const f = filter.construct('foo: test0, key1: "literal1", key2: value2') expect(f.name).to.equal('foo') expect(f.args).to.deep.equal([ 'test0', '\'key1\'', '"literal1"', '\'key2\'', 'value2' ]) }) it('should support argument values named same as keys', function () { filter.register('foo', x => x) - let f = filter.construct('foo: a: a') + const f = filter.construct('foo: a: a') expect(f.name).to.equal('foo') expect(f.args).to.deep.equal(['\'a\'', 'a']) }) it('should support argument literals named same as keys', function () { filter.register('foo', x => x) - let f = filter.construct('foo: a: "a"') + const f = filter.construct('foo: a: "a"') expect(f.name).to.equal('foo') expect(f.args).to.deep.equal(['\'a\'', '"a"']) }) diff --git a/test/filters.js b/test/filters.js index 0bfa4177b..fd827242b 100644 --- a/test/filters.js +++ b/test/filters.js @@ -6,7 +6,7 @@ chai.use(chaiAsPromised) const liquid = new Liquid() const expect = chai.expect -let ctx = { +const ctx = { date: new Date(), foo: 'bar', arr: [-2, 'a'], @@ -85,7 +85,7 @@ describe('filters', function () { describe('date', function () { it('should support date: %a %b %d %Y', function () { - let str = ctx.date.toDateString() + const str = ctx.date.toDateString() return test('{{ date | date:"%a %b %d %Y"}}', str) }) it('should create a new Date when given "now"', function () { @@ -142,7 +142,7 @@ describe('filters', function () { }) it('should support split/first', function () { - let src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' + + const src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' + '{{ my_array | first }}' return test(src, 'apples') }) @@ -155,19 +155,19 @@ describe('filters', function () { }) it('should support join', function () { - let src = '{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}' + + const src = '{% assign beatles = "John, Paul, George, Ringo" | split: ", " %}' + '{{ beatles | join: " and " }}' return test(src, 'John and Paul and George and Ringo') }) it('should support split/last', function () { - let src = '{% assign my_array = "zebra, octopus, giraffe, tiger" | split: ", " %}' + + const src = '{% assign my_array = "zebra, octopus, giraffe, tiger" | split: ", " %}' + '{{ my_array|last }}' return test(src, 'tiger') }) it('should support lstrip', function () { - let src = '{{ " So much room for activities! " | lstrip }}' + const src = '{{ " So much room for activities! " | lstrip }}' return test(src, 'So much room for activities! ') }) @@ -193,12 +193,12 @@ describe('filters', function () { }) it('should support string_with_newlines', function () { - let src = '{% capture string_with_newlines %}\n' + + const src = '{% capture string_with_newlines %}\n' + 'Hello\n' + 'there\n' + '{% endcapture %}' + '{{ string_with_newlines | newline_to_br }}' - let dst = '
' + + const dst = '
' + 'Hello
' + 'there
' return test(src, dst) diff --git a/test/index.js b/test/index.js index e817f2962..2d392505a 100644 --- a/test/index.js +++ b/test/index.js @@ -1,8 +1,10 @@ -const chai = require('chai') +import chai from 'chai' +import mock from 'mock-fs' +import Liquid from '../src' +import chaiAsPromised from 'chai-as-promised' + const expect = chai.expect -const Liquid = require('../src') -const mock = require('mock-fs') -chai.use(require('chai-as-promised')) +chai.use(chaiAsPromised) describe('liquid', function () { let engine, strictEngine, ctx @@ -37,7 +39,7 @@ describe('liquid', function () { }) describe('Liquid', function () { it('should ignore invalid root option', function () { - let liquid = Liquid({ root: /regex/ }) + const liquid = Liquid({ root: /regex/ }) expect(liquid.options.root).to.deep.equal([]) }) }) @@ -68,18 +70,18 @@ describe('liquid', function () { }).to.not.throw() }) it('should render template multiple times', function () { - let template = engine.parse('{{obj}}') + const template = engine.parse('{{obj}}') return engine.render(template, ctx) .then(result => expect(result).to.equal('{"foo":"bar"}')) .then(() => engine.render(template, ctx)) .then((result) => expect(result).to.equal('{"foo":"bar"}')) }) it('should render filters', function () { - let template = engine.parse('

{{arr | join: "_"}}

') + const template = engine.parse('

{{arr | join: "_"}}

') return expect(engine.render(template, ctx)).to.eventually.equal('

-2_a

') }) it('should render accessive filters', function () { - let src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' + + const src = '{% assign my_array = "apples, oranges, peaches, plums" | split: ", " %}' + '{{ my_array | first }}' return expect(engine.parseAndRender(src)).to.eventually.equal('apples') }) @@ -89,7 +91,7 @@ describe('liquid', function () { .to.eventually.equal('foo') }) it('should find files without extname', function () { - let engine = Liquid({root: '/root'}) + const engine = Liquid({root: '/root'}) return expect(engine.renderFile('/root/files/bar', ctx)) .to.eventually.equal('bar') }) @@ -106,7 +108,7 @@ describe('liquid', function () { .to.eventually.equal('foo') }) it('should default root to cwd', function () { - let files = {} + const files = {} files[process.cwd() + '/foo.html'] = 'FOO' mock(files) diff --git a/test/lexical.js b/test/lexical.js index 142cc1d5d..fedc8e24a 100644 --- a/test/lexical.js +++ b/test/lexical.js @@ -1,7 +1,7 @@ const chai = require('chai') const expect = chai.expect -let lexical = require('../src/lexical.js') +const lexical = require('../src/lexical.js') describe('lexical', function () { it('should test filter syntax', function () { @@ -105,26 +105,26 @@ describe('lexical', function () { }) it('should throw if non-literal', function () { - let fn = () => lexical.parseLiteral('a') + const fn = () => lexical.parseLiteral('a') expect(fn).to.throw("cannot parse 'a' as literal") }) }) describe('.matchValue()', function () { it('should match -5-5', function () { - let match = lexical.matchValue('-5-5') + const match = lexical.matchValue('-5-5') expect(match && match[0]).to.equal('-5-5') }) it('should match 4-3', function () { - let match = lexical.matchValue('4-3') + const match = lexical.matchValue('4-3') expect(match && match[0]).to.equal('4-3') }) it('should match 4-3', function () { - let match = lexical.matchValue('4-3') + const match = lexical.matchValue('4-3') expect(match && match[0]).to.equal('4-3') }) it('should match var-1', function () { - let match = lexical.matchValue('var-1') + const match = lexical.matchValue('var-1') expect(match && match[0]).to.equal('var-1') }) }) diff --git a/test/options/cache.js b/test/options/cache.js index 92cf539fa..3b7943923 100644 --- a/test/options/cache.js +++ b/test/options/cache.js @@ -1,8 +1,10 @@ -const chai = require('chai') +import chai from 'chai' +import mock from 'mock-fs' +import Liquid from '../../src' +import chaiAsPromised from 'chai-as-promised' + const expect = chai.expect -const mock = require('mock-fs') -const Liquid = require('../../src') -chai.use(require('chai-as-promised')) +chai.use(chaiAsPromised) describe('cache options', function () { let engine diff --git a/test/options/strict.js b/test/options/strict.js index f699da17f..e7e460504 100644 --- a/test/options/strict.js +++ b/test/options/strict.js @@ -6,7 +6,7 @@ chai.use(require('chai-as-promised')) describe('strict options', function () { let engine - let ctx = {} + const ctx = {} beforeEach(function () { engine = Liquid({ root: '/root/', @@ -18,16 +18,16 @@ describe('strict options', function () { .eventually.equal('beforeafter') }) it('should throw when strict_variables true', function () { - let tpl = engine.parse('before{{notdefined}}after') - let opts = { + const tpl = engine.parse('before{{notdefined}}after') + const opts = { strict_variables: true } return expect(engine.render(tpl, ctx, opts)).to .be.rejectedWith(/undefined variable: notdefined/) }) it('should pass strict_variables to render by parseAndRender', function () { - let html = 'before{{notdefined}}after' - let opts = { + const html = 'before{{notdefined}}after' + const opts = { strict_variables: true } return expect(engine.parseAndRender(html, ctx, opts)).to diff --git a/test/options/trimming.js b/test/options/trimming.js index c9a2f51cc..d34565fdc 100644 --- a/test/options/trimming.js +++ b/test/options/trimming.js @@ -1,62 +1,64 @@ -const chai = require('chai') +import chai from 'chai' +import Liquid from '../../src' +import chaiAsPromised from 'chai-as-promised' + const expect = chai.expect -const Liquid = require('../../src') -chai.use(require('chai-as-promised')) +chai.use(chaiAsPromised) describe('trimming', function () { - let ctx = {name: 'harttle'} + const ctx = {name: 'harttle'} describe('tag trimming', function () { it('should respect trim_tag_left', function () { - let engine = Liquid({ trim_tag_left: true }) + const engine = Liquid({ trim_tag_left: true }) return expect(engine.parseAndRender(' \n \t{%if true%}foo{%endif%} ')) .to.eventually.equal('foo ') }) it('should respect trim_tag_right', function () { - let engine = Liquid({ trim_tag_right: true }) + const engine = Liquid({ trim_tag_right: true }) return expect(engine.parseAndRender('\t{%if true%}foo{%endif%} \n')) .to.eventually.equal('\tfoo') }) it('should not trim value', function () { - let engine = Liquid({ trim_tag_left: true, trim_tag_right: true }) + const engine = Liquid({ trim_tag_left: true, trim_tag_right: true }) return expect(engine.parseAndRender('{%if true%}a {{name}} b{%endif%}', ctx)) .to.eventually.equal('a harttle b') }) }) describe('value trimming', function () { it('should respect trim_value_left', function () { - let engine = Liquid({ trim_value_left: true }) + const engine = Liquid({ trim_value_left: true }) return expect(engine.parseAndRender(' \n \t{{name}} ', ctx)) .to.eventually.equal('harttle ') }) it('should respect trim_value_right', function () { - let engine = Liquid({ trim_value_right: true }) + const engine = Liquid({ trim_value_right: true }) return expect(engine.parseAndRender(' \n \t{{name}} ', ctx)) .to.eventually.equal(' \n \tharttle') }) it('should respect not trim tag', function () { - let engine = Liquid({ trim_value_left: true, trim_value_right: true }) + const engine = Liquid({ trim_value_left: true, trim_value_right: true }) return expect(engine.parseAndRender('\t{% if true %} aha {%endif%}\t')) .to.eventually.equal('\t aha \t') }) }) describe('greedy', function () { - let src = '\n {%-if true-%}\n a \n{{-name-}}{%-endif-%}\n ' + const src = '\n {%-if true-%}\n a \n{{-name-}}{%-endif-%}\n ' it('should enable greedy by default', function () { - let engine = Liquid() + const engine = Liquid() return expect(engine.parseAndRender(src, ctx)) .to.eventually.equal('aharttle') }) it('should respect to greedy:false by default', function () { - let engine = Liquid({greedy: false}) + const engine = Liquid({greedy: false}) return expect(engine.parseAndRender(src, ctx)) .to.eventually.equal('\n a \nharttle ') }) }) describe('markup', function () { it('should support trim using markup', function () { - let engine = Liquid() - let src = [ + const engine = Liquid() + const src = [ '{%- assign username = "John G. Chalmers-Smith" -%}', '{%- if username and username.length > 10 -%}', ' Wow, {{ username }}, you have a long name!', @@ -64,12 +66,12 @@ describe('trimming', function () { ' Hello there!', '{%- endif -%}' ].join('\n') - let dst = 'Wow, John G. Chalmers-Smith, you have a long name!' + const dst = 'Wow, John G. Chalmers-Smith, you have a long name!' return expect(engine.parseAndRender(src)).to.eventually.equal(dst) }) it('should not trim when not specified', function () { - let engine = Liquid() - let src = [ + const engine = Liquid() + const src = [ '{% assign username = "John G. Chalmers-Smith" %}', '{% if username and username.length > 10 %}', ' Wow, {{ username }}, you have a long name!', @@ -77,7 +79,7 @@ describe('trimming', function () { ' Hello there!', '{% endif %}' ].join('\n') - let dst = '\n\n Wow, John G. Chalmers-Smith, you have a long name!\n' + const dst = '\n\n Wow, John G. Chalmers-Smith, you have a long name!\n' return expect(engine.parseAndRender(src)).to.eventually.equal(dst) }) }) diff --git a/test/parser.js b/test/parser.js index 6a0b3849d..d8a74b318 100644 --- a/test/parser.js +++ b/test/parser.js @@ -1,15 +1,17 @@ -const chai = require('chai') +import chai from 'chai' +import sinonChai from 'sinon-chai' +import Filter from '../src/filter.js' +import Tag from '../src/tag.js' +import Template from '../src/parser.js' + const expect = chai.expect - -chai.use(require('sinon-chai')) - -let filter = require('../src/filter.js')() -let tag = require('../src/tag.js')() -let Template = require('../src/parser.js') +const filter = Filter() +const tag = Tag() +chai.use(sinonChai) describe('template', function () { let template - let add = (l, r) => l + r + const add = (l, r) => l + r beforeEach(function () { filter.clear() @@ -26,21 +28,21 @@ describe('template', function () { }) it('should parse value string', function () { - let tpl = template.parseValue('foo') + const tpl = template.parseValue('foo') expect(tpl.type).to.equal('value') expect(tpl.initial).to.equal('foo') expect(tpl.filters).to.deep.equal([]) }) it('should parse value string with a simple filter', function () { - let tpl = template.parseValue('foo | add: 3, "foo"') + const tpl = template.parseValue('foo | add: 3, "foo"') expect(tpl.initial).to.equal('foo') expect(tpl.filters.length).to.equal(1) expect(tpl.filters[0].filter).to.equal(add) }) it('should parse value string with filters', function () { - let tpl = template.parseValue('foo | add: "|" | add') + const tpl = template.parseValue('foo | add: "|" | add') expect(tpl.initial).to.equal('foo') expect(tpl.filters.length).to.equal(2) }) diff --git a/test/render.js b/test/render.js index f0c78ed9a..9229aa445 100644 --- a/test/render.js +++ b/test/render.js @@ -1,18 +1,20 @@ -'use strict' -const chai = require('chai') -const chaiAsPromised = require('chai-as-promised') -const expect = chai.expect -const sinonChai = require('sinon-chai') -const sinon = require('sinon') +import chai from 'chai' +import chaiAsPromised from 'chai-as-promised' +import sinonChai from 'sinon-chai' +import sinon from 'sinon' +import Tag from '../src/tag.js' +import {factory as scopeFactory} from '../src/scope.js' +import Filter from '../src/filter' +import Render from '../src/render.js' +import parser from '../src/parser.js' chai.use(sinonChai) chai.use(chaiAsPromised) -let tag = require('../src/tag.js')() -let Scope = require('../src/scope.js') -let filter = require('../src/filter')() -let Render = require('../src/render.js') -let Template = require('../src/parser.js')(tag, filter) +const expect = chai.expect +const tag = Tag() +const filter = Filter() +const Template = parser(tag, filter) let render describe('render', function () { @@ -24,43 +26,41 @@ describe('render', function () { describe('.renderTemplates()', function () { it('should throw when scope undefined', function () { - expect(function () { - render.renderTemplates([]) - }).to.throw(/scope undefined/) + expect(render.renderTemplates([])).to.be.rejectedWith(/scope undefined/) }) it('should render html', function () { - let scope = Scope.factory({}) + const scope = scopeFactory({}) return expect(render.renderTemplates([{type: 'html', value: '

'}], scope)).to.eventually.equal('

') }) }) describe('.renderValue()', function () { it('should respect to .to_liquid() method', function () { - let scope = Scope.factory({ + const scope = scopeFactory({ bar: { to_liquid: x => 'custom' } }) - let tpl = Template.parseValue('bar') + const tpl = Template.parseValue('bar') return expect(render.renderValue(tpl, scope)).to.eventually.equal('custom') }) it('should stringify objects', function () { - let scope = Scope.factory({ + const scope = scopeFactory({ foo: { obj: { arr: ['a', 2] } } }) - let tpl = Template.parseValue('foo') + const tpl = Template.parseValue('foo') return expect(render.renderValue(tpl, scope)).to.eventually.equal('{"obj":{"arr":["a",2]}}') }) it('should skip circular property', function () { - let ctx = { foo: { num: 2 }, bar: 'bar' } + const ctx = { foo: { num: 2 }, bar: 'bar' } ctx.foo.circular = ctx - let scope = Scope.factory(ctx) - let tpl = Template.parseValue('foo') + const scope = scopeFactory(ctx) + const tpl = Template.parseValue('foo') return expect(render.renderValue(tpl, scope)).to.eventually.equal('{"num":2,"circular":{"bar":"bar"}}') }) it('should skip function property', function () { - let scope = Scope.factory({obj: {foo: 'foo', bar: x => x}}) - let tpl = Template.parseValue('obj') + const scope = scopeFactory({obj: {foo: 'foo', bar: x => x}}) + const tpl = Template.parseValue('obj') return expect(render.renderValue(tpl, scope)).to.eventually.equal('{"foo":"foo"}') }) }) @@ -74,24 +74,24 @@ describe('render', function () { it('should eval value', function () { filter.register('date', (l, r) => l + r) filter.register('time', (l, r) => l + 3 * r) - let tpl = Template.parseValue('foo.bar[0] | date: "b" | time:2') - let scope = Scope.factory({ + const tpl = Template.parseValue('foo.bar[0] | date: "b" | time:2') + const scope = scopeFactory({ foo: { bar: ['a'] } }) expect(render.evalValue(tpl, scope)).to.equal('ab6') }) it('should reserve type', function () { filter.register('arr', () => [1]) - let tpl = Template.parseValue('"x" | arr') - expect(render.evalValue(tpl, Scope.factory())).to.deep.equal([1]) + const tpl = Template.parseValue('"x" | arr') + expect(render.evalValue(tpl, scopeFactory())).to.deep.equal([1]) }) it('should eval filter with correct arguments', function () { - let date = sinon.stub().returns('y') - let time = sinon.spy() + const date = sinon.stub().returns('y') + const time = sinon.spy() filter.register('date', date) filter.register('time', time) - let tpl = Template.parseValue('foo.bar | date: "b" | time:2') - let scope = Scope.factory({ + const tpl = Template.parseValue('foo.bar | date: "b" | time:2') + const scope = scopeFactory({ foo: {bar: 'bar'} }) render.evalValue(tpl, scope) diff --git a/test/scope.js b/test/scope.js index 8165ab1a8..92225bb58 100644 --- a/test/scope.js +++ b/test/scope.js @@ -1,5 +1,5 @@ import chai from 'chai' -import Scope from '../src/scope.js' +import {factory as scopeFactory} from '../src/scope.js' const expect = chai.expect @@ -14,7 +14,7 @@ describe('scope', function () { arr: ['a', 'b'] } } - scope = Scope.factory(ctx) + scope = scopeFactory(ctx) }) describe('#propertyAccessSeq()', function () { @@ -88,7 +88,7 @@ describe('scope', function () { }) it('should respect to to_liquid', function () { - let scope = Scope.factory({foo: { + const scope = scopeFactory({foo: { to_liquid: () => ({bar: 'BAR'}), bar: 'bar' }}) @@ -96,7 +96,7 @@ describe('scope', function () { }) it('should respect to toLiquid', function () { - let scope = Scope.factory({foo: { + const scope = scopeFactory({foo: { toLiquid: () => ({bar: 'BAR'}), bar: 'bar' }}) @@ -162,7 +162,7 @@ describe('scope', function () { describe('strict_variables', function () { let scope beforeEach(function () { - scope = Scope.factory(ctx, { + scope = scopeFactory(ctx, { strict_variables: true }) }) @@ -227,10 +227,10 @@ describe('scope', function () { }) }) it('should pop specified scope', function () { - let scope1 = { + const scope1 = { foo: 'foo' } - let scope2 = { + const scope2 = { bar: 'bar' } scope.push(scope1) @@ -242,7 +242,7 @@ describe('scope', function () { expect(scope.get('bar')).to.equal('bar') }) it('should throw when specified scope not found', function () { - let scope1 = { + const scope1 = { foo: 'foo' } expect(() => scope.pop(scope1)).to.throw('scope not found, cannot pop') diff --git a/test/syntax.js b/test/syntax.js index 934832aee..66d53323c 100644 --- a/test/syntax.js +++ b/test/syntax.js @@ -1,11 +1,11 @@ const chai = require('chai') const expect = chai.expect -let syntax = require('../src/syntax.js') -let Scope = require('../src/scope.js') +const syntax = require('../src/syntax.js') +const Scope = require('../src/scope.js') -let evalExp = syntax.evalExp -let evalValue = syntax.evalValue -let isTruthy = syntax.isTruthy +const evalExp = syntax.evalExp +const evalValue = syntax.evalValue +const isTruthy = syntax.isTruthy describe('expression', function () { let scope @@ -36,7 +36,7 @@ describe('expression', function () { }) it('should throw if not valid', function () { - let fn = () => evalValue('===') + const fn = () => evalValue('===') expect(fn).to.throw("cannot eval '===' as value") }) }) diff --git a/test/tag.js b/test/tag.js index 77df19282..49eb4fd58 100644 --- a/test/tag.js +++ b/test/tag.js @@ -1,15 +1,17 @@ -const chai = require('chai') -const sinon = require('sinon') -const expect = chai.expect -chai.use(require('sinon-chai')) +import chai from 'chai' +import Tag from '../src/tag.js' +import {factory as scopeFactory} from '../src/scope.js' +import sinon from 'sinon' +import sinonChai from 'sinon-chai' -let tag = require('../src/tag.js')() -let Scope = require('../src/scope.js') +chai.use(sinonChai) +const expect = chai.expect +const tag = Tag() describe('tag', function () { let scope before(function () { - scope = Scope.factory({ + scope = scopeFactory({ foo: 'bar', arr: [2, 1], bar: { @@ -37,19 +39,18 @@ describe('tag', function () { }).not.throw() }) - it('should call tag.render', function () { - let spy = sinon.spy() + it('should call tag.render', async function () { + const spy = sinon.spy() tag.register('foo', { render: spy }) - return tag - .construct({ - type: 'tag', - value: 'foo', - name: 'foo' - }, []) - .render(scope, {}) - .then(() => expect(spy).to.have.been.called) + const token = { + type: 'tag', + value: 'foo', + name: 'foo' + } + await tag.construct(token, []).render(scope, {}) + expect(spy).to.have.been.called }) describe('hash', function () { @@ -66,33 +67,33 @@ describe('tag', function () { args: 'aa:foo bb: arr[0] cc: 2.3\ndd:bar.coo' } }) - it('should call tag.render with scope', function () { - return tag.construct(token, []).render(scope, {}) - .then(() => expect(spy).to.have.been.calledWithMatch(scope)) + it('should call tag.render with scope', async function () { + await tag.construct(token, []).render(scope, {}) + expect(spy).to.have.been.calledWithMatch(scope) }) - it('should resolve identifier hash', function () { - return tag.construct(token, []).render(scope, {}) - .then(() => expect(spy).to.have.been.calledWithMatch({}, { - aa: 'bar' - })) + it('should resolve identifier hash', async function () { + await tag.construct(token, []).render(scope, {}) + expect(spy).to.have.been.calledWithMatch({}, { + aa: 'bar' + }) }) - it('should accept space between key/value', function () { - return tag.construct(token, []).render(scope, {}) - .then(() => expect(spy).to.have.been.calledWithMatch({}, { - bb: 2 - })) + it('should accept space between key/value', async function () { + await tag.construct(token, []).render(scope, {}) + expect(spy).to.have.been.calledWithMatch({}, { + bb: 2 + }) }) - it('should resolve number value hash', function () { - return tag.construct(token, []).render(scope, {}) - .then(() => expect(spy).to.have.been.calledWithMatch(scope, { - cc: 2.3 - })) + it('should resolve number value hash', async function () { + await tag.construct(token, []).render(scope, {}) + expect(spy).to.have.been.calledWithMatch(scope, { + cc: 2.3 + }) }) - it('should resolve property access hash', function () { - return tag.construct(token, []).render(scope, {}) - .then(() => expect(spy).to.have.been.calledWithMatch(scope, { - dd: 'uoo' - })) + it('should resolve property access hash', async function () { + await tag.construct(token, []).render(scope, {}) + expect(spy).to.have.been.calledWithMatch(scope, { + dd: 'uoo' + }) }) }) }) diff --git a/test/tags/assign.js b/test/tags/assign.js index a2604b833..d8cab06b2 100644 --- a/test/tags/assign.js +++ b/test/tags/assign.js @@ -1,29 +1,30 @@ -'use strict' -const Liquid = require('../../src') -const chai = require('chai') +import Liquid from '../../src' +import chai from 'chai' +import sinonChai from 'chai-as-promised' + +chai.use(sinonChai) const expect = chai.expect -chai.use(require('chai-as-promised')) describe('tags/assign', function () { - let liquid = Liquid() + const liquid = Liquid() it('should throw when variable expression illegal', function () { - let src = '{% assign / %}' - let ctx = {} + const src = '{% assign / %}' + const ctx = {} return expect(liquid.parseAndRender(src, ctx)).to.be.rejectedWith(/illegal/) }) it('should support assign to a string', function () { - let src = '{% assign foo="bar" %}{{foo}}' + const src = '{% assign foo="bar" %}{{foo}}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('bar') }) it('should support assign to a number', function () { - let src = '{% assign foo=10086 %}{{foo}}' + const src = '{% assign foo=10086 %}{{foo}}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('10086') }) it('should shading rather than overwriting', function () { - let ctx = {foo: 'foo'} - let src = '{% assign foo="FOO" %}{{foo}}' + const ctx = {foo: 'foo'} + const src = '{% assign foo="FOO" %}{{foo}}' return liquid.parseAndRender(src, ctx) .then(x => { expect(x).to.equal('FOO') @@ -31,37 +32,37 @@ describe('tags/assign', function () { }) }) it('should assign as array', function () { - let src = '{% assign foo=(1..3) %}{{foo}}' + const src = '{% assign foo=(1..3) %}{{foo}}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('[1,2,3]') }) it('should assign as filter result', function () { - let src = '{% assign foo="a b" | capitalize | split: " " | first %}{{foo}}' + const src = '{% assign foo="a b" | capitalize | split: " " | first %}{{foo}}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('A') }) it('should assign var-1', function () { - let src = '{% assign var-1 = 5 %}{{ var-1 }}' + const src = '{% assign var-1 = 5 %}{{ var-1 }}' return expect(liquid.parseAndRender(src)).to.eventually.equal('5') }) it('should assign var-', function () { - let src = '{% assign var- = 5 %}{{ var- }}' + const src = '{% assign var- = 5 %}{{ var- }}' return expect(liquid.parseAndRender(src)).to.eventually.equal('5') }) it('should assign -var', function () { - let src = '{% assign -let = 5 %}{{ -let }}' + const src = '{% assign -let = 5 %}{{ -let }}' return expect(liquid.parseAndRender(src)).to.eventually.equal('5') }) it('should assign -5-5', function () { - let src = '{% assign -5-5 = 5 %}{{ -5-5 }}' + const src = '{% assign -5-5 = 5 %}{{ -5-5 }}' return expect(liquid.parseAndRender(src)).to.eventually.equal('5') }) it('should assign 4-3', function () { - let src = '{% assign 4-3 = 5 %}{{ 4-3 }}' + const src = '{% assign 4-3 = 5 %}{{ 4-3 }}' return expect(liquid.parseAndRender(src)).to.eventually.equal('5') }) it('should not assign -6', function () { - let src = '{% assign -6 = 5 %}{{ -6 }}' + const src = '{% assign -6 = 5 %}{{ -6 }}' return expect(liquid.parseAndRender(src)).to.eventually.equal('-6') }) }) diff --git a/test/tags/capture.js b/test/tags/capture.js index 0d38faed0..e83ad6247 100644 --- a/test/tags/capture.js +++ b/test/tags/capture.js @@ -5,17 +5,17 @@ const expect = chai.expect chai.use(require('chai-as-promised')) describe('tags/capture', function () { - let liquid = Liquid() + const liquid = Liquid() it('should support capture', function () { - let src = '{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}' + const src = '{% capture f %}{{"a" | capitalize}}{%endcapture%}{{f}}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('A') }) it('should shading rather than overwriting', function () { - let src = '{% capture var %}10{% endcapture %}{{var}}' - let ctx = {'var': 20} + const src = '{% capture var %}10{% endcapture %}{{var}}' + const ctx = {'var': 20} return liquid.parseAndRender(src, ctx) .then(x => { expect(x).to.equal('10') @@ -24,13 +24,13 @@ describe('tags/capture', function () { }) it('should throw on invalid identifier', function () { - let src = '{% capture = %}{%endcapture%}' + const src = '{% capture = %}{%endcapture%}' return expect(liquid.parseAndRender(src)) .to.be.rejectedWith(/= not valid identifier/) }) it('should throw when capture not closed', function () { - let src = '{%capture c%}{{c}}' + const src = '{%capture c%}{{c}}' return expect(liquid.parseAndRender(src)) .to.be.rejectedWith(/tag .* not closed/) }) diff --git a/test/tags/case.js b/test/tags/case.js index 97f87a40f..3cb943a21 100644 --- a/test/tags/case.js +++ b/test/tags/case.js @@ -5,46 +5,46 @@ const expect = chai.expect chai.use(require('chai-as-promised')) describe('tags/case', function () { - let liquid = Liquid() + const liquid = Liquid() it('should reject if not closed', function () { - let src = '{% case "foo"%}' + const src = '{% case "foo"%}' return expect(liquid.parseAndRender(src)) .to.be.rejectedWith(/{% case "foo"%} not closed/) }) it('should hit the specified case', function () { - let src = '{% case "foo"%}' + + const src = '{% case "foo"%}' + '{% when "foo" %}foo{% when "bar"%}bar' + '{%endcase%}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('foo') }) it('should resolve empty string if not hit', function () { - let src = '{% case empty %}' + + const src = '{% case empty %}' + '{% when "foo" %}foo{% when ""%}bar' + '{%endcase%}' - let ctx = { + const ctx = { empty: '' } return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('bar') }) it('should accept empty string as branch name', function () { - let src = '{% case false %}' + + const src = '{% case false %}' + '{% when "foo" %}foo{% when ""%}bar' + '{%endcase%}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('') }) it('should support boolean case', function () { - let src = '{% case false %}' + + const src = '{% case false %}' + '{% when "foo" %}foo{% when false%}bar' + '{%endcase%}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('bar') }) it('should support else branch', function () { - let src = '{% case "a" %}' + + const src = '{% case "a" %}' + '{% when "b" %}b{% when "c"%}c{%else %}d' + '{%endcase%}' return expect(liquid.parseAndRender(src)) diff --git a/test/tags/comment.js b/test/tags/comment.js index 5c930da2e..35df73e0e 100644 --- a/test/tags/comment.js +++ b/test/tags/comment.js @@ -5,29 +5,29 @@ const expect = chai.expect chai.use(require('chai-as-promised')) describe('tags/comment', function () { - let liquid = Liquid() + const liquid = Liquid() it('should support empty content', function () { - let src = '{% comment %}{% raw%}' + const src = '{% comment %}{% raw%}' return expect(liquid.parseAndRender(src)) .to.be.rejectedWith(/{% comment %} not closed/) }) it('should ignore plain string', function () { - let src = 'My name is {% comment %}super{% endcomment %} Shopify.' + const src = 'My name is {% comment %}super{% endcomment %} Shopify.' return expect(liquid.parseAndRender(src)) .to.eventually.equal('My name is Shopify.') }) it('should ignore output tokens', function () { - let src = '{% comment %}\n{{ foo}} \n{% endcomment %}' + const src = '{% comment %}\n{{ foo}} \n{% endcomment %}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('') }) it('should ignore tag tokens', function () { - let src = '{% comment %}{%if true%}true{%else%}false{%endif%}{% endcomment %}' + const src = '{% comment %}{%if true%}true{%else%}false{%endif%}{% endcomment %}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('') }) it('should ignore un-balenced tag tokens', function () { - let src = '{% comment %}{%if true%}true{%else%}false{% endcomment %}' + const src = '{% comment %}{%if true%}true{%else%}false{% endcomment %}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('') }) diff --git a/test/tags/cycle.js b/test/tags/cycle.js index 5d4a2edd3..7bb16b6f0 100644 --- a/test/tags/cycle.js +++ b/test/tags/cycle.js @@ -5,10 +5,10 @@ const expect = chai.expect chai.use(require('chai-as-promised')) describe('tags/cycle', function () { - let liquid = Liquid() + const liquid = Liquid() it('should support cycle', function () { - let src = "{% cycle '1', '2', '3' %}" + const src = "{% cycle '1', '2', '3' %}" return expect(liquid.parseAndRender(src + src + src + src)) .to.eventually.equal('1231') }) @@ -19,8 +19,8 @@ describe('tags/cycle', function () { }) it('should support cycle in for block', function () { - let src = '{% for i in (1..5) %}{% cycle one, "e"%}{% endfor %}' - let ctx = { + const src = '{% for i in (1..5) %}{% cycle one, "e"%}{% endfor %}' + const ctx = { one: 1 } return expect(liquid.parseAndRender(src, ctx)) @@ -28,10 +28,10 @@ describe('tags/cycle', function () { }) it('should support cycle group', function () { - let src = "{% cycle one: '1', '2', '3'%}" + + const src = "{% cycle one: '1', '2', '3'%}" + "{% cycle 1: '1', '2', '3'%}" + "{% cycle 2: '1', '2', '3'%}" - let ctx = { + const ctx = { one: 1 } return expect(liquid.parseAndRender(src, ctx)) diff --git a/test/tags/decrement.js b/test/tags/decrement.js index 85cbeab9f..252d4bee6 100644 --- a/test/tags/decrement.js +++ b/test/tags/decrement.js @@ -5,22 +5,22 @@ const expect = chai.expect chai.use(require('chai-as-promised')) describe('tags/decrement', function () { - let liquid = Liquid() + const liquid = Liquid() it('should throw when variable expression illegal', function () { - let src = '{% decrement / %}{{var}}' - let ctx = {} + const src = '{% decrement / %}{{var}}' + const ctx = {} return expect(liquid.parseAndRender(src, ctx)).to.be.rejectedWith(/illegal/) }) it('should decrement undefined variable', function () { - let src = '{% decrement var %}{% decrement var %}{% decrement var %}' + const src = '{% decrement var %}{% decrement var %}{% decrement var %}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('-1-2-3') }) it('should decrement defined variable', function () { - let src = '{% decrement var %}{% decrement var %}{% decrement var %}' - let ctx = {'var': 10} + const src = '{% decrement var %}{% decrement var %}{% decrement var %}' + const ctx = {'var': 10} return liquid.parseAndRender(src, ctx) .then(x => { expect(x).to.equal('987') @@ -29,31 +29,31 @@ describe('tags/decrement', function () { }) it('should be independent from assign', function () { - let src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %}' + const src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('-1-2-3') }) it('should be independent from capture', function () { - let src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %}' + const src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('-1-2-3') }) it('should not shading assign', function () { - let src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}' + const src = '{% assign var=10 %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('-1-2-3 10') }) it('should not shading capture', function () { - let src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}' + const src = '{% capture var %}10{% endcapture %}{% decrement var %}{% decrement var %}{% decrement var %} {{var}}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('-1-2-3 10') }) it('should share the same variable with increment', function () { - let src = '{%increment var%}{%increment var%}{%decrement var%}{%decrement var%}{%increment var%}' + const src = '{%increment var%}{%increment var%}{%decrement var%}{%decrement var%}{%increment var%}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('01100') }) diff --git a/test/tags/for.js b/test/tags/for.js index d9885d5b3..2c12d4b32 100644 --- a/test/tags/for.js +++ b/test/tags/for.js @@ -23,25 +23,25 @@ describe('tags/for', function () { } }) it('should support array', function () { - let src = '{%for c in alpha%}{{c}}{%endfor%}' + const src = '{%for c in alpha%}{{c}}{%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('abc') }) it('should support object', function () { - let src = '{%for item in obj%}{{item[0]}},{{item[1]}}-{%else%}b{%endfor%}' + const src = '{%for item in obj%}{{item[0]}},{{item[1]}}-{%else%}b{%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('foo,bar-coo,haa-') }) describe('scope', function () { it('should read super scope', function () { - let src = '{%for a in (1..2)%}{{num}}{%endfor%}' + const src = '{%for a in (1..2)%}{{num}}{%endfor%}' return expect(liquid.parseAndRender(src, {num: 1})) .to.eventually.equal('11') }) it('should write super scope', function () { - let src = '{%for a in (1..2)%}{{num}}{%assign num = 2%}{%endfor%}' + const src = '{%for a in (1..2)%}{{num}}{%assign num = 2%}{%endfor%}' return expect(liquid.parseAndRender(src, {num: 1})) .to.eventually.equal('12') }) @@ -49,13 +49,13 @@ describe('tags/for', function () { describe('illegal', function () { it('should reject when for not closed', function () { - let src = '{%for c in alpha%}{{c}}' + const src = '{%for c in alpha%}{{c}}' return expect(liquid.parseAndRender(src, ctx)) .to.be.rejectedWith(/tag .* not closed/) }) it('should reject when inner templates rejected', function () { - let src = '{%for c in alpha%}{%throwingTag%}{%endfor%}' + const src = '{%for c in alpha%}{%throwingTag%}{%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.be.rejectedWith(/intended render error/) }) @@ -63,51 +63,51 @@ describe('tags/for', function () { describe('else', function () { it('should goto else for empty array', function () { - let src = '{%for c in emptyArray%}a{%else%}b{%endfor%}' + const src = '{%for c in emptyArray%}a{%else%}b{%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('b') }) it('should treat non-empty string as one single element', function () { - let src = '{%for c in "abc"%}x{{c}}{%else%}y{%endfor%}' + const src = '{%for c in "abc"%}x{{c}}{%else%}y{%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('xabc') }) it('should goto else for empty string', function () { - let src = '{%for c in ""%}a{%else%}b{%endfor%}' + const src = '{%for c in ""%}a{%else%}b{%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('b') }) it('should goto else for empty string object', function () { // it should be false although `new String` is none-conform - let src = '{%for c in strObj%}a{%else%}b{%endfor%}' + const src = '{%for c in strObj%}a{%else%}b{%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('b') }) it('should goto else for empty object', function () { - let src = '{%for c in emptyObj%}a{%else%}b{%endfor%}' + const src = '{%for c in emptyObj%}a{%else%}b{%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('b') }) it('should goto else for null-prototyped object', function () { - let src = '{%for c in nullProtoObj%}a{%else%}b{%endfor%}' + const src = '{%for c in nullProtoObj%}a{%else%}b{%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('b') }) }) it('should support for with forloop', function () { - let src = '{%for c in alpha%}' + + const src = '{%for c in alpha%}' + '{{forloop.first}}.{{forloop.index}}.{{forloop.index0}}.' + '{{forloop.last}}.{{forloop.length}}.' + '{{forloop.rindex}}.{{forloop.rindex0}}' + '{{c}}\n' + '{%endfor%}' - let dst = 'true.1.0.false.3.3.2a\n' + + const dst = 'true.1.0.false.3.3.2a\n' + 'false.2.1.false.3.2.1b\n' + 'false.3.2.true.3.1.0c\n' return expect(liquid.parseAndRender(src, ctx)) @@ -115,14 +115,14 @@ describe('tags/for', function () { }) it('should support for with continue', function () { - let src = '{% for i in (1..5) %}' + + const src = '{% for i in (1..5) %}' + '{{i}}{% continue %}after' + '{% endfor %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('12345') }) it('should support for with break', function () { - let src = '{% for i in (one..5) %}' + + const src = '{% for i in (one..5) %}' + '{% if i == 4 %}{% break %}{% endif %}' + '{{ i }}' + '{% endfor %}' @@ -132,22 +132,22 @@ describe('tags/for', function () { describe('limit', function () { it('should support for with limit', function () { - let src = '{% for i in (1..5) limit:2 %}{{ i }}{% endfor %}' + const src = '{% for i in (1..5) limit:2 %}{{ i }}{% endfor %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('12') }) it('should set forloop.last properly', function () { - let src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.last}} {%endfor%}' + const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.last}} {%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('false true ') }) it('should set forloop.first properly', function () { - let src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.first}} {%endfor%}' + const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.first}} {%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('true false ') }) it('should set forloop.length properly', function () { - let src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.length}} {%endfor%}' + const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.length}} {%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('2 2 ') }) @@ -155,27 +155,27 @@ describe('tags/for', function () { describe('offset', function () { it('should support offset with limit', function () { - let src = '{% for i in (1..10) limit:2 offset:5%}{{ i }}{% endfor %}' + const src = '{% for i in (1..10) limit:2 offset:5%}{{ i }}{% endfor %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('67') }) it('should set index properly', function () { - let src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index}} {%endfor%}' + const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index}} {%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('1 2 ') }) it('should set index0 properly', function () { - let src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index0}} {%endfor%}' + const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.index0}} {%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('0 1 ') }) it('should set rindex properly', function () { - let src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex}} {%endfor%}' + const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex}} {%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('2 1 ') }) it('should set rindex0 properly', function () { - let src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex0}} {%endfor%}' + const src = '{%for i in (1..10) limit:2 offset:3%}{{forloop.rindex0}} {%endfor%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('1 0 ') }) @@ -183,19 +183,19 @@ describe('tags/for', function () { describe('reverse', function () { it('should support for reversed in the last position', function () { - let src = '{% for i in (1..5) limit:2 reversed %}{{ i }}{% endfor %}' + const src = '{% for i in (1..5) limit:2 reversed %}{{ i }}{% endfor %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('21') }) it('should support for reversed in the first position', function () { - let src = '{% for i in (1..5) reversed limit:2 %}{{ i }}{% endfor %}' + const src = '{% for i in (1..5) reversed limit:2 %}{{ i }}{% endfor %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('21') }) it('should support for reversed in the middle position', function () { - let src = '{% for i in (1..5) offset:2 reversed limit:4 %}{{ i }}{% endfor %}' + const src = '{% for i in (1..5) offset:2 reversed limit:4 %}{{ i }}{% endfor %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('543') }) diff --git a/test/tags/if.js b/test/tags/if.js index 8fc417c48..1e99ee4a1 100644 --- a/test/tags/if.js +++ b/test/tags/if.js @@ -5,8 +5,8 @@ const expect = chai.expect chai.use(require('chai-as-promised')) describe('tags/if', function () { - let liquid = Liquid() - let ctx = { + const liquid = Liquid() + const ctx = { one: 1, two: 2, emptyString: '', @@ -14,101 +14,101 @@ describe('tags/if', function () { } it('should throw if not closed', function () { - let src = '{% if false%}yes' + const src = '{% if false%}yes' return expect(liquid.parseAndRender(src, ctx)) .to.be.rejectedWith(/tag {% if false%} not closed/) }) it('should support nested', function () { - let src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}' + const src = '{%if false%}{%if true%}{%else%}a{%endif%}{%endif%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('') }) describe('single value as condition', function () { it('should support boolean', function () { - let src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}' + const src = '{% if false %}1{%elsif true%}2{%else%}3{%endif%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('2') }) it('should treat Array truthy', function () { - let src = '{%if emptyArray%}a{%endif%}' + const src = '{%if emptyArray%}a{%endif%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('a') }) it('should return true if empty string', function () { - let src = '{%if emptyString%}a{%endif%}' + const src = '{%if emptyString%}a{%endif%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('a') }) }) describe('expression as condition', function () { it('should support ==', function () { - let src = '{% if 2==3 %}yes{%else%}no{%endif%}' + const src = '{% if 2==3 %}yes{%else%}no{%endif%}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('no') }) it('should support >=', function () { - let src = '{% if 1>=2 and one 10', function () { - let src = '{% if null > 10 %}yes{% else %}no{% endif %}' + const src = '{% if null > 10 %}yes{% else %}no{% endif %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('no') }) it('should evaluate false for null <= 10', function () { - let src = '{% if null <= 10 %}yes{% else %}no{% endif %}' + const src = '{% if null <= 10 %}yes{% else %}no{% endif %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('no') }) it('should evaluate false for null >= 10', function () { - let src = '{% if null >= 10 %}yes{% else %}no{% endif %}' + const src = '{% if null >= 10 %}yes{% else %}no{% endif %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('no') }) it('should evaluate false for 10 < null', function () { - let src = '{% if 10 < null %}yes{% else %}no{% endif %}' + const src = '{% if 10 < null %}yes{% else %}no{% endif %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('no') }) it('should evaluate false for 10 > null', function () { - let src = '{% if 10 > null %}yes{% else %}no{% endif %}' + const src = '{% if 10 > null %}yes{% else %}no{% endif %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('no') }) it('should evaluate false for 10 <= null', function () { - let src = '{% if 10 <= null %}yes{% else %}no{% endif %}' + const src = '{% if 10 <= null %}yes{% else %}no{% endif %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('no') }) it('should evaluate false for 10 >= null', function () { - let src = '{% if 10 >= null %}yes{% else %}no{% endif %}' + const src = '{% if 10 >= null %}yes{% else %}no{% endif %}' return expect(liquid.parseAndRender(src, ctx)) .to.eventually.equal('no') }) diff --git a/test/tags/include.js b/test/tags/include.js index 2b3599e57..ff4127a75 100644 --- a/test/tags/include.js +++ b/test/tags/include.js @@ -95,7 +95,7 @@ describe('tags/include', function () { '/card.html': '

{{person.firstName}} {{person.lastName}}
{% include "address" %}

', '/address.html': 'City: {{person.address.city}}' }) - let ctx = { + const ctx = { person: { firstName: 'Joe', lastName: 'Shmoe', @@ -114,7 +114,7 @@ describe('tags/include', function () { '/parent.html': 'X{% include child.html color:"red" %}Y', '/child.html': 'child with {{color}}' }) - let staticLiquid = new Liquid({dynamicPartials: false, root: '/'}) + const staticLiquid = new Liquid({dynamicPartials: false, root: '/'}) return expect(staticLiquid.renderFile('parent.html')).to .eventually.equal('Xchild with redY') }) @@ -124,7 +124,7 @@ describe('tags/include', function () { '/parent.html': 'X{% include bar/./../foo/child.html %}Y', '/foo/child.html': 'child' }) - let staticLiquid = new Liquid({dynamicPartials: false, root: '/'}) + const staticLiquid = new Liquid({dynamicPartials: false, root: '/'}) return expect(staticLiquid.renderFile('parent.html')).to .eventually.equal('XchildY') }) @@ -134,7 +134,7 @@ describe('tags/include', function () { '/parent.html': 'X{% include foo/child.html %}Y', '/foo/child.html': 'child' }) - let staticLiquid = new Liquid({dynamicPartials: false, root: '/'}) + const staticLiquid = new Liquid({dynamicPartials: false, root: '/'}) return expect(staticLiquid.renderFile('parent.html')).to .eventually.equal('XchildY') }) @@ -144,7 +144,7 @@ describe('tags/include', function () { '/parent.html': 'X{% include child.html, color:"red" %}Y', '/child.html': 'child with {{color}}' }) - let staticLiquid = new Liquid({dynamicPartials: false, root: '/'}) + const staticLiquid = new Liquid({dynamicPartials: false, root: '/'}) return expect(staticLiquid.renderFile('parent.html')).to .eventually.equal('Xchild with redY') }) diff --git a/test/tags/increment.js b/test/tags/increment.js index a29adb48b..dcbda6f32 100644 --- a/test/tags/increment.js +++ b/test/tags/increment.js @@ -5,17 +5,17 @@ const expect = chai.expect chai.use(require('chai-as-promised')) describe('tags/increment', function () { - let liquid = Liquid() + const liquid = Liquid() it('should increment undefined variable', function () { - let src = '{% increment one %}{% increment one %}{% increment one %}' + const src = '{% increment one %}{% increment one %}{% increment one %}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('012') }) it('should increment defined variable', function () { - let src = '{% increment one %}{% increment one %}{% increment one %}' - let ctx = {one: 7} + const src = '{% increment one %}{% increment one %}{% increment one %}' + const ctx = {one: 7} return liquid.parseAndRender(src, ctx) .then(x => { expect(x).to.equal('789') @@ -24,25 +24,25 @@ describe('tags/increment', function () { }) it('should be independent from assign', function () { - let src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %}' + const src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('012') }) it('should be independent from capture', function () { - let src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %}' + const src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('012') }) it('should not shading assign', function () { - let src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %} {{var}}' + const src = '{% assign var=10 %}{% increment var %}{% increment var %}{% increment var %} {{var}}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('012 10') }) it('should not shading capture', function () { - let src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %} {{var}}' + const src = '{% capture var %}10{% endcapture %}{% increment var %}{% increment var %}{% increment var %} {{var}}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('012 10') }) diff --git a/test/tags/layout.js b/test/tags/layout.js index 244a5807c..4b188461a 100644 --- a/test/tags/layout.js +++ b/test/tags/layout.js @@ -21,7 +21,7 @@ describe('tags/layout', function () { mock({ '/parent.html': 'parent' }) - let src = '{% layout "parent" %}{%block%}A' + const src = '{% layout "parent" %}{%block%}A' return expect(liquid.parseAndRender(src)).to .be.rejectedWith(/tag {%block%} not closed/) }) @@ -39,7 +39,7 @@ describe('tags/layout', function () { mock({ '/parent.html': 'X{%block%}{%endblock%}Y' }) - let src = '{% layout "parent.html" %}{%block%}A{%endblock%}' + const src = '{% layout "parent.html" %}{%block%}A{%endblock%}' return expect(liquid.parseAndRender(src)).to .eventually.equal('XAY') }) @@ -47,7 +47,7 @@ describe('tags/layout', function () { mock({ '/parent.html': 'X{%block%}{%endblock%}Y' }) - let src = '{% layout "parent.html" %}A' + const src = '{% layout "parent.html" %}A' return expect(liquid.parseAndRender(src)).to .eventually.equal('XAY') }) @@ -56,7 +56,7 @@ describe('tags/layout', function () { mock({ '/parent.html': 'X{% block "a"%}{% endblock %}Y{% block b%}{%endblock%}Z' }) - let src = '{% layout "parent.html" %}' + + const src = '{% layout "parent.html" %}' + '{%block a%}A{%endblock%}' + '{%block b%}B{%endblock%}' return expect(liquid.parseAndRender(src)).to @@ -66,7 +66,7 @@ describe('tags/layout', function () { mock({ '/parent.html': 'X{% block "a"%}A{% endblock %}Y{% block b%}B{%endblock%}Z' }) - let src = '{% layout "parent.html" %}{%block a%}a{%endblock%}' + const src = '{% layout "parent.html" %}{%block a%}a{%endblock%}' return expect(liquid.parseAndRender(src)).to .eventually.equal('XaYBZ') }) @@ -113,7 +113,7 @@ describe('tags/layout', function () { '/parent.html': '{{color}}{%block%}{%endblock%}', '/main.html': '{% layout parent.html color:"black"%}{%block%}A{%endblock%}' }) - let staticLiquid = Liquid({ root: '/', dynamicPartials: false }) + const staticLiquid = Liquid({ root: '/', dynamicPartials: false }) return expect(staticLiquid.renderFile('/main.html')).to .eventually.equal('blackA') }) @@ -123,7 +123,7 @@ describe('tags/layout', function () { '/foo/parent.html': '{{color}}{%block%}{%endblock%}', '/main.html': '{% layout bar/../foo/parent.html color:"black"%}{%block%}A{%endblock%}' }) - let staticLiquid = Liquid({ root: '/', dynamicPartials: false }) + const staticLiquid = Liquid({ root: '/', dynamicPartials: false }) return expect(staticLiquid.renderFile('/main.html')).to .eventually.equal('blackA') }) @@ -133,7 +133,7 @@ describe('tags/layout', function () { '/foo/parent.html': '{{color}}{%block%}{%endblock%}', '/main.html': '{% layout foo/parent.html color:"black"%}{%block%}A{%endblock%}' }) - let staticLiquid = Liquid({ root: '/', dynamicPartials: false }) + const staticLiquid = Liquid({ root: '/', dynamicPartials: false }) return expect(staticLiquid.renderFile('/main.html')).to .eventually.equal('blackA') }) diff --git a/test/tags/raw.js b/test/tags/raw.js index ab6c45b8c..cf507a99c 100644 --- a/test/tags/raw.js +++ b/test/tags/raw.js @@ -5,21 +5,19 @@ const expect = chai.expect chai.use(require('chai-as-promised')) describe('tags/raw', function () { - let liquid = Liquid() - it('should support raw 1', function () { - return expect(liquid.parseAndRender('{% raw%}')) - .to.be.rejectedWith(/{% raw%} not closed/) + const liquid = Liquid() + it('should support raw 1', async function () { + const p = liquid.parseAndRender('{% raw%}') + return expect(p).be.rejectedWith(/{% raw%} not closed/) }) - it('should support raw 2', function () { - let src = '{% raw %}{{ 5 | plus: 6 }}{% endraw %} is equal to 11.' - let dst = '{{ 5 | plus: 6 }} is equal to 11.' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal(dst) + it('should support raw 2', async function () { + const src = '{% raw %}{{ 5 | plus: 6 }}{% endraw %} is equal to 11.' + const dst = '{{ 5 | plus: 6 }} is equal to 11.' + return expect(liquid.parseAndRender(src)).to.eventually.equal(dst) }) it('should support raw 3', function () { - let src = '{% raw %}\n{{ foo}} \n{% endraw %}' - let dst = '\n{{ foo}} \n' - return expect(liquid.parseAndRender(src)) - .to.eventually.equal(dst) + const src = '{% raw %}\n{{ foo}} \n{% endraw %}' + const dst = '\n{{ foo}} \n' + return expect(liquid.parseAndRender(src)).to.eventually.equal(dst) }) }) diff --git a/test/tags/tablerow.js b/test/tags/tablerow.js index fa585541e..f2f3d46ea 100644 --- a/test/tags/tablerow.js +++ b/test/tags/tablerow.js @@ -5,52 +5,52 @@ const expect = chai.expect chai.use(require('chai-as-promised')) describe('tags/tablerow', function () { - let liquid = Liquid() + const liquid = Liquid() it('should support tablerow', function () { - let src = '{% tablerow i in (1..3)%}{{ i }}{% endtablerow %}' - let dst = '123' + const src = '{% tablerow i in (1..3)%}{{ i }}{% endtablerow %}' + const dst = '123' return expect(liquid.parseAndRender(src)).to.eventually.equal(dst) }) it('should support cols', function () { - let src = '{% tablerow i in alpha cols:2 %}{{ i }}{% endtablerow %}' - let ctx = { + const src = '{% tablerow i in alpha cols:2 %}{{ i }}{% endtablerow %}' + const ctx = { alpha: ['a', 'b', 'c'] } - let dst = + const dst = 'ab' + 'c' return expect(liquid.parseAndRender(src, ctx)).to.eventually.equal(dst) }) it('should support cols set to 0', function () { - let src = '{% tablerow i in (1..3) cols:0 %}{{ i }}{% endtablerow %}' - let dst = '123' + const src = '{% tablerow i in (1..3) cols:0 %}{{ i }}{% endtablerow %}' + const dst = '123' return expect(liquid.parseAndRender(src)).to.eventually.equal(dst) }) it('should support empty tablerow', function () { - let src = '{% tablerow i in (1..0) cols:2 %}{{ i }}{% endtablerow %}' - let dst = '' + const src = '{% tablerow i in (1..0) cols:2 %}{{ i }}{% endtablerow %}' + const dst = '' return expect(liquid.parseAndRender(src)).to.eventually.equal(dst) }) it('should support empty array', function () { - let src = '{% tablerow i in alpha.z cols:2 %}{{ i }}{% endtablerow %}' - let dst = '' + const src = '{% tablerow i in alpha.z cols:2 %}{{ i }}{% endtablerow %}' + const dst = '' return expect(liquid.parseAndRender(src)).to.eventually.equal(dst) }) it('should throw when tablerow not closed', function () { - let src = '{% tablerow i in (1..0) cols:2 %}{{ i }}' + const src = '{% tablerow i in (1..0) cols:2 %}{{ i }}' return expect(liquid.parseAndRender(src)) .to.be.rejectedWith(/tag .* not closed/) }) it('should support tablerow with range', function () { - let src = '{% tablerow i in (1..5) cols:2 %}{{ i }}{% endtablerow %}' - let dst = + const src = '{% tablerow i in (1..5) cols:2 %}{{ i }}{% endtablerow %}' + const dst = '12' + '34' + '5' @@ -58,16 +58,16 @@ describe('tags/tablerow', function () { }) it('should support tablerow with limit', function () { - let src = '{% tablerow i in (1..5) cols:2 limit:3 %}{{ i }}{% endtablerow %}' - let dst = + const src = '{% tablerow i in (1..5) cols:2 limit:3 %}{{ i }}{% endtablerow %}' + const dst = '12' + '3' return expect(liquid.parseAndRender(src)).to.eventually.equal(dst) }) it('should support tablerow with offset', function () { - let src = '{% tablerow i in (1..5) cols:2 offset:3 %}{{ i }}{% endtablerow %}' - let dst = '45' + const src = '{% tablerow i in (1..5) cols:2 offset:3 %}{{ i }}{% endtablerow %}' + const dst = '45' return expect(liquid.parseAndRender(src)).to.eventually.equal(dst) }) }) diff --git a/test/tags/unless.js b/test/tags/unless.js index 275247abf..e672af31a 100644 --- a/test/tags/unless.js +++ b/test/tags/unless.js @@ -5,31 +5,31 @@ const expect = chai.expect chai.use(require('chai-as-promised')) describe('tags/unless', function () { - let liquid = Liquid() + const liquid = Liquid() it('should render else when predicate yields true', function () { // 0 is truthy - let src = '{% unless 0 %}yes{%else%}no{%endunless%}' + const src = '{% unless 0 %}yes{%else%}no{%endunless%}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('no') }) it('should render unless when predicate yields false', function () { - let src = '{% unless false %}yes{%else%}no{%endunless%}' + const src = '{% unless false %}yes{%else%}no{%endunless%}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('yes') }) it('should reject when tag not closed', function () { - let src = '{% unless 1>2 %}yes' + const src = '{% unless 1>2 %}yes' return expect(liquid.parseAndRender(src)) .to.be.rejectedWith(/tag {% unless 1>2 %} not closed/) }) it('should render unless when predicate yields false and else undefined', function () { - let src = '{% unless 1>2 %}yes{%endunless%}' + const src = '{% unless 1>2 %}yes{%endunless%}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('yes') }) it('should render "" when predicate yields false and else undefined', function () { - let src = '{% unless 1<2 %}yes{%endunless%}' + const src = '{% unless 1<2 %}yes{%endunless%}' return expect(liquid.parseAndRender(src)) .to.eventually.equal('') }) diff --git a/test/tokenizer.js b/test/tokenizer.js index fa80e6a6e..7672155ba 100644 --- a/test/tokenizer.js +++ b/test/tokenizer.js @@ -5,8 +5,8 @@ const expect = chai.expect describe('tokenizer', function () { describe('parse', function () { it('should handle plain HTML', function () { - let html = '

Lorem Ipsum

' - let tokens = parse(html) + const html = '

Lorem Ipsum

' + const tokens = parse(html) expect(tokens.length).to.equal(1) expect(tokens[0].value).to.equal(html) @@ -18,24 +18,24 @@ describe('tokenizer', function () { }).to.throw('illegal input') }) it('should handle tag syntax', function () { - let html = '

{% for p in a[1]%}

' - let tokens = parse(html) + const html = '

{% for p in a[1]%}

' + const tokens = parse(html) expect(tokens.length).to.equal(3) expect(tokens[1].type).to.equal('tag') expect(tokens[1].value).to.equal('for p in a[1]') }) it('should handle value syntax', function () { - let html = '

{{foo | date: "%Y-%m-%d"}}

' - let tokens = parse(html) + const html = '

{{foo | date: "%Y-%m-%d"}}

' + const tokens = parse(html) expect(tokens.length).to.equal(3) expect(tokens[1].type).to.equal('value') expect(tokens[1].value).to.equal('foo | date: "%Y-%m-%d"') }) it('should handle consecutive value and tags', function () { - let html = '{{foo}}{{bar}}{%foo%}{%bar%}' - let tokens = parse(html) + const html = '{{foo}}{{bar}}{%foo%}{%bar%}' + const tokens = parse(html) expect(tokens.length).to.equal(4) expect(tokens[0].type).to.equal('value') @@ -45,8 +45,8 @@ describe('tokenizer', function () { expect(tokens[2].value).to.equal('foo') }) it('should keep white spaces and newlines', function () { - let html = '{%foo%}\n{%bar %} \n {%alice%}' - let tokens = parse(html) + const html = '{%foo%}\n{%bar %} \n {%alice%}' + const tokens = parse(html) expect(tokens.length).to.equal(5) expect(tokens[1].type).to.equal('html') expect(tokens[1].raw).to.equal('\n') @@ -54,16 +54,16 @@ describe('tokenizer', function () { expect(tokens[3].raw).to.equal(' \n ') }) it('should handle multiple lines tag', function () { - let html = '{%foo\na:a\nb:1.23\n%}' - let tokens = parse(html) + const html = '{%foo\na:a\nb:1.23\n%}' + const tokens = parse(html) expect(tokens.length).to.equal(1) expect(tokens[0].type).to.equal('tag') expect(tokens[0].args).to.equal('a:a\nb:1.23') expect(tokens[0].raw).to.equal('{%foo\na:a\nb:1.23\n%}') }) it('should handle multiple lines value', function () { - let html = '{{foo\n|date:\n"%Y-%m-%d"\n}}' - let tokens = parse(html) + const html = '{{foo\n|date:\n"%Y-%m-%d"\n}}' + const tokens = parse(html) expect(tokens.length).to.equal(1) expect(tokens[0].type).to.equal('value') expect(tokens[0].raw).to.equal('{{foo\n|date:\n"%Y-%m-%d"\n}}') diff --git a/test/util/assert.js b/test/util/assert.js index 083b2f819..6dc2605fd 100644 --- a/test/util/assert.js +++ b/test/util/assert.js @@ -1,18 +1,19 @@ -const chai = require('chai') +import chai from 'chai' +import assert from '../../src/util/assert.js' + const expect = chai.expect -const assert = require('../../src/util/assert.js') describe('assert', function () { it('should not throw if predicate is truthy', function () { - let fn = () => assert('foo', 'bar') + const fn = () => assert('foo', 'bar') expect(fn).to.not.throw() }) it('should not throw if predicate is truthy', function () { - let fn = () => assert('', 'bar') + const fn = () => assert('', 'bar') expect(fn).to.throw(/bar/) }) it('should populate default message', function () { - let fn = () => assert(false) + const fn = () => assert(false) expect(fn).to.throw(/expect false to be true/) }) }) diff --git a/test/util/error.js b/test/util/error.js index 9c1bc750c..99c02d9f0 100644 --- a/test/util/error.js +++ b/test/util/error.js @@ -7,7 +7,7 @@ const expect = chai.expect chai.use(require('chai-as-promised')) let engine = Liquid() -let strictEngine = Liquid({ +const strictEngine = Liquid({ strict_variables: true, strict_filters: true }) @@ -18,80 +18,59 @@ describe('error', function () { }) describe('TokenizationError', function () { - it('should throw TokenizationError when tag illegal', function () { - return expect(engine.parseAndRender('{% . a %}', {})).to.eventually - .be.rejected - .then(function (err) { - expect(err.name).to.equal('TokenizationError') - expect(err.message).to.contain('illegal tag syntax') - }) + it('should throw TokenizationError when tag illegal', async function () { + const err = await expect(engine.parseAndRender('{% . a %}', {})).be.rejected + expect(err.name).to.equal('TokenizationError') + expect(err.message).to.contain('illegal tag syntax') }) - it('should contain template content in err.message', function () { - let html = ['1st', '2nd', 'X{% . a %} Y', '4th'] - let message = [ + it('should contain template content in err.message', async function () { + const html = ['1st', '2nd', 'X{% . a %} Y', '4th'] + const message = [ ' 1| 1st', ' 2| 2nd', '>> 3| X{% . a %} Y', ' 4| 4th', 'TokenizationError' ] - return expect(engine.parseAndRender(html.join('\n'))).to.eventually - .be.rejected - .then(function (err) { - expect(err.message).to.equal('illegal tag syntax, line:3') - expect(err.stack).to.contain(message.join('\n')) - expect(err.name).to.equal('TokenizationError') - }) + const err = await expect(engine.parseAndRender(html.join('\n'))).be.rejected + expect(err.message).to.equal('illegal tag syntax, line:3') + expect(err.stack).to.contain(message.join('\n')) + expect(err.name).to.equal('TokenizationError') }) - it('should contain the whole template content in err.input', function () { - let html = 'bar\nfoo{% . a %}\nfoo' - return expect(engine.parseAndRender(html)).to.eventually - .be.rejected - .then(function (err) { - expect(err.input).to.equal(html) - }) + it('should contain the whole template content in err.input', async function () { + const html = 'bar\nfoo{% . a %}\nfoo' + const err = await expect(engine.parseAndRender(html)).be.rejected + expect(err.input).to.equal(html) }) - it('should contain line number in err.line', function () { - return expect(engine.parseAndRender('1\n2\n{% . a %}\n4', {})).to.eventually - .be.rejected - .then(function (err) { - expect(err.name).to.equal('TokenizationError') - expect(err.line).to.equal(3) - }) + it('should contain line number in err.line', async function () { + const err = await expect(engine.parseAndRender('1\n2\n{% . a %}\n4')).be.rejected + expect(err.name).to.equal('TokenizationError') + expect(err.line).to.equal(3) }) - it('should contain stack in err.stack', function () { - return expect(engine.parseAndRender('{% . a %}')).to.eventually - .be.rejected - .then(function (err) { - expect(err.message).to.contain('illegal tag syntax') - expect(err.stack).to.contain('at Object.parse') - }) + it('should contain stack in err.stack', async function () { + const err = await expect(engine.parseAndRender('{% . a %}')).be.rejected + expect(err.message).to.contain('illegal tag syntax') + expect(err.stack).to.contain('at Object.parse') }) describe('captureStackTrace compatibility', function () { - let captureStackTrace = Error.captureStackTrace + const captureStackTrace = Error.captureStackTrace before(() => (Error.captureStackTrace = null)) after(() => (Error.captureStackTrace = captureStackTrace)) - it('should use empty string if captureStackTrace not defined', function () { - return expect(engine.parseAndRender('{% . a %}')).to.eventually - .be.rejected - .then(function (err) { - expect(err.stack).to.contain('illegal tag syntax') - expect(err.stack).to.not.contain('at Object.parse') - }) + it('should be empty when captureStackTrace undefined', async function () { + const err = await expect(engine.parseAndRender('{% . a %}')).be.rejected + expect(err.stack).to.contain('illegal tag syntax') + expect(err.stack).to.not.contain('at Object.parse') }) }) - it('should contain file path in err.file', function () { - let html = '\n\n\n{% . a %}\n\n' + it('should contain file path in err.file', async function () { + const html = '\n\n\n{% . a %}\n\n' mock({ '/foo.html': html }) - return expect(engine.renderFile('/foo.html')).to.eventually - .be.rejected - .then(function (err) { - mock.restore() - expect(err.name).to.equal('TokenizationError') - expect(err.file).to.equal(path.resolve('/foo.html')) - }) + const err = await expect(engine.renderFile('/foo.html')).be.rejected + mock.restore() + expect(err.name).to.equal('TokenizationError') + expect(err.file).to.equal(path.resolve('/foo.html')) }) }) @@ -106,55 +85,43 @@ describe('error', function () { } }) engine.registerTag('rejectingTag', { - render: function () { - return Promise.reject(new Error('intended render reject')) + render: async function () { + throw new Error('intended render reject') } }) engine.registerFilter('throwingFilter', () => { throw new Error('throwed by filter') }) }) - it('should throw RenderError when tag throws', function () { - let src = '{%throwingTag%}' - return expect(engine.parseAndRender(src)).to.eventually - .be.rejected - .then(function (err) { - expect(err.name).to.equal('RenderError') - expect(err.message).to.contain('intended render error') - }) + it('should throw RenderError when tag throws', async function () { + const src = '{%throwingTag%}' + const err = await expect(engine.parseAndRender(src)).be.rejected + expect(err.name).to.equal('RenderError') + expect(err.message).to.contain('intended render error') }) - it('should throw RenderError when tag rejects', function () { - let src = '{%rejectingTag%}' - return expect(engine.parseAndRender(src)).to.eventually - .be.rejected - .then(function (err) { - expect(err.name).to.equal('RenderError') - expect(err.message).to.contain('intended render reject') - }) + it('should throw RenderError when tag rejects', async function () { + const src = '{%rejectingTag%}' + const err = await expect(engine.parseAndRender(src)).be.rejected + expect(err.name).to.equal('RenderError') + expect(err.message).to.contain('intended render reject') }) - it('should throw RenderError when filter throws', function () { - let src = '{{1|throwingFilter}}' - return expect(engine.parseAndRender(src)).to.eventually - .be.rejected - .then(function (err) { - expect(err.name).to.equal('RenderError') - expect(err.message).to.contain('throwed by filter') - }) + it('should throw RenderError when filter throws', async function () { + const src = '{{1|throwingFilter}}' + const err = await expect(engine.parseAndRender(src)).be.rejected + expect(err.name).to.equal('RenderError') + expect(err.message).to.contain('throwed by filter') }) it('should not throw when variable undefined by default', function () { return expect(engine.parseAndRender('X{{a}}Y')).to.eventually.equal('XY') }) - it('should throw RenderError when variable not defined', function () { - return expect(strictEngine.parseAndRender('{{a}}')).to.eventually - .be.rejected - .then(function (e) { - expect(e).to.have.property('name', 'RenderError') - expect(e.message).to.contain('undefined variable: a') - }) + it('should throw RenderError when variable not defined', async function () { + const err = await expect(strictEngine.parseAndRender('{{a}}')).be.rejected + expect(err).to.have.property('name', 'RenderError') + expect(err.message).to.contain('undefined variable: a') }) - it('should contain template context in err.stack', function () { - let html = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th'] - let message = [ + it('should contain template context in err.stack', async function () { + const html = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th'] + const message = [ ' 2| 2nd', ' 3| 3rd', '>> 4| X{%throwingTag%} Y', @@ -163,15 +130,12 @@ describe('error', function () { ' 7| 7th', 'RenderError' ] - return expect(engine.parseAndRender(html.join('\n'))).to.eventually - .be.rejected - .then(function (err) { - expect(err.message).to.equal('intended render error, line:4') - expect(err.stack).to.contain(message.join('\n')) - expect(err.name).to.equal('RenderError') - }) + const err = await expect(engine.parseAndRender(html.join('\n'))).be.rejected + expect(err.message).to.equal('intended render error, line:4') + expect(err.stack).to.contain(message.join('\n')) + expect(err.name).to.equal('RenderError') }) - it('should contain original error info for {% layout %}', function () { + it('should contain original error info for {% layout %}', async function () { mock({ '/throwing-tag.html': [ '1st', @@ -183,8 +147,8 @@ describe('error', function () { '7th' ].join('\n') }) - let html = '{%layout "throwing-tag.html"%}' - let message = [ + const html = '{%layout "throwing-tag.html"%}' + const message = [ ' 2| 2nd', ' 3| 3rd', '>> 4| X{%throwingTag%} Y', @@ -193,23 +157,20 @@ describe('error', function () { ' 7| 7th', 'RenderError' ] - return expect(engine.parseAndRender(html)).to.eventually - .be.rejected - .then(function (err) { - console.log(err.message) - console.log(err.stack) - expect(err.message).to.equal(`intended render error, file:${path.resolve('/throwing-tag.html')}, line:4`) - expect(err.stack).to.contain(message.join('\n')) - expect(err.name).to.equal('RenderError') - }) + const err = await expect(engine.parseAndRender(html)).be.rejected + console.log(err.message) + console.log(err.stack) + expect(err.message).to.equal(`intended render error, file:${path.resolve('/throwing-tag.html')}, line:4`) + expect(err.stack).to.contain(message.join('\n')) + expect(err.name).to.equal('RenderError') }) - it('should contain original error info for {% include %}', function () { - let origin = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th'] + it('should contain original error info for {% include %}', async function () { + const origin = ['1st', '2nd', '3rd', 'X{%throwingTag%} Y', '5th', '6th', '7th'] mock({ '/throwing-tag.html': origin.join('\n') }) - let html = '{%include "throwing-tag.html"%}' - let message = [ + const html = '{%include "throwing-tag.html"%}' + const message = [ ' 2| 2nd', ' 3| 3rd', '>> 4| X{%throwingTag%} Y', @@ -218,54 +179,39 @@ describe('error', function () { ' 7| 7th', 'RenderError' ] - return expect(engine.parseAndRender(html)).to.eventually - .be.rejected - .then(function (err) { - expect(err.message).to.equal(`intended render error, file:${path.resolve('/throwing-tag.html')}, line:4`) - expect(err.stack).to.contain(message.join('\n')) - expect(err.name).to.equal('RenderError') - }) + const err = await expect(engine.parseAndRender(html)).be.rejected + expect(err.message).to.equal(`intended render error, file:${path.resolve('/throwing-tag.html')}, line:4`) + expect(err.stack).to.contain(message.join('\n')) + expect(err.name).to.equal('RenderError') }) - it('should contain the whole template content in err.input', function () { - let html = 'bar\nfoo{%throwingTag%}\nfoo' - return expect(engine.parseAndRender(html)).to.eventually - .be.rejected - .then(function (err) { - expect(err.input).to.equal(html) - expect(err.name).to.equal('RenderError') - }) + it('should contain the whole template content in err.input', async function () { + const html = 'bar\nfoo{%throwingTag%}\nfoo' + const err = await expect(engine.parseAndRender(html)).be.rejected + expect(err.input).to.equal(html) + expect(err.name).to.equal('RenderError') }) - it('should contain line number in err.line', function () { - let src = '1\n2\n{{1|throwingFilter}}\n4' - return expect(engine.parseAndRender(src)).to.eventually - .be.rejected - .then(function (err) { - expect(err.line).to.equal(3) - expect(err.name).to.equal('RenderError') - }) + it('should contain line number in err.line', async function () { + const src = '1\n2\n{{1|throwingFilter}}\n4' + const err = await expect(engine.parseAndRender(src)).be.rejected + expect(err.line).to.equal(3) + expect(err.name).to.equal('RenderError') }) - it('should contain stack in err.stack', function () { - return expect(engine.parseAndRender('{%rejectingTag%}')).to.eventually - .be.rejected - .then(function (err) { - expect(err.message).to.contain('intended render reject') - expect(err.stack).to.match(/at .*:\d+:\d+/) - }) + it('should contain stack in err.stack', async function () { + const err = await expect(engine.parseAndRender('{%rejectingTag%}')).be.rejected + expect(err.message).to.contain('intended render reject') + expect(err.stack).to.match(/at .*:\d+:\d+/) }) - it('should contain file path in err.file', function () { - let html = '\n\n\n{% throwingTag %}\n\n' + it('should contain file path in err.file', async function () { + const html = '\n\n\n{% throwingTag %}\n\n' mock({ '/foo.html': html }) - return expect(engine.renderFile('/foo.html')).to.eventually - .be.rejected - .then(function (err) { - mock.restore() - console.log(err, err.name) - expect(err.name).to.equal('RenderError') - expect(err.file).to.equal(path.resolve('/foo.html')) - }) + const err = await expect(engine.renderFile('/foo.html')).be.rejected + mock.restore() + console.log(err, err.name) + expect(err.name).to.equal('RenderError') + expect(err.file).to.equal(path.resolve('/foo.html')) }) }) @@ -278,53 +224,36 @@ describe('error', function () { } }) }) - it('should throw RenderError when filter not defined', function () { - return expect(strictEngine.parseAndRender('{{1 | a}}')).to.eventually - .be.rejected - .then(function (e) { - expect(e).to.have.property('name', 'ParseError') - expect(e.message).to.contain('undefined filter: a') - }) + it('should throw RenderError when filter not defined', async function () { + const err = await expect(strictEngine.parseAndRender('{{1 | a}}')).be.rejected + expect(err).to.have.property('name', 'ParseError') + expect(err.message).to.contain('undefined filter: a') }) - it('should throw ParseError when tag not closed', function () { - return expect(engine.parseAndRender('{% if %}')).to.eventually - .be.rejected - .then(function (err) { - expect(err.name).to.equal('ParseError') - expect(err.message).to.contain('tag {% if %} not closed') - }) + it('should throw ParseError when tag not closed', async function () { + const err = await expect(engine.parseAndRender('{% if %}')).be.rejected + expect(err.name).to.equal('ParseError') + expect(err.message).to.contain('tag {% if %} not closed') }) - it('should throw ParseError when tag parse throws', function () { - let src = '{%throwsOnParse%}' - return expect(engine.parseAndRender(src)).to.eventually - .be.rejected - .then(function (err) { - expect(err.name).to.equal('ParseError') - expect(err.message).to.contain('intended parse error') - }) + it('should throw ParseError when tag parse throws', async function () { + const err = await expect(engine.parseAndRender('{%throwsOnParse%}')).be.rejected + expect(err.name).to.equal('ParseError') + expect(err.message).to.contain('intended parse error') }) - it('should throw ParseError when tag not found', function () { - let src = '{%if true%}\naaa{%endif%}\n{% -a %}\n3' - return expect(engine.parseAndRender(src)).to.eventually - .be.rejected - .then(function (err) { - expect(err.name).to.equal('ParseError') - expect(err.message).to.contain('tag -a not found') - }) + it('should throw ParseError when tag not found', async function () { + const src = '{%if true%}\naaa{%endif%}\n{% -a %}\n3' + const err = await expect(engine.parseAndRender(src)).be.rejected + expect(err.name).to.equal('ParseError') + expect(err.message).to.contain('tag -a not found') + }) + it('should throw ParseError when tag not exist', async function () { + const err = await expect(engine.parseAndRender('{% a %}')).be.rejected + expect(err.name).to.equal('ParseError') + expect(err.message).to.contain('tag a not found') }) - it('should throw ParseError when tag not exist', function () { - return expect(engine.parseAndRender('{% a %}')).to.eventually - .be.rejected - .then(function (err) { - expect(err.name).to.equal('ParseError') - expect(err.message).to.contain('tag a not found') - }) - }) - - it('should contain template context in err.stack', function () { - let html = ['1st', '2nd', '3rd', 'X{% a %} {% enda %} Y', '5th', '6th', '7th'] - let message = [ + it('should contain template context in err.stack', async function () { + const html = ['1st', '2nd', '3rd', 'X{% a %} {% enda %} Y', '5th', '6th', '7th'] + const message = [ ' 2| 2nd', ' 3| 3rd', '>> 4| X{% a %} {% enda %} Y', @@ -333,62 +262,47 @@ describe('error', function () { ' 7| 7th', 'ParseError: tag a not found' ] - return expect(engine.parseAndRender(html.join('\n'))).to.eventually - .be.rejected - .then(function (err) { - expect(err.message).to.equal('tag a not found, line:4') - expect(err.stack).to.contain(message.join('\n')) - expect(err.name).to.equal('ParseError') - }) + const err = await expect(engine.parseAndRender(html.join('\n'))).be.rejected + expect(err.message).to.equal('tag a not found, line:4') + expect(err.stack).to.contain(message.join('\n')) + expect(err.name).to.equal('ParseError') }) - it('should handle err.message when context not enough', function () { - let html = ['1st', 'X{% a %} {% enda %} Y', '3rd', '4th'] - let message = [ + it('should handle err.message when context not enough', async function () { + const html = ['1st', 'X{% a %} {% enda %} Y', '3rd', '4th'] + const message = [ ' 1| 1st', '>> 2| X{% a %} {% enda %} Y', ' 3| 3rd', ' 4| 4th', 'ParseError: tag a not found' ] - return expect(engine.parseAndRender(html.join('\n'))).to.eventually - .be.rejected - .then(function (err) { - expect(err.message).to.equal('tag a not found, line:2') - expect(err.stack).to.contain(message.join('\n')) - }) + const err = await expect(engine.parseAndRender(html.join('\n'))).be.rejected + expect(err.message).to.equal('tag a not found, line:2') + expect(err.stack).to.contain(message.join('\n')) }) - it('should contain line number in err.line', function () { - let html = '\n\n\n{% raw %}\n\n' - return expect(engine.parseAndRender(html)).to.eventually - .be.rejected - .then(function (err) { - expect(err.line).to.equal(4) - }) + it('should contain line number in err.line', async function () { + const html = '\n\n\n{% raw %}\n\n' + const err = await expect(engine.parseAndRender(html)).be.rejected + expect(err.line).to.equal(4) }) - it('should contain stack in err.stack', function () { - return expect(engine.parseAndRender('{% -a %}')).to.eventually - .be.rejected - .then(function (err) { - expect(err.stack).to.contain('ParseError: tag -a not found') - expect(err.stack).to.match(/at .*:\d+:\d+\)/) - }) + it('should contain stack in err.stack', async function () { + const err = await expect(engine.parseAndRender('{% -a %}')).be.rejected + expect(err.stack).to.contain('ParseError: tag -a not found') + expect(err.stack).to.match(/at .*:\d+:\d+\)/) }) - it('should contain file path in err.file', function () { - let html = '\n\n\n{% raw %}\n\n' + it('should contain file path in err.file', async function () { + const html = '\n\n\n{% raw %}\n\n' mock({ '/foo.html': html }) - return expect(engine.renderFile('/foo.html')).to.eventually - .be.rejected - .then(function (err) { - mock.restore() - expect(err.name).to.equal('ParseError') - expect(err.file).to.equal(path.resolve('/foo.html')) - }) + const err = await expect(engine.renderFile('/foo.html')).be.rejected + mock.restore() + expect(err.name).to.equal('ParseError') + expect(err.file).to.equal(path.resolve('/foo.html')) }) }) }) diff --git a/test/util/promise.js b/test/util/promise.js index bc9814ccf..b23ff9c9e 100644 --- a/test/util/promise.js +++ b/test/util/promise.js @@ -4,13 +4,13 @@ const expect = chai.expect chai.use(require('chai-as-promised')) chai.use(require('sinon-chai')) -let P = require('../../src/util/promise.js') +const P = require('../../src/util/promise.js') describe('util/promise', function () { describe('.anySeries()', function () { it('should resolve in series', function () { - let spy1 = sinon.spy() - let spy2 = sinon.spy() + const spy1 = sinon.spy() + const spy2 = sinon.spy() return P .anySeries( ['first', 'second'], @@ -28,17 +28,17 @@ describe('util/promise', function () { .then(() => expect(spy2).to.have.been.calledAfter(spy1)) }) it('should reject when all rejected', function () { - let p = P.anySeries(['first', 'second', 'third'], + const p = P.anySeries(['first', 'second', 'third'], item => Promise.reject(new Error(item))) return expect(p).to.be.rejectedWith('third') }) it('should resolve the value that first callback resolved', () => { - let p = P.anySeries(['first', 'second'], + const p = P.anySeries(['first', 'second'], item => Promise.resolve(item)) return expect(p).to.eventually.equal('first') }) it('should not call rest of callbacks once resolved', () => { - let spy = sinon.spy() + const spy = sinon.spy() return P .anySeries(['first', 'second'], (item, idx) => { if (idx > 0) { @@ -51,18 +51,18 @@ describe('util/promise', function () { }) describe('.mapSeries()', function () { it('should resolve when all resolved', function () { - let p = P.mapSeries(['first', 'second', 'third'], + const p = P.mapSeries(['first', 'second', 'third'], item => Promise.resolve(item)) return expect(p).to.eventually.deep.equal(['first', 'second', 'third']) }) it('should reject with the error that first callback rejected', () => { - let p = P.mapSeries(['first', 'second'], + const p = P.mapSeries(['first', 'second'], item => Promise.reject(item)) return expect(p).to.rejectedWith('first') }) it('should resolve in series', function () { - let spy1 = sinon.spy() - let spy2 = sinon.spy() + const spy1 = sinon.spy() + const spy2 = sinon.spy() return P .mapSeries( ['first', 'second'], @@ -80,7 +80,7 @@ describe('util/promise', function () { .then(() => expect(spy2).to.have.been.calledAfter(spy1)) }) it('should not call rest of callbacks once rejected', () => { - let spy = sinon.spy() + const spy = sinon.spy() return P .mapSeries(['first', 'second'], (item, idx) => { if (idx > 0) { diff --git a/test/util/strftime.js b/test/util/strftime.js index df9c287c6..1adad048a 100644 --- a/test/util/strftime.js +++ b/test/util/strftime.js @@ -1,7 +1,7 @@ -const chai = require('chai') -const expect = chai.expect +import chai from 'chai' +import t from '../../src/util/strftime.js' -let t = require('../../src/util/strftime.js') +const expect = chai.expect describe('util/strftime', function () { let now @@ -37,7 +37,7 @@ describe('util/strftime', function () { expect(t(now, '%I')).to.equal('01') }) it('should format %I as 12 for 00:00', function () { - let date = new Date('2016-01-01T00:00:00.000Z') + const date = new Date('2016-01-01T00:00:00.000Z') expect(t(date, '%I')).to.equal('12') }) describe('%j', function () { @@ -45,11 +45,11 @@ describe('util/strftime', function () { expect(t(then, '%j')).to.equal('066') }) it('should take count of leap years', function () { - let date = new Date('2001-03-01') + const date = new Date('2001-03-01') expect(t(date, '%j')).to.equal('060') }) it('should take count of leap years', function () { - let date = new Date('2000-03-01') + const date = new Date('2000-03-01') expect(t(date, '%j')).to.equal('061') }) }) @@ -60,7 +60,7 @@ describe('util/strftime', function () { expect(t(now, '%l')).to.equal(' 1') }) it('should format %l as 12 for 00:00', function () { - let date = new Date('2016-01-01T00:00:00.000Z') + const date = new Date('2016-01-01T00:00:00.000Z') expect(t(date, '%l')).to.equal('12') }) it('should format %L as 0 padded millisecond', function () { @@ -75,9 +75,9 @@ describe('util/strftime', function () { expect(t(then, '%P')).to.equal('am') }) it('should format %q as date suffix', function () { - let st = new Date('2016-03-01T03:05:03.000Z') - let nd = new Date('2016-03-02T03:05:03.000Z') - let rd = new Date('2016-03-03T03:05:03.000Z') + const st = new Date('2016-03-01T03:05:03.000Z') + const nd = new Date('2016-03-02T03:05:03.000Z') + const rd = new Date('2016-03-03T03:05:03.000Z') expect(t(st, '%q')).to.equal('st') expect(t(nd, '%q')).to.equal('nd') expect(t(rd, '%q')).to.equal('rd') @@ -113,7 +113,7 @@ describe('util/strftime', function () { expect(t(now, '%z')).to.equal('+0800') }) it('should format %z as negative time zone', function () { - let date = new Date('2016-01-04T13:15:23.000Z') + const date = new Date('2016-01-04T13:15:23.000Z') date.getTimezoneOffset = () => 480 expect(t(date, '%z')).to.equal('-0800') }) @@ -126,7 +126,7 @@ describe('util/strftime', function () { }) function mockUTC () { - let p = Date.prototype + const p = Date.prototype p._getHours = p.getHours p.getHours = p.getUTCHours @@ -139,7 +139,7 @@ function mockUTC () { } function restoreUTC () { - let p = Date.prototype + const p = Date.prototype p.getHours = p._getHours p.getDays = p._getDays p.getTimezoneOffset = p._getTimezoneOffset diff --git a/test/util/underscore.js b/test/util/underscore.js index 2dfb5c8cf..cb08cf215 100644 --- a/test/util/underscore.js +++ b/test/util/underscore.js @@ -1,10 +1,11 @@ import chai from 'chai' +import sinonChai from 'sinon-chai' import sinon from 'sinon' import {RenderError, RenderBreakError} from '../../src/util/error.js' -import _ from '../../src/util/underscore.js' +import * as _ from '../../src/util/underscore.js' const expect = chai.expect -chai.use(require('sinon-chai')) +chai.use(sinonChai) describe('util/underscore', function () { describe('.isError()', function () { @@ -12,7 +13,7 @@ describe('util/underscore', function () { expect(_.isError(new Error())).to.be.true }) it('should return true for RenderError', function () { - let tpl = { + const tpl = { token: { input: 'xx' } @@ -53,21 +54,21 @@ describe('util/underscore', function () { }) describe('.forOwn()', function () { it('should iterate all properties', function () { - let spy = sinon.spy() - let obj = { + const spy = sinon.spy() + const obj = { foo: 'bar' } _.forOwn(obj, spy) expect(spy).to.have.been.calledWith('bar', 'foo', obj) }) it('should default to empty object', function () { - let spy = sinon.spy() + const spy = sinon.spy() _.forOwn(undefined, spy) expect(spy).to.have.not.been.called }) it('should not iterate over properties on prototype', function () { - let spy = sinon.spy() - let obj = Object.create({ + const spy = sinon.spy() + const obj = Object.create({ bar: 'foo' }) obj.foo = 'bar' @@ -76,7 +77,7 @@ describe('util/underscore', function () { expect(spy).to.have.been.calledWith('bar', 'foo', obj) }) it('should break when returned false', function () { - let spy = sinon.stub().returns(false) + const spy = sinon.stub().returns(false) _.forOwn({ 'foo': 'foo', 'bar': 'foo' @@ -101,11 +102,11 @@ describe('util/underscore', function () { }) }) it('should assign 2 objects', function () { - let src = { + const src = { foo: 'foo', bar: 'bar' } - let dst = { + const dst = { foo: 'bar', kaa: 'kaa' } diff --git a/test/util/url.js b/test/util/url.js index 4622bfac7..75edfac94 100644 --- a/test/util/url.js +++ b/test/util/url.js @@ -1,4 +1,4 @@ -import {resolve} from '../../src/util/url.js' +import {extname, resolve} from '../../src/util/url.js' import chai from 'chai' const expect = chai.expect @@ -22,23 +22,23 @@ describe('util/url', function () { }) describe('resolve', function () { describe('root', function () { - it('should support width relative path', function () { + it('should support relative root', function () { expect(resolve('./views', 'foo')) .to.equal('https://example.com/foo/bar/views/foo') expect(resolve('./views/', 'foo')) .to.equal('https://example.com/foo/bar/views/foo') }) - it('should support width absolute path', function () { + it('should support absolute root', function () { expect(resolve('/views', 'foo')) .to.equal('https://example.com/views/foo') expect(resolve('/views/', 'foo')) .to.equal('https://example.com/views/foo') }) - it('should support with empty', function () { + it('should support empty root', function () { expect(resolve('', 'page.html')) .to.equal('https://example.com/foo/bar/page.html') }) - it('should support with url', function () { + it('should support full url as root', function () { expect(resolve('https://example.com/views', 'page.html')) .to.equal('https://example.com/views/page.html') expect(resolve('https://example.com/views/', 'page.html')) @@ -51,14 +51,12 @@ describe('util/url', function () { .to.equal('https://example.com/views/page.html') }) }) - describe('path', function () { - it('should support width relative path', function () { - expect(resolve('./views/', 'page.html')) - .to.equal('https://example.com/foo/bar/views/page.html') + describe('extname', function () { + it('should support relative path', function () { + expect(extname('./views/page.html')).to.equal('.html') }) - it('should support with absolute path', function () { - expect(resolve('/views/', '/page.html')) - .to.equal('https://example.com/page.html') + it('should support absolute path', function () { + expect(extname('/views/page.xml')).to.equal('.xml') }) }) })