UNPKG

169 kBJavaScriptView Raw
1/*
2 * liquidjs@9.40.0, https://github.com/harttle/liquidjs
3 * (c) 2016-2022 harttle
4 * Released under the MIT License.
5 */
6'use strict';
7
8Object.defineProperty(exports, '__esModule', { value: true });
9
10var path = require('path');
11var fs$1 = require('fs');
12var stream = require('stream');
13
14/*! *****************************************************************************
15Copyright (c) Microsoft Corporation.
16
17Permission to use, copy, modify, and/or distribute this software for any
18purpose with or without fee is hereby granted.
19
20THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
21REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
23INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
24LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
25OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
26PERFORMANCE OF THIS SOFTWARE.
27***************************************************************************** */
28/* global Reflect, Promise */
29
30var extendStatics = function(d, b) {
31 extendStatics = Object.setPrototypeOf ||
32 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
33 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
34 return extendStatics(d, b);
35};
36
37function __extends(d, b) {
38 if (typeof b !== "function" && b !== null)
39 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
40 extendStatics(d, b);
41 function __() { this.constructor = d; }
42 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
43}
44
45var __assign = function() {
46 __assign = Object.assign || function __assign(t) {
47 for (var s, i = 1, n = arguments.length; i < n; i++) {
48 s = arguments[i];
49 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
50 }
51 return t;
52 };
53 return __assign.apply(this, arguments);
54};
55
56function __awaiter(thisArg, _arguments, P, generator) {
57 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
58 return new (P || (P = Promise))(function (resolve, reject) {
59 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
60 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
61 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
62 step((generator = generator.apply(thisArg, _arguments || [])).next());
63 });
64}
65
66function __generator(thisArg, body) {
67 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
68 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
69 function verb(n) { return function (v) { return step([n, v]); }; }
70 function step(op) {
71 if (f) throw new TypeError("Generator is already executing.");
72 while (_) try {
73 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
74 if (y = 0, t) op = [op[0] & 2, t.value];
75 switch (op[0]) {
76 case 0: case 1: t = op; break;
77 case 4: _.label++; return { value: op[1], done: false };
78 case 5: _.label++; y = op[1]; op = [0]; continue;
79 case 7: op = _.ops.pop(); _.trys.pop(); continue;
80 default:
81 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
82 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
83 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
84 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
85 if (t[2]) _.ops.pop();
86 _.trys.pop(); continue;
87 }
88 op = body.call(thisArg, _);
89 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
90 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
91 }
92}
93
94function __values(o) {
95 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
96 if (m) return m.call(o);
97 if (o && typeof o.length === "number") return {
98 next: function () {
99 if (o && i >= o.length) o = void 0;
100 return { value: o && o[i++], done: !o };
101 }
102 };
103 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
104}
105
106function __read(o, n) {
107 var m = typeof Symbol === "function" && o[Symbol.iterator];
108 if (!m) return o;
109 var i = m.call(o), r, ar = [], e;
110 try {
111 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
112 }
113 catch (error) { e = { error: error }; }
114 finally {
115 try {
116 if (r && !r.done && (m = i["return"])) m.call(i);
117 }
118 finally { if (e) throw e.error; }
119 }
120 return ar;
121}
122
123function __spreadArray(to, from, pack) {
124 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
125 if (ar || !(i in from)) {
126 if (!ar) ar = Array.prototype.slice.call(from, 0, i);
127 ar[i] = from[i];
128 }
129 }
130 return to.concat(ar || Array.prototype.slice.call(from));
131}
132
133var Drop = /** @class */ (function () {
134 function Drop() {
135 }
136 Drop.prototype.liquidMethodMissing = function (key) {
137 return undefined;
138 };
139 return Drop;
140}());
141
142var toString$1 = Object.prototype.toString;
143var toLowerCase = String.prototype.toLowerCase;
144var hasOwnProperty = Object.hasOwnProperty;
145function isString(value) {
146 return typeof value === 'string';
147}
148// eslint-disable-next-line @typescript-eslint/ban-types
149function isFunction(value) {
150 return typeof value === 'function';
151}
152function isPromise(val) {
153 return val && isFunction(val.then);
154}
155function isIterator(val) {
156 return val && isFunction(val.next) && isFunction(val.throw) && isFunction(val.return);
157}
158function escapeRegex(str) {
159 return str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
160}
161function promisify(fn) {
162 return function () {
163 var args = [];
164 for (var _i = 0; _i < arguments.length; _i++) {
165 args[_i] = arguments[_i];
166 }
167 return new Promise(function (resolve, reject) {
168 fn.apply(void 0, __spreadArray(__spreadArray([], __read(args), false), [function (err, result) {
169 err ? reject(err) : resolve(result);
170 }], false));
171 });
172 };
173}
174function stringify(value) {
175 value = toValue(value);
176 if (isString(value))
177 return value;
178 if (isNil(value))
179 return '';
180 if (isArray(value))
181 return value.map(function (x) { return stringify(x); }).join('');
182 return String(value);
183}
184function toValue(value) {
185 return (value instanceof Drop && isFunction(value.valueOf)) ? value.valueOf() : value;
186}
187function isNumber(value) {
188 return typeof value === 'number';
189}
190function toLiquid(value) {
191 if (value && isFunction(value.toLiquid))
192 return toLiquid(value.toLiquid());
193 return value;
194}
195function isNil(value) {
196 return value == null;
197}
198function isArray(value) {
199 // be compatible with IE 8
200 return toString$1.call(value) === '[object Array]';
201}
202function isIterable(value) {
203 return isObject(value) && Symbol.iterator in value;
204}
205/*
206 * Iterates over own enumerable string keyed properties of an object and invokes iteratee for each property.
207 * The iteratee is invoked with three arguments: (value, key, object).
208 * Iteratee functions may exit iteration early by explicitly returning false.
209 * @param {Object} object The object to iterate over.
210 * @param {Function} iteratee The function invoked per iteration.
211 * @return {Object} Returns object.
212 */
213function forOwn(obj, iteratee) {
214 obj = obj || {};
215 for (var k in obj) {
216 if (hasOwnProperty.call(obj, k)) {
217 if (iteratee(obj[k], k, obj) === false)
218 break;
219 }
220 }
221 return obj;
222}
223function last$1(arr) {
224 return arr[arr.length - 1];
225}
226/*
227 * Checks if value is the language type of Object.
228 * (e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))
229 * @param {any} value The value to check.
230 * @return {Boolean} Returns true if value is an object, else false.
231 */
232function isObject(value) {
233 var type = typeof value;
234 return value !== null && (type === 'object' || type === 'function');
235}
236function range(start, stop, step) {
237 if (step === void 0) { step = 1; }
238 var arr = [];
239 for (var i = start; i < stop; i += step) {
240 arr.push(i);
241 }
242 return arr;
243}
244function padStart(str, length, ch) {
245 if (ch === void 0) { ch = ' '; }
246 return pad(str, length, ch, function (str, ch) { return ch + str; });
247}
248function padEnd(str, length, ch) {
249 if (ch === void 0) { ch = ' '; }
250 return pad(str, length, ch, function (str, ch) { return str + ch; });
251}
252function pad(str, length, ch, add) {
253 str = String(str);
254 var n = length - str.length;
255 while (n-- > 0)
256 str = add(str, ch);
257 return str;
258}
259function identify(val) {
260 return val;
261}
262function snakeCase(str) {
263 return str.replace(/(\w?)([A-Z])/g, function (_, a, b) { return (a ? a + '_' : '') + b.toLowerCase(); });
264}
265function changeCase(str) {
266 var hasLowerCase = __spreadArray([], __read(str), false).some(function (ch) { return ch >= 'a' && ch <= 'z'; });
267 return hasLowerCase ? str.toUpperCase() : str.toLowerCase();
268}
269function ellipsis(str, N) {
270 return str.length > N ? str.substr(0, N - 3) + '...' : str;
271}
272// compare string in case-insensitive way, undefined values to the tail
273function caseInsensitiveCompare(a, b) {
274 if (a == null && b == null)
275 return 0;
276 if (a == null)
277 return 1;
278 if (b == null)
279 return -1;
280 a = toLowerCase.call(a);
281 b = toLowerCase.call(b);
282 if (a < b)
283 return -1;
284 if (a > b)
285 return 1;
286 return 0;
287}
288function argumentsToValue(fn) {
289 return function () {
290 var args = [];
291 for (var _i = 0; _i < arguments.length; _i++) {
292 args[_i] = arguments[_i];
293 }
294 return fn.apply(void 0, __spreadArray([], __read(args.map(toValue)), false));
295 };
296}
297function escapeRegExp(text) {
298 return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
299}
300
301var Node = /** @class */ (function () {
302 function Node(key, value, next, prev) {
303 this.key = key;
304 this.value = value;
305 this.next = next;
306 this.prev = prev;
307 }
308 return Node;
309}());
310var LRU = /** @class */ (function () {
311 function LRU(limit, size) {
312 if (size === void 0) { size = 0; }
313 this.limit = limit;
314 this.size = size;
315 this.cache = {};
316 this.head = new Node('HEAD', null, null, null);
317 this.tail = new Node('TAIL', null, null, null);
318 this.head.next = this.tail;
319 this.tail.prev = this.head;
320 }
321 LRU.prototype.write = function (key, value) {
322 if (this.cache[key]) {
323 this.cache[key].value = value;
324 }
325 else {
326 var node = new Node(key, value, this.head.next, this.head);
327 this.head.next.prev = node;
328 this.head.next = node;
329 this.cache[key] = node;
330 this.size++;
331 this.ensureLimit();
332 }
333 };
334 LRU.prototype.read = function (key) {
335 if (!this.cache[key])
336 return;
337 var value = this.cache[key].value;
338 this.remove(key);
339 this.write(key, value);
340 return value;
341 };
342 LRU.prototype.remove = function (key) {
343 var node = this.cache[key];
344 node.prev.next = node.next;
345 node.next.prev = node.prev;
346 delete this.cache[key];
347 this.size--;
348 };
349 LRU.prototype.clear = function () {
350 this.head.next = this.tail;
351 this.tail.prev = this.head;
352 this.size = 0;
353 this.cache = {};
354 };
355 LRU.prototype.ensureLimit = function () {
356 if (this.size > this.limit)
357 this.remove(this.tail.prev.key);
358 };
359 return LRU;
360}());
361
362var requireResolve = require.resolve;
363
364var statAsync = promisify(fs$1.stat);
365var readFileAsync = promisify(fs$1.readFile);
366function exists(filepath) {
367 return __awaiter(this, void 0, void 0, function () {
368 return __generator(this, function (_a) {
369 switch (_a.label) {
370 case 0:
371 _a.trys.push([0, 2, , 3]);
372 return [4 /*yield*/, statAsync(filepath)];
373 case 1:
374 _a.sent();
375 return [2 /*return*/, true];
376 case 2:
377 _a.sent();
378 return [2 /*return*/, false];
379 case 3: return [2 /*return*/];
380 }
381 });
382 });
383}
384function readFile(filepath) {
385 return readFileAsync(filepath, 'utf8');
386}
387function existsSync(filepath) {
388 try {
389 fs$1.statSync(filepath);
390 return true;
391 }
392 catch (err) {
393 return false;
394 }
395}
396function readFileSync(filepath) {
397 return fs$1.readFileSync(filepath, 'utf8');
398}
399function resolve(root, file, ext) {
400 if (!path.extname(file))
401 file += ext;
402 return path.resolve(root, file);
403}
404function fallback(file) {
405 try {
406 return requireResolve(file);
407 }
408 catch (e) { }
409}
410function dirname(filepath) {
411 return path.dirname(filepath);
412}
413function contains(root, file) {
414 root = path.resolve(root);
415 root = root.endsWith(path.sep) ? root : root + path.sep;
416 return file.startsWith(root);
417}
418
419var fs = /*#__PURE__*/Object.freeze({
420 __proto__: null,
421 exists: exists,
422 readFile: readFile,
423 existsSync: existsSync,
424 readFileSync: readFileSync,
425 resolve: resolve,
426 fallback: fallback,
427 dirname: dirname,
428 contains: contains,
429 sep: path.sep
430});
431
432function isComparable(arg) {
433 return arg && isFunction(arg.equals);
434}
435
436function isTruthy(val, ctx) {
437 return !isFalsy(val, ctx);
438}
439function isFalsy(val, ctx) {
440 if (ctx.opts.jsTruthy) {
441 return !val;
442 }
443 else {
444 return val === false || undefined === val || val === null;
445 }
446}
447
448var defaultOperators = {
449 '==': function (l, r) {
450 if (isComparable(l))
451 return l.equals(r);
452 if (isComparable(r))
453 return r.equals(l);
454 return toValue(l) === toValue(r);
455 },
456 '!=': function (l, r) {
457 if (isComparable(l))
458 return !l.equals(r);
459 if (isComparable(r))
460 return !r.equals(l);
461 return toValue(l) !== toValue(r);
462 },
463 '>': function (l, r) {
464 if (isComparable(l))
465 return l.gt(r);
466 if (isComparable(r))
467 return r.lt(l);
468 return toValue(l) > toValue(r);
469 },
470 '<': function (l, r) {
471 if (isComparable(l))
472 return l.lt(r);
473 if (isComparable(r))
474 return r.gt(l);
475 return toValue(l) < toValue(r);
476 },
477 '>=': function (l, r) {
478 if (isComparable(l))
479 return l.geq(r);
480 if (isComparable(r))
481 return r.leq(l);
482 return toValue(l) >= toValue(r);
483 },
484 '<=': function (l, r) {
485 if (isComparable(l))
486 return l.leq(r);
487 if (isComparable(r))
488 return r.geq(l);
489 return toValue(l) <= toValue(r);
490 },
491 'contains': function (l, r) {
492 l = toValue(l);
493 r = toValue(r);
494 return l && isFunction(l.indexOf) ? l.indexOf(r) > -1 : false;
495 },
496 'and': function (l, r, ctx) { return isTruthy(toValue(l), ctx) && isTruthy(toValue(r), ctx); },
497 'or': function (l, r, ctx) { return isTruthy(toValue(l), ctx) || isTruthy(toValue(r), ctx); }
498};
499
500// **DO NOT CHANGE THIS FILE**
501//
502// This file is generated by bin/character-gen.js
503// bitmask character types to boost performance
504var TYPES = [0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 4, 4, 4, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 2, 8, 0, 0, 0, 0, 8, 0, 0, 0, 64, 0, 65, 0, 0, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 0, 0, 2, 2, 2, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0];
505var IDENTIFIER = 1;
506var BLANK = 4;
507var QUOTE = 8;
508var INLINE_BLANK = 16;
509var NUMBER = 32;
510var SIGN = 64;
511TYPES[160] = TYPES[5760] = TYPES[6158] = TYPES[8192] = TYPES[8193] = TYPES[8194] = TYPES[8195] = TYPES[8196] = TYPES[8197] = TYPES[8198] = TYPES[8199] = TYPES[8200] = TYPES[8201] = TYPES[8202] = TYPES[8232] = TYPES[8233] = TYPES[8239] = TYPES[8287] = TYPES[12288] = BLANK;
512
513function createTrie(operators) {
514 var e_1, _a;
515 var trie = {};
516 try {
517 for (var _b = __values(Object.entries(operators)), _c = _b.next(); !_c.done; _c = _b.next()) {
518 var _d = __read(_c.value, 2), name_1 = _d[0], handler = _d[1];
519 var node = trie;
520 for (var i = 0; i < name_1.length; i++) {
521 var c = name_1[i];
522 node[c] = node[c] || {};
523 if (i === name_1.length - 1 && (TYPES[name_1.charCodeAt(i)] & IDENTIFIER)) {
524 node[c].needBoundary = true;
525 }
526 node = node[c];
527 }
528 node.handler = handler;
529 node.end = true;
530 }
531 }
532 catch (e_1_1) { e_1 = { error: e_1_1 }; }
533 finally {
534 try {
535 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
536 }
537 finally { if (e_1) throw e_1.error; }
538 }
539 return trie;
540}
541
542var escapeMap = {
543 '&': '&amp;',
544 '<': '&lt;',
545 '>': '&gt;',
546 '"': '&#34;',
547 "'": '&#39;'
548};
549var unescapeMap = {
550 '&amp;': '&',
551 '&lt;': '<',
552 '&gt;': '>',
553 '&#34;': '"',
554 '&#39;': "'"
555};
556function escape(str) {
557 return stringify(str).replace(/&|<|>|"|'/g, function (m) { return escapeMap[m]; });
558}
559function unescape(str) {
560 return stringify(str).replace(/&(amp|lt|gt|#34|#39);/g, function (m) { return unescapeMap[m]; });
561}
562function escapeOnce(str) {
563 return escape(unescape(stringify(str)));
564}
565function newlineToBr(v) {
566 return stringify(v).replace(/\n/g, '<br />\n');
567}
568function stripHtml(v) {
569 return stringify(v).replace(/<script.*?<\/script>|<!--.*?-->|<style.*?<\/style>|<.*?>/g, '');
570}
571
572var abs = argumentsToValue(Math.abs);
573var atLeast = argumentsToValue(Math.max);
574var atMost = argumentsToValue(Math.min);
575var ceil = argumentsToValue(Math.ceil);
576var dividedBy = argumentsToValue(function (dividend, divisor, integerArithmetic) {
577 if (integerArithmetic === void 0) { integerArithmetic = false; }
578 return integerArithmetic ? Math.floor(dividend / divisor) : dividend / divisor;
579});
580var floor = argumentsToValue(Math.floor);
581var minus = argumentsToValue(function (v, arg) { return v - arg; });
582var modulo = argumentsToValue(function (v, arg) { return v % arg; });
583var times = argumentsToValue(function (v, arg) { return v * arg; });
584function round(v, arg) {
585 if (arg === void 0) { arg = 0; }
586 v = toValue(v);
587 arg = toValue(arg);
588 var amp = Math.pow(10, arg);
589 return Math.round(v * amp) / amp;
590}
591function plus(v, arg) {
592 v = toValue(v);
593 arg = toValue(arg);
594 return Number(v) + Number(arg);
595}
596
597var urlDecode = function (x) { return stringify(x).split('+').map(decodeURIComponent).join(' '); };
598var urlEncode = function (x) { return stringify(x).split(' ').map(encodeURIComponent).join('+'); };
599
600function toEnumerable(val) {
601 val = toValue(val);
602 if (isArray(val))
603 return val;
604 if (isString(val) && val.length > 0)
605 return [val];
606 if (isIterable(val))
607 return Array.from(val);
608 if (isObject(val))
609 return Object.keys(val).map(function (key) { return [key, val[key]]; });
610 return [];
611}
612function toArray(val) {
613 if (isNil(val))
614 return [];
615 if (isArray(val))
616 return val;
617 return [val];
618}
619
620var join = argumentsToValue(function (v, arg) { return toArray(v).join(arg === undefined ? ' ' : arg); });
621var last = argumentsToValue(function (v) { return isArray(v) ? last$1(v) : ''; });
622var first = argumentsToValue(function (v) { return isArray(v) ? v[0] : ''; });
623var reverse = argumentsToValue(function (v) { return __spreadArray([], __read(toArray(v)), false).reverse(); });
624function sort(arr, property) {
625 var _this = this;
626 arr = toValue(arr);
627 var getValue = function (obj) { return property ? _this.context.getFromScope(obj, stringify(property).split('.')) : obj; };
628 return __spreadArray([], __read(toArray(arr)), false).sort(function (lhs, rhs) {
629 lhs = getValue(lhs);
630 rhs = getValue(rhs);
631 return lhs < rhs ? -1 : (lhs > rhs ? 1 : 0);
632 });
633}
634function sortNatural(input, property) {
635 input = toValue(input);
636 var propertyString = stringify(property);
637 var compare = property === undefined
638 ? caseInsensitiveCompare
639 : function (lhs, rhs) { return caseInsensitiveCompare(lhs[propertyString], rhs[propertyString]); };
640 return __spreadArray([], __read(toArray(input)), false).sort(compare);
641}
642var size = function (v) { return (v && v.length) || 0; };
643function map(arr, property) {
644 var _this = this;
645 arr = toValue(arr);
646 return toArray(arr).map(function (obj) { return _this.context.getFromScope(obj, stringify(property).split('.')); });
647}
648function compact(arr) {
649 arr = toValue(arr);
650 return toArray(arr).filter(function (x) { return !isNil(toValue(x)); });
651}
652function concat(v, arg) {
653 if (arg === void 0) { arg = []; }
654 v = toValue(v);
655 arg = toArray(arg).map(function (v) { return toValue(v); });
656 return toArray(v).concat(arg);
657}
658function slice(v, begin, length) {
659 if (length === void 0) { length = 1; }
660 v = toValue(v);
661 if (isNil(v))
662 return [];
663 if (!isArray(v))
664 v = stringify(v);
665 begin = begin < 0 ? v.length + begin : begin;
666 return v.slice(begin, begin + length);
667}
668function where(arr, property, expected) {
669 var _this = this;
670 arr = toValue(arr);
671 return toArray(arr).filter(function (obj) {
672 var value = _this.context.getFromScope(obj, stringify(property).split('.'));
673 if (expected === undefined)
674 return isTruthy(value, _this.context);
675 if (isComparable(expected))
676 return expected.equals(value);
677 return value === expected;
678 });
679}
680function uniq(arr) {
681 arr = toValue(arr);
682 var u = {};
683 return (arr || []).filter(function (val) {
684 if (hasOwnProperty.call(u, String(val)))
685 return false;
686 u[String(val)] = true;
687 return true;
688 });
689}
690
691var rFormat = /%([-_0^#:]+)?(\d+)?([EO])?(.)/;
692var monthNames = [
693 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
694 'September', 'October', 'November', 'December'
695];
696var dayNames = [
697 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
698];
699var monthNamesShort = monthNames.map(abbr);
700var dayNamesShort = dayNames.map(abbr);
701var suffixes = {
702 1: 'st',
703 2: 'nd',
704 3: 'rd',
705 'default': 'th'
706};
707function abbr(str) {
708 return str.slice(0, 3);
709}
710// prototype extensions
711function daysInMonth(d) {
712 var feb = isLeapYear(d) ? 29 : 28;
713 return [31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
714}
715function getDayOfYear(d) {
716 var num = 0;
717 for (var i = 0; i < d.getMonth(); ++i) {
718 num += daysInMonth(d)[i];
719 }
720 return num + d.getDate();
721}
722function getWeekOfYear(d, startDay) {
723 // Skip to startDay of this week
724 var now = getDayOfYear(d) + (startDay - d.getDay());
725 // Find the first startDay of the year
726 var jan1 = new Date(d.getFullYear(), 0, 1);
727 var then = (7 - jan1.getDay() + startDay);
728 return String(Math.floor((now - then) / 7) + 1);
729}
730function isLeapYear(d) {
731 var year = d.getFullYear();
732 return !!((year & 3) === 0 && (year % 100 || (year % 400 === 0 && year)));
733}
734function getSuffix(d) {
735 var str = d.getDate().toString();
736 var index = parseInt(str.slice(-1));
737 return suffixes[index] || suffixes['default'];
738}
739function century(d) {
740 return parseInt(d.getFullYear().toString().substring(0, 2), 10);
741}
742// default to 0
743var padWidths = {
744 d: 2,
745 e: 2,
746 H: 2,
747 I: 2,
748 j: 3,
749 k: 2,
750 l: 2,
751 L: 3,
752 m: 2,
753 M: 2,
754 S: 2,
755 U: 2,
756 W: 2
757};
758// default to '0'
759var padChars = {
760 a: ' ',
761 A: ' ',
762 b: ' ',
763 B: ' ',
764 c: ' ',
765 e: ' ',
766 k: ' ',
767 l: ' ',
768 p: ' ',
769 P: ' '
770};
771var formatCodes = {
772 a: function (d) { return dayNamesShort[d.getDay()]; },
773 A: function (d) { return dayNames[d.getDay()]; },
774 b: function (d) { return monthNamesShort[d.getMonth()]; },
775 B: function (d) { return monthNames[d.getMonth()]; },
776 c: function (d) { return d.toLocaleString(); },
777 C: function (d) { return century(d); },
778 d: function (d) { return d.getDate(); },
779 e: function (d) { return d.getDate(); },
780 H: function (d) { return d.getHours(); },
781 I: function (d) { return String(d.getHours() % 12 || 12); },
782 j: function (d) { return getDayOfYear(d); },
783 k: function (d) { return d.getHours(); },
784 l: function (d) { return String(d.getHours() % 12 || 12); },
785 L: function (d) { return d.getMilliseconds(); },
786 m: function (d) { return d.getMonth() + 1; },
787 M: function (d) { return d.getMinutes(); },
788 N: function (d, opts) {
789 var width = Number(opts.width) || 9;
790 var str = String(d.getMilliseconds()).substr(0, width);
791 return padEnd(str, width, '0');
792 },
793 p: function (d) { return (d.getHours() < 12 ? 'AM' : 'PM'); },
794 P: function (d) { return (d.getHours() < 12 ? 'am' : 'pm'); },
795 q: function (d) { return getSuffix(d); },
796 s: function (d) { return Math.round(d.getTime() / 1000); },
797 S: function (d) { return d.getSeconds(); },
798 u: function (d) { return d.getDay() || 7; },
799 U: function (d) { return getWeekOfYear(d, 0); },
800 w: function (d) { return d.getDay(); },
801 W: function (d) { return getWeekOfYear(d, 1); },
802 x: function (d) { return d.toLocaleDateString(); },
803 X: function (d) { return d.toLocaleTimeString(); },
804 y: function (d) { return d.getFullYear().toString().substring(2, 4); },
805 Y: function (d) { return d.getFullYear(); },
806 z: function (d, opts) {
807 var nOffset = Math.abs(d.getTimezoneOffset());
808 var h = Math.floor(nOffset / 60);
809 var m = nOffset % 60;
810 return (d.getTimezoneOffset() > 0 ? '-' : '+') +
811 padStart(h, 2, '0') +
812 (opts.flags[':'] ? ':' : '') +
813 padStart(m, 2, '0');
814 },
815 't': function () { return '\t'; },
816 'n': function () { return '\n'; },
817 '%': function () { return '%'; }
818};
819formatCodes.h = formatCodes.b;
820function strftime (d, formatStr) {
821 var output = '';
822 var remaining = formatStr;
823 var match;
824 while ((match = rFormat.exec(remaining))) {
825 output += remaining.slice(0, match.index);
826 remaining = remaining.slice(match.index + match[0].length);
827 output += format(d, match);
828 }
829 return output + remaining;
830}
831function format(d, match) {
832 var e_1, _a;
833 var _b = __read(match, 5), input = _b[0], _c = _b[1], flagStr = _c === void 0 ? '' : _c, width = _b[2], modifier = _b[3], conversion = _b[4];
834 var convert = formatCodes[conversion];
835 if (!convert)
836 return input;
837 var flags = {};
838 try {
839 for (var flagStr_1 = __values(flagStr), flagStr_1_1 = flagStr_1.next(); !flagStr_1_1.done; flagStr_1_1 = flagStr_1.next()) {
840 var flag = flagStr_1_1.value;
841 flags[flag] = true;
842 }
843 }
844 catch (e_1_1) { e_1 = { error: e_1_1 }; }
845 finally {
846 try {
847 if (flagStr_1_1 && !flagStr_1_1.done && (_a = flagStr_1.return)) _a.call(flagStr_1);
848 }
849 finally { if (e_1) throw e_1.error; }
850 }
851 var ret = String(convert(d, { flags: flags, width: width, modifier: modifier }));
852 var padChar = padChars[conversion] || '0';
853 var padWidth = width || padWidths[conversion] || 0;
854 if (flags['^'])
855 ret = ret.toUpperCase();
856 else if (flags['#'])
857 ret = changeCase(ret);
858 if (flags['_'])
859 padChar = ' ';
860 else if (flags['0'])
861 padChar = '0';
862 if (flags['-'])
863 padWidth = 0;
864 return padStart(ret, padWidth, padChar);
865}
866
867// one minute in milliseconds
868var OneMinute = 60000;
869var hostTimezoneOffset = new Date().getTimezoneOffset();
870var ISO8601_TIMEZONE_PATTERN = /([zZ]|([+-])(\d{2}):(\d{2}))$/;
871/**
872 * A date implementation with timezone info, just like Ruby date
873 *
874 * Implementation:
875 * - create a Date offset by it's timezone difference, avoiding overriding a bunch of methods
876 * - rewrite getTimezoneOffset() to trick strftime
877 */
878var TimezoneDate = /** @class */ (function () {
879 function TimezoneDate(init, timezoneOffset) {
880 if (init instanceof TimezoneDate) {
881 this.date = init.date;
882 timezoneOffset = init.timezoneOffset;
883 }
884 else {
885 var diff = (hostTimezoneOffset - timezoneOffset) * OneMinute;
886 var time = new Date(init).getTime() + diff;
887 this.date = new Date(time);
888 }
889 this.timezoneOffset = timezoneOffset;
890 }
891 TimezoneDate.prototype.getTime = function () {
892 return this.date.getTime();
893 };
894 TimezoneDate.prototype.getMilliseconds = function () {
895 return this.date.getMilliseconds();
896 };
897 TimezoneDate.prototype.getSeconds = function () {
898 return this.date.getSeconds();
899 };
900 TimezoneDate.prototype.getMinutes = function () {
901 return this.date.getMinutes();
902 };
903 TimezoneDate.prototype.getHours = function () {
904 return this.date.getHours();
905 };
906 TimezoneDate.prototype.getDay = function () {
907 return this.date.getDay();
908 };
909 TimezoneDate.prototype.getDate = function () {
910 return this.date.getDate();
911 };
912 TimezoneDate.prototype.getMonth = function () {
913 return this.date.getMonth();
914 };
915 TimezoneDate.prototype.getFullYear = function () {
916 return this.date.getFullYear();
917 };
918 TimezoneDate.prototype.toLocaleTimeString = function (locale) {
919 return this.date.toLocaleTimeString(locale);
920 };
921 TimezoneDate.prototype.toLocaleDateString = function (locale) {
922 return this.date.toLocaleDateString(locale);
923 };
924 TimezoneDate.prototype.getTimezoneOffset = function () {
925 return this.timezoneOffset;
926 };
927 /**
928 * Create a Date object fixed to it's declared Timezone. Both
929 * - 2021-08-06T02:29:00.000Z and
930 * - 2021-08-06T02:29:00.000+08:00
931 * will always be displayed as
932 * - 2021-08-06 02:29:00
933 * regardless timezoneOffset in JavaScript realm
934 *
935 * The implementation hack:
936 * Instead of calling `.getMonth()`/`.getUTCMonth()` respect to `preserveTimezones`,
937 * we create a different Date to trick strftime, it's both simpler and more performant.
938 * Given that a template is expected to be parsed fewer times than rendered.
939 */
940 TimezoneDate.createDateFixedToTimezone = function (dateString) {
941 var m = dateString.match(ISO8601_TIMEZONE_PATTERN);
942 // representing a UTC timestamp
943 if (m && m[1] === 'Z') {
944 return new TimezoneDate(+new Date(dateString), 0);
945 }
946 // has a timezone specified
947 if (m && m[2] && m[3] && m[4]) {
948 var _a = __read(m, 5), sign = _a[2], hours = _a[3], minutes = _a[4];
949 var delta = (sign === '+' ? -1 : 1) * (parseInt(hours, 10) * 60 + parseInt(minutes, 10));
950 return new TimezoneDate(+new Date(dateString), delta);
951 }
952 return new Date(dateString);
953 };
954 return TimezoneDate;
955}());
956
957function date(v, arg) {
958 var opts = this.context.opts;
959 var date;
960 v = toValue(v);
961 arg = stringify(arg);
962 if (v === 'now' || v === 'today') {
963 date = new Date();
964 }
965 else if (isNumber(v)) {
966 date = new Date(v * 1000);
967 }
968 else if (isString(v)) {
969 if (/^\d+$/.test(v)) {
970 date = new Date(+v * 1000);
971 }
972 else if (opts.preserveTimezones) {
973 date = TimezoneDate.createDateFixedToTimezone(v);
974 }
975 else {
976 date = new Date(v);
977 }
978 }
979 else {
980 date = v;
981 }
982 if (!isValidDate(date))
983 return v;
984 if (opts.hasOwnProperty('timezoneOffset')) {
985 date = new TimezoneDate(date, opts.timezoneOffset);
986 }
987 return strftime(date, arg);
988}
989function isValidDate(date) {
990 return (date instanceof Date || date instanceof TimezoneDate) && !isNaN(date.getTime());
991}
992
993function Default(value, defaultValue) {
994 var args = [];
995 for (var _i = 2; _i < arguments.length; _i++) {
996 args[_i - 2] = arguments[_i];
997 }
998 value = toValue(value);
999 if (isArray(value) || isString(value))
1000 return value.length ? value : defaultValue;
1001 if (value === false && (new Map(args)).get('allow_false'))
1002 return false;
1003 return isFalsy(value, this.context) ? defaultValue : value;
1004}
1005function json(value) {
1006 return JSON.stringify(value);
1007}
1008var raw$1 = identify;
1009
1010var LiquidError = /** @class */ (function (_super) {
1011 __extends(LiquidError, _super);
1012 function LiquidError(err, token) {
1013 var _this = _super.call(this, err.message) || this;
1014 _this.originalError = err;
1015 _this.token = token;
1016 _this.context = '';
1017 return _this;
1018 }
1019 LiquidError.prototype.update = function () {
1020 var err = this.originalError;
1021 this.context = mkContext(this.token);
1022 this.message = mkMessage(err.message, this.token);
1023 this.stack = this.message + '\n' + this.context +
1024 '\n' + this.stack + '\nFrom ' + err.stack;
1025 };
1026 return LiquidError;
1027}(Error));
1028var TokenizationError = /** @class */ (function (_super) {
1029 __extends(TokenizationError, _super);
1030 function TokenizationError(message, token) {
1031 var _this = _super.call(this, new Error(message), token) || this;
1032 _this.name = 'TokenizationError';
1033 _super.prototype.update.call(_this);
1034 return _this;
1035 }
1036 return TokenizationError;
1037}(LiquidError));
1038var ParseError = /** @class */ (function (_super) {
1039 __extends(ParseError, _super);
1040 function ParseError(err, token) {
1041 var _this = _super.call(this, err, token) || this;
1042 _this.name = 'ParseError';
1043 _this.message = err.message;
1044 _super.prototype.update.call(_this);
1045 return _this;
1046 }
1047 return ParseError;
1048}(LiquidError));
1049var RenderError = /** @class */ (function (_super) {
1050 __extends(RenderError, _super);
1051 function RenderError(err, tpl) {
1052 var _this = _super.call(this, err, tpl.token) || this;
1053 _this.name = 'RenderError';
1054 _this.message = err.message;
1055 _super.prototype.update.call(_this);
1056 return _this;
1057 }
1058 RenderError.is = function (obj) {
1059 return obj.name === 'RenderError';
1060 };
1061 return RenderError;
1062}(LiquidError));
1063var UndefinedVariableError = /** @class */ (function (_super) {
1064 __extends(UndefinedVariableError, _super);
1065 function UndefinedVariableError(err, token) {
1066 var _this = _super.call(this, err, token) || this;
1067 _this.name = 'UndefinedVariableError';
1068 _this.message = err.message;
1069 _super.prototype.update.call(_this);
1070 return _this;
1071 }
1072 return UndefinedVariableError;
1073}(LiquidError));
1074// only used internally; raised where we don't have token information,
1075// so it can't be an UndefinedVariableError.
1076var InternalUndefinedVariableError = /** @class */ (function (_super) {
1077 __extends(InternalUndefinedVariableError, _super);
1078 function InternalUndefinedVariableError(variableName) {
1079 var _this = _super.call(this, "undefined variable: ".concat(variableName)) || this;
1080 _this.name = 'InternalUndefinedVariableError';
1081 _this.variableName = variableName;
1082 return _this;
1083 }
1084 return InternalUndefinedVariableError;
1085}(Error));
1086var AssertionError = /** @class */ (function (_super) {
1087 __extends(AssertionError, _super);
1088 function AssertionError(message) {
1089 var _this = _super.call(this, message) || this;
1090 _this.name = 'AssertionError';
1091 _this.message = message + '';
1092 return _this;
1093 }
1094 return AssertionError;
1095}(Error));
1096function mkContext(token) {
1097 var _a = __read(token.getPosition(), 1), line = _a[0];
1098 var lines = token.input.split('\n');
1099 var begin = Math.max(line - 2, 1);
1100 var end = Math.min(line + 3, lines.length);
1101 var context = range(begin, end + 1)
1102 .map(function (lineNumber) {
1103 var indicator = (lineNumber === line) ? '>> ' : ' ';
1104 var num = padStart(String(lineNumber), String(end).length);
1105 var text = lines[lineNumber - 1];
1106 return "".concat(indicator).concat(num, "| ").concat(text);
1107 })
1108 .join('\n');
1109 return context;
1110}
1111function mkMessage(msg, token) {
1112 if (token.file)
1113 msg += ", file:".concat(token.file);
1114 var _a = __read(token.getPosition(), 2), line = _a[0], col = _a[1];
1115 msg += ", line:".concat(line, ", col:").concat(col);
1116 return msg;
1117}
1118
1119function assert(predicate, message) {
1120 if (!predicate) {
1121 var msg = typeof message === 'function'
1122 ? message()
1123 : (message || "expect ".concat(predicate, " to be true"));
1124 throw new AssertionError(msg);
1125 }
1126}
1127
1128/**
1129 * String related filters
1130 *
1131 * * prefer stringify() to String() since `undefined`, `null` should eval ''
1132 */
1133function append(v, arg) {
1134 assert(arguments.length === 2, 'append expect 2 arguments');
1135 return stringify(v) + stringify(arg);
1136}
1137function prepend(v, arg) {
1138 assert(arguments.length === 2, 'prepend expect 2 arguments');
1139 return stringify(arg) + stringify(v);
1140}
1141function lstrip(v, chars) {
1142 if (chars) {
1143 chars = escapeRegExp(stringify(chars));
1144 return stringify(v).replace(new RegExp("^[".concat(chars, "]+"), 'g'), '');
1145 }
1146 return stringify(v).replace(/^\s+/, '');
1147}
1148function downcase(v) {
1149 return stringify(v).toLowerCase();
1150}
1151function upcase(str) {
1152 return stringify(str).toUpperCase();
1153}
1154function remove(v, arg) {
1155 return stringify(v).split(String(arg)).join('');
1156}
1157function removeFirst(v, l) {
1158 return stringify(v).replace(String(l), '');
1159}
1160function rstrip(str, chars) {
1161 if (chars) {
1162 chars = escapeRegExp(stringify(chars));
1163 return stringify(str).replace(new RegExp("[".concat(chars, "]+$"), 'g'), '');
1164 }
1165 return stringify(str).replace(/\s+$/, '');
1166}
1167function split(v, arg) {
1168 var arr = stringify(v).split(String(arg));
1169 // align to ruby split, which is the behavior of shopify/liquid
1170 // see: https://ruby-doc.org/core-2.4.0/String.html#method-i-split
1171 while (arr.length && arr[arr.length - 1] === '')
1172 arr.pop();
1173 return arr;
1174}
1175function strip(v, chars) {
1176 if (chars) {
1177 chars = escapeRegExp(stringify(chars));
1178 return stringify(v)
1179 .replace(new RegExp("^[".concat(chars, "]+"), 'g'), '')
1180 .replace(new RegExp("[".concat(chars, "]+$"), 'g'), '');
1181 }
1182 return stringify(v).trim();
1183}
1184function stripNewlines(v) {
1185 return stringify(v).replace(/\n/g, '');
1186}
1187function capitalize(str) {
1188 str = stringify(str);
1189 return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
1190}
1191function replace(v, pattern, replacement) {
1192 return stringify(v).split(String(pattern)).join(replacement);
1193}
1194function replaceFirst(v, arg1, arg2) {
1195 return stringify(v).replace(String(arg1), arg2);
1196}
1197function truncate(v, l, o) {
1198 if (l === void 0) { l = 50; }
1199 if (o === void 0) { o = '...'; }
1200 v = stringify(v);
1201 if (v.length <= l)
1202 return v;
1203 return v.substring(0, l - o.length) + o;
1204}
1205function truncatewords(v, l, o) {
1206 if (l === void 0) { l = 15; }
1207 if (o === void 0) { o = '...'; }
1208 var arr = stringify(v).split(/\s+/);
1209 var ret = arr.slice(0, l).join(' ');
1210 if (arr.length >= l)
1211 ret += o;
1212 return ret;
1213}
1214
1215var builtinFilters = /*#__PURE__*/Object.freeze({
1216 __proto__: null,
1217 escape: escape,
1218 escapeOnce: escapeOnce,
1219 newlineToBr: newlineToBr,
1220 stripHtml: stripHtml,
1221 abs: abs,
1222 atLeast: atLeast,
1223 atMost: atMost,
1224 ceil: ceil,
1225 dividedBy: dividedBy,
1226 floor: floor,
1227 minus: minus,
1228 modulo: modulo,
1229 times: times,
1230 round: round,
1231 plus: plus,
1232 urlDecode: urlDecode,
1233 urlEncode: urlEncode,
1234 join: join,
1235 last: last,
1236 first: first,
1237 reverse: reverse,
1238 sort: sort,
1239 sortNatural: sortNatural,
1240 size: size,
1241 map: map,
1242 compact: compact,
1243 concat: concat,
1244 slice: slice,
1245 where: where,
1246 uniq: uniq,
1247 date: date,
1248 Default: Default,
1249 json: json,
1250 raw: raw$1,
1251 append: append,
1252 prepend: prepend,
1253 lstrip: lstrip,
1254 downcase: downcase,
1255 upcase: upcase,
1256 remove: remove,
1257 removeFirst: removeFirst,
1258 rstrip: rstrip,
1259 split: split,
1260 strip: strip,
1261 stripNewlines: stripNewlines,
1262 capitalize: capitalize,
1263 replace: replace,
1264 replaceFirst: replaceFirst,
1265 truncate: truncate,
1266 truncatewords: truncatewords
1267});
1268
1269exports.TokenKind = void 0;
1270(function (TokenKind) {
1271 TokenKind[TokenKind["Number"] = 1] = "Number";
1272 TokenKind[TokenKind["Literal"] = 2] = "Literal";
1273 TokenKind[TokenKind["Tag"] = 4] = "Tag";
1274 TokenKind[TokenKind["Output"] = 8] = "Output";
1275 TokenKind[TokenKind["HTML"] = 16] = "HTML";
1276 TokenKind[TokenKind["Filter"] = 32] = "Filter";
1277 TokenKind[TokenKind["Hash"] = 64] = "Hash";
1278 TokenKind[TokenKind["PropertyAccess"] = 128] = "PropertyAccess";
1279 TokenKind[TokenKind["Word"] = 256] = "Word";
1280 TokenKind[TokenKind["Range"] = 512] = "Range";
1281 TokenKind[TokenKind["Quoted"] = 1024] = "Quoted";
1282 TokenKind[TokenKind["Operator"] = 2048] = "Operator";
1283 TokenKind[TokenKind["Delimited"] = 12] = "Delimited";
1284})(exports.TokenKind || (exports.TokenKind = {}));
1285
1286function isDelimitedToken(val) {
1287 return !!(getKind(val) & exports.TokenKind.Delimited);
1288}
1289function isOperatorToken(val) {
1290 return getKind(val) === exports.TokenKind.Operator;
1291}
1292function isHTMLToken(val) {
1293 return getKind(val) === exports.TokenKind.HTML;
1294}
1295function isOutputToken(val) {
1296 return getKind(val) === exports.TokenKind.Output;
1297}
1298function isTagToken(val) {
1299 return getKind(val) === exports.TokenKind.Tag;
1300}
1301function isQuotedToken(val) {
1302 return getKind(val) === exports.TokenKind.Quoted;
1303}
1304function isLiteralToken(val) {
1305 return getKind(val) === exports.TokenKind.Literal;
1306}
1307function isNumberToken(val) {
1308 return getKind(val) === exports.TokenKind.Number;
1309}
1310function isPropertyAccessToken(val) {
1311 return getKind(val) === exports.TokenKind.PropertyAccess;
1312}
1313function isWordToken(val) {
1314 return getKind(val) === exports.TokenKind.Word;
1315}
1316function isRangeToken(val) {
1317 return getKind(val) === exports.TokenKind.Range;
1318}
1319function getKind(val) {
1320 return val ? val.kind : -1;
1321}
1322
1323var typeGuards = /*#__PURE__*/Object.freeze({
1324 __proto__: null,
1325 isDelimitedToken: isDelimitedToken,
1326 isOperatorToken: isOperatorToken,
1327 isHTMLToken: isHTMLToken,
1328 isOutputToken: isOutputToken,
1329 isTagToken: isTagToken,
1330 isQuotedToken: isQuotedToken,
1331 isLiteralToken: isLiteralToken,
1332 isNumberToken: isNumberToken,
1333 isPropertyAccessToken: isPropertyAccessToken,
1334 isWordToken: isWordToken,
1335 isRangeToken: isRangeToken
1336});
1337
1338var NullDrop = /** @class */ (function (_super) {
1339 __extends(NullDrop, _super);
1340 function NullDrop() {
1341 return _super !== null && _super.apply(this, arguments) || this;
1342 }
1343 NullDrop.prototype.equals = function (value) {
1344 return isNil(toValue(value));
1345 };
1346 NullDrop.prototype.gt = function () {
1347 return false;
1348 };
1349 NullDrop.prototype.geq = function () {
1350 return false;
1351 };
1352 NullDrop.prototype.lt = function () {
1353 return false;
1354 };
1355 NullDrop.prototype.leq = function () {
1356 return false;
1357 };
1358 NullDrop.prototype.valueOf = function () {
1359 return null;
1360 };
1361 return NullDrop;
1362}(Drop));
1363
1364var EmptyDrop = /** @class */ (function (_super) {
1365 __extends(EmptyDrop, _super);
1366 function EmptyDrop() {
1367 return _super !== null && _super.apply(this, arguments) || this;
1368 }
1369 EmptyDrop.prototype.equals = function (value) {
1370 if (value instanceof EmptyDrop)
1371 return false;
1372 value = toValue(value);
1373 if (isString(value) || isArray(value))
1374 return value.length === 0;
1375 if (isObject(value))
1376 return Object.keys(value).length === 0;
1377 return false;
1378 };
1379 EmptyDrop.prototype.gt = function () {
1380 return false;
1381 };
1382 EmptyDrop.prototype.geq = function () {
1383 return false;
1384 };
1385 EmptyDrop.prototype.lt = function () {
1386 return false;
1387 };
1388 EmptyDrop.prototype.leq = function () {
1389 return false;
1390 };
1391 EmptyDrop.prototype.valueOf = function () {
1392 return '';
1393 };
1394 return EmptyDrop;
1395}(Drop));
1396
1397var BlankDrop = /** @class */ (function (_super) {
1398 __extends(BlankDrop, _super);
1399 function BlankDrop() {
1400 return _super !== null && _super.apply(this, arguments) || this;
1401 }
1402 BlankDrop.prototype.equals = function (value) {
1403 if (value === false)
1404 return true;
1405 if (isNil(toValue(value)))
1406 return true;
1407 if (isString(value))
1408 return /^\s*$/.test(value);
1409 return _super.prototype.equals.call(this, value);
1410 };
1411 return BlankDrop;
1412}(EmptyDrop));
1413
1414var nil = new NullDrop();
1415var literalValues = {
1416 'true': true,
1417 'false': false,
1418 'nil': nil,
1419 'null': nil,
1420 'empty': new EmptyDrop(),
1421 'blank': new BlankDrop()
1422};
1423
1424var rHex = /[\da-fA-F]/;
1425var rOct = /[0-7]/;
1426var escapeChar = {
1427 b: '\b',
1428 f: '\f',
1429 n: '\n',
1430 r: '\r',
1431 t: '\t',
1432 v: '\x0B'
1433};
1434function hexVal(c) {
1435 var code = c.charCodeAt(0);
1436 if (code >= 97)
1437 return code - 87;
1438 if (code >= 65)
1439 return code - 55;
1440 return code - 48;
1441}
1442function parseStringLiteral(str) {
1443 var ret = '';
1444 for (var i = 1; i < str.length - 1; i++) {
1445 if (str[i] !== '\\') {
1446 ret += str[i];
1447 continue;
1448 }
1449 if (escapeChar[str[i + 1]] !== undefined) {
1450 ret += escapeChar[str[++i]];
1451 }
1452 else if (str[i + 1] === 'u') {
1453 var val = 0;
1454 var j = i + 2;
1455 while (j <= i + 5 && rHex.test(str[j])) {
1456 val = val * 16 + hexVal(str[j++]);
1457 }
1458 i = j - 1;
1459 ret += String.fromCharCode(val);
1460 }
1461 else if (!rOct.test(str[i + 1])) {
1462 ret += str[++i];
1463 }
1464 else {
1465 var j = i + 1;
1466 var val = 0;
1467 while (j <= i + 3 && rOct.test(str[j])) {
1468 val = val * 8 + hexVal(str[j++]);
1469 }
1470 i = j - 1;
1471 ret += String.fromCharCode(val);
1472 }
1473 }
1474 return ret;
1475}
1476
1477var Expression = /** @class */ (function () {
1478 function Expression(tokens) {
1479 this.postfix = __spreadArray([], __read(toPostfix(tokens)), false);
1480 }
1481 Expression.prototype.evaluate = function (ctx, lenient) {
1482 var operands, _a, _b, token, r, l, result, _c, _d, e_1_1;
1483 var e_1, _e;
1484 return __generator(this, function (_f) {
1485 switch (_f.label) {
1486 case 0:
1487 assert(ctx, 'unable to evaluate: context not defined');
1488 operands = [];
1489 _f.label = 1;
1490 case 1:
1491 _f.trys.push([1, 8, 9, 10]);
1492 _a = __values(this.postfix), _b = _a.next();
1493 _f.label = 2;
1494 case 2:
1495 if (!!_b.done) return [3 /*break*/, 7];
1496 token = _b.value;
1497 if (!isOperatorToken(token)) return [3 /*break*/, 4];
1498 r = operands.pop();
1499 l = operands.pop();
1500 return [4 /*yield*/, evalOperatorToken(ctx.opts.operators, token, l, r, ctx)];
1501 case 3:
1502 result = _f.sent();
1503 operands.push(result);
1504 return [3 /*break*/, 6];
1505 case 4:
1506 _d = (_c = operands).push;
1507 return [4 /*yield*/, evalToken(token, ctx, lenient && this.postfix.length === 1)];
1508 case 5:
1509 _d.apply(_c, [_f.sent()]);
1510 _f.label = 6;
1511 case 6:
1512 _b = _a.next();
1513 return [3 /*break*/, 2];
1514 case 7: return [3 /*break*/, 10];
1515 case 8:
1516 e_1_1 = _f.sent();
1517 e_1 = { error: e_1_1 };
1518 return [3 /*break*/, 10];
1519 case 9:
1520 try {
1521 if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
1522 }
1523 finally { if (e_1) throw e_1.error; }
1524 return [7 /*endfinally*/];
1525 case 10: return [2 /*return*/, operands[0]];
1526 }
1527 });
1528 };
1529 return Expression;
1530}());
1531function evalToken(token, ctx, lenient) {
1532 if (lenient === void 0) { lenient = false; }
1533 if (isPropertyAccessToken(token))
1534 return evalPropertyAccessToken(token, ctx, lenient);
1535 if (isRangeToken(token))
1536 return evalRangeToken(token, ctx);
1537 if (isLiteralToken(token))
1538 return evalLiteralToken(token);
1539 if (isNumberToken(token))
1540 return evalNumberToken(token);
1541 if (isWordToken(token))
1542 return token.getText();
1543 if (isQuotedToken(token))
1544 return evalQuotedToken(token);
1545}
1546function evalPropertyAccessToken(token, ctx, lenient) {
1547 var props = token.props.map(function (prop) { return evalToken(prop, ctx, false); });
1548 try {
1549 return ctx.get(__spreadArray([token.propertyName], __read(props), false));
1550 }
1551 catch (e) {
1552 if (lenient && e.name === 'InternalUndefinedVariableError')
1553 return null;
1554 throw (new UndefinedVariableError(e, token));
1555 }
1556}
1557function evalNumberToken(token) {
1558 var str = token.whole.content + '.' + (token.decimal ? token.decimal.content : '');
1559 return Number(str);
1560}
1561function evalQuotedToken(token) {
1562 return parseStringLiteral(token.getText());
1563}
1564function evalOperatorToken(operators, token, lhs, rhs, ctx) {
1565 var impl = operators[token.operator];
1566 return impl(lhs, rhs, ctx);
1567}
1568function evalLiteralToken(token) {
1569 return literalValues[token.literal];
1570}
1571function evalRangeToken(token, ctx) {
1572 var low = evalToken(token.lhs, ctx);
1573 var high = evalToken(token.rhs, ctx);
1574 return range(+low, +high + 1);
1575}
1576function toPostfix(tokens) {
1577 var ops, tokens_1, tokens_1_1, token, e_2_1;
1578 var e_2, _a;
1579 return __generator(this, function (_b) {
1580 switch (_b.label) {
1581 case 0:
1582 ops = [];
1583 _b.label = 1;
1584 case 1:
1585 _b.trys.push([1, 10, 11, 12]);
1586 tokens_1 = __values(tokens), tokens_1_1 = tokens_1.next();
1587 _b.label = 2;
1588 case 2:
1589 if (!!tokens_1_1.done) return [3 /*break*/, 9];
1590 token = tokens_1_1.value;
1591 if (!isOperatorToken(token)) return [3 /*break*/, 6];
1592 _b.label = 3;
1593 case 3:
1594 if (!(ops.length && ops[ops.length - 1].getPrecedence() > token.getPrecedence())) return [3 /*break*/, 5];
1595 return [4 /*yield*/, ops.pop()];
1596 case 4:
1597 _b.sent();
1598 return [3 /*break*/, 3];
1599 case 5:
1600 ops.push(token);
1601 return [3 /*break*/, 8];
1602 case 6: return [4 /*yield*/, token];
1603 case 7:
1604 _b.sent();
1605 _b.label = 8;
1606 case 8:
1607 tokens_1_1 = tokens_1.next();
1608 return [3 /*break*/, 2];
1609 case 9: return [3 /*break*/, 12];
1610 case 10:
1611 e_2_1 = _b.sent();
1612 e_2 = { error: e_2_1 };
1613 return [3 /*break*/, 12];
1614 case 11:
1615 try {
1616 if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
1617 }
1618 finally { if (e_2) throw e_2.error; }
1619 return [7 /*endfinally*/];
1620 case 12:
1621 if (!ops.length) return [3 /*break*/, 14];
1622 return [4 /*yield*/, ops.pop()];
1623 case 13:
1624 _b.sent();
1625 return [3 /*break*/, 12];
1626 case 14: return [2 /*return*/];
1627 }
1628 });
1629}
1630
1631var Token = /** @class */ (function () {
1632 function Token(kind, input, begin, end, file) {
1633 this.kind = kind;
1634 this.input = input;
1635 this.begin = begin;
1636 this.end = end;
1637 this.file = file;
1638 }
1639 Token.prototype.getText = function () {
1640 return this.input.slice(this.begin, this.end);
1641 };
1642 Token.prototype.getPosition = function () {
1643 var _a = __read([1, 1], 2), row = _a[0], col = _a[1];
1644 for (var i = 0; i < this.begin; i++) {
1645 if (this.input[i] === '\n') {
1646 row++;
1647 col = 1;
1648 }
1649 else
1650 col++;
1651 }
1652 return [row, col];
1653 };
1654 Token.prototype.size = function () {
1655 return this.end - this.begin;
1656 };
1657 return Token;
1658}());
1659
1660var DelimitedToken = /** @class */ (function (_super) {
1661 __extends(DelimitedToken, _super);
1662 function DelimitedToken(kind, content, input, begin, end, trimLeft, trimRight, file) {
1663 var _this = _super.call(this, kind, input, begin, end, file) || this;
1664 _this.trimLeft = false;
1665 _this.trimRight = false;
1666 _this.content = _this.getText();
1667 var tl = content[0] === '-';
1668 var tr = last$1(content) === '-';
1669 _this.content = content
1670 .slice(tl ? 1 : 0, tr ? -1 : content.length)
1671 .trim();
1672 _this.trimLeft = tl || trimLeft;
1673 _this.trimRight = tr || trimRight;
1674 return _this;
1675 }
1676 return DelimitedToken;
1677}(Token));
1678
1679function whiteSpaceCtrl(tokens, options) {
1680 var inRaw = false;
1681 for (var i = 0; i < tokens.length; i++) {
1682 var token = tokens[i];
1683 if (!isDelimitedToken(token))
1684 continue;
1685 if (!inRaw && token.trimLeft) {
1686 trimLeft(tokens[i - 1], options.greedy);
1687 }
1688 if (isTagToken(token)) {
1689 if (token.name === 'raw')
1690 inRaw = true;
1691 else if (token.name === 'endraw')
1692 inRaw = false;
1693 }
1694 if (!inRaw && token.trimRight) {
1695 trimRight(tokens[i + 1], options.greedy);
1696 }
1697 }
1698}
1699function trimLeft(token, greedy) {
1700 if (!token || !isHTMLToken(token))
1701 return;
1702 var mask = greedy ? BLANK : INLINE_BLANK;
1703 while (TYPES[token.input.charCodeAt(token.end - 1 - token.trimRight)] & mask)
1704 token.trimRight++;
1705}
1706function trimRight(token, greedy) {
1707 if (!token || !isHTMLToken(token))
1708 return;
1709 var mask = greedy ? BLANK : INLINE_BLANK;
1710 while (TYPES[token.input.charCodeAt(token.begin + token.trimLeft)] & mask)
1711 token.trimLeft++;
1712 if (token.input.charAt(token.begin + token.trimLeft) === '\n')
1713 token.trimLeft++;
1714}
1715
1716var NumberToken = /** @class */ (function (_super) {
1717 __extends(NumberToken, _super);
1718 function NumberToken(whole, decimal) {
1719 var _this = _super.call(this, exports.TokenKind.Number, whole.input, whole.begin, decimal ? decimal.end : whole.end, whole.file) || this;
1720 _this.whole = whole;
1721 _this.decimal = decimal;
1722 return _this;
1723 }
1724 return NumberToken;
1725}(Token));
1726
1727var IdentifierToken = /** @class */ (function (_super) {
1728 __extends(IdentifierToken, _super);
1729 function IdentifierToken(input, begin, end, file) {
1730 var _this = _super.call(this, exports.TokenKind.Word, input, begin, end, file) || this;
1731 _this.input = input;
1732 _this.begin = begin;
1733 _this.end = end;
1734 _this.file = file;
1735 _this.content = _this.getText();
1736 return _this;
1737 }
1738 IdentifierToken.prototype.isNumber = function (allowSign) {
1739 if (allowSign === void 0) { allowSign = false; }
1740 var begin = allowSign && TYPES[this.input.charCodeAt(this.begin)] & SIGN
1741 ? this.begin + 1
1742 : this.begin;
1743 for (var i = begin; i < this.end; i++) {
1744 if (!(TYPES[this.input.charCodeAt(i)] & NUMBER))
1745 return false;
1746 }
1747 return true;
1748 };
1749 return IdentifierToken;
1750}(Token));
1751
1752var LiteralToken = /** @class */ (function (_super) {
1753 __extends(LiteralToken, _super);
1754 function LiteralToken(input, begin, end, file) {
1755 var _this = _super.call(this, exports.TokenKind.Literal, input, begin, end, file) || this;
1756 _this.input = input;
1757 _this.begin = begin;
1758 _this.end = end;
1759 _this.file = file;
1760 _this.literal = _this.getText();
1761 return _this;
1762 }
1763 return LiteralToken;
1764}(Token));
1765
1766var precedence = {
1767 '==': 1,
1768 '!=': 1,
1769 '>': 1,
1770 '<': 1,
1771 '>=': 1,
1772 '<=': 1,
1773 'contains': 1,
1774 'and': 0,
1775 'or': 0
1776};
1777var OperatorToken = /** @class */ (function (_super) {
1778 __extends(OperatorToken, _super);
1779 function OperatorToken(input, begin, end, file) {
1780 var _this = _super.call(this, exports.TokenKind.Operator, input, begin, end, file) || this;
1781 _this.input = input;
1782 _this.begin = begin;
1783 _this.end = end;
1784 _this.file = file;
1785 _this.operator = _this.getText();
1786 return _this;
1787 }
1788 OperatorToken.prototype.getPrecedence = function () {
1789 var key = this.getText();
1790 return key in precedence ? precedence[key] : 1;
1791 };
1792 return OperatorToken;
1793}(Token));
1794
1795var PropertyAccessToken = /** @class */ (function (_super) {
1796 __extends(PropertyAccessToken, _super);
1797 function PropertyAccessToken(variable, props, end) {
1798 var _this = _super.call(this, exports.TokenKind.PropertyAccess, variable.input, variable.begin, end, variable.file) || this;
1799 _this.variable = variable;
1800 _this.props = props;
1801 _this.propertyName = _this.variable instanceof IdentifierToken
1802 ? _this.variable.getText()
1803 : parseStringLiteral(_this.variable.getText());
1804 return _this;
1805 }
1806 return PropertyAccessToken;
1807}(Token));
1808
1809var FilterToken = /** @class */ (function (_super) {
1810 __extends(FilterToken, _super);
1811 function FilterToken(name, args, input, begin, end, file) {
1812 var _this = _super.call(this, exports.TokenKind.Filter, input, begin, end, file) || this;
1813 _this.name = name;
1814 _this.args = args;
1815 return _this;
1816 }
1817 return FilterToken;
1818}(Token));
1819
1820var HashToken = /** @class */ (function (_super) {
1821 __extends(HashToken, _super);
1822 function HashToken(input, begin, end, name, value, file) {
1823 var _this = _super.call(this, exports.TokenKind.Hash, input, begin, end, file) || this;
1824 _this.input = input;
1825 _this.begin = begin;
1826 _this.end = end;
1827 _this.name = name;
1828 _this.value = value;
1829 _this.file = file;
1830 return _this;
1831 }
1832 return HashToken;
1833}(Token));
1834
1835var QuotedToken = /** @class */ (function (_super) {
1836 __extends(QuotedToken, _super);
1837 function QuotedToken(input, begin, end, file) {
1838 var _this = _super.call(this, exports.TokenKind.Quoted, input, begin, end, file) || this;
1839 _this.input = input;
1840 _this.begin = begin;
1841 _this.end = end;
1842 _this.file = file;
1843 return _this;
1844 }
1845 return QuotedToken;
1846}(Token));
1847
1848var HTMLToken = /** @class */ (function (_super) {
1849 __extends(HTMLToken, _super);
1850 function HTMLToken(input, begin, end, file) {
1851 var _this = _super.call(this, exports.TokenKind.HTML, input, begin, end, file) || this;
1852 _this.input = input;
1853 _this.begin = begin;
1854 _this.end = end;
1855 _this.file = file;
1856 _this.trimLeft = 0;
1857 _this.trimRight = 0;
1858 return _this;
1859 }
1860 HTMLToken.prototype.getContent = function () {
1861 return this.input.slice(this.begin + this.trimLeft, this.end - this.trimRight);
1862 };
1863 return HTMLToken;
1864}(Token));
1865
1866var RangeToken = /** @class */ (function (_super) {
1867 __extends(RangeToken, _super);
1868 function RangeToken(input, begin, end, lhs, rhs, file) {
1869 var _this = _super.call(this, exports.TokenKind.Range, input, begin, end, file) || this;
1870 _this.input = input;
1871 _this.begin = begin;
1872 _this.end = end;
1873 _this.lhs = lhs;
1874 _this.rhs = rhs;
1875 _this.file = file;
1876 return _this;
1877 }
1878 return RangeToken;
1879}(Token));
1880
1881var OutputToken = /** @class */ (function (_super) {
1882 __extends(OutputToken, _super);
1883 function OutputToken(input, begin, end, options, file) {
1884 var _this = this;
1885 var trimOutputLeft = options.trimOutputLeft, trimOutputRight = options.trimOutputRight, outputDelimiterLeft = options.outputDelimiterLeft, outputDelimiterRight = options.outputDelimiterRight;
1886 var value = input.slice(begin + outputDelimiterLeft.length, end - outputDelimiterRight.length);
1887 _this = _super.call(this, exports.TokenKind.Output, value, input, begin, end, trimOutputLeft, trimOutputRight, file) || this;
1888 return _this;
1889 }
1890 return OutputToken;
1891}(DelimitedToken));
1892
1893function matchOperator(str, begin, trie, end) {
1894 if (end === void 0) { end = str.length; }
1895 var node = trie;
1896 var i = begin;
1897 var info;
1898 while (node[str[i]] && i < end) {
1899 node = node[str[i++]];
1900 if (node['end'])
1901 info = node;
1902 }
1903 if (!info)
1904 return -1;
1905 if (info['needBoundary'] && (TYPES[str.charCodeAt(i)] & IDENTIFIER))
1906 return -1;
1907 return i;
1908}
1909
1910var LiquidTagToken = /** @class */ (function (_super) {
1911 __extends(LiquidTagToken, _super);
1912 function LiquidTagToken(input, begin, end, options, file) {
1913 var _this = this;
1914 var value = input.slice(begin, end);
1915 _this = _super.call(this, exports.TokenKind.Tag, value, input, begin, end, false, false, file) || this;
1916 if (!/\S/.test(value)) {
1917 // A line that contains only whitespace.
1918 _this.name = '';
1919 _this.args = '';
1920 }
1921 else {
1922 var tokenizer = new Tokenizer(_this.content, options.operatorsTrie);
1923 _this.name = tokenizer.readTagName();
1924 if (!_this.name)
1925 throw new TokenizationError("illegal liquid tag syntax", _this);
1926 tokenizer.skipBlank();
1927 _this.args = tokenizer.remaining();
1928 }
1929 return _this;
1930 }
1931 return LiquidTagToken;
1932}(DelimitedToken));
1933
1934var Tokenizer = /** @class */ (function () {
1935 function Tokenizer(input, trie, file) {
1936 if (trie === void 0) { trie = defaultOptions.operatorsTrie; }
1937 if (file === void 0) { file = ''; }
1938 this.input = input;
1939 this.trie = trie;
1940 this.file = file;
1941 this.p = 0;
1942 this.rawBeginAt = -1;
1943 this.N = input.length;
1944 }
1945 Tokenizer.prototype.readExpression = function () {
1946 return new Expression(this.readExpressionTokens());
1947 };
1948 Tokenizer.prototype.readExpressionTokens = function () {
1949 var operand, operator, operand_1;
1950 return __generator(this, function (_a) {
1951 switch (_a.label) {
1952 case 0:
1953 operand = this.readValue();
1954 if (!operand)
1955 return [2 /*return*/];
1956 return [4 /*yield*/, operand];
1957 case 1:
1958 _a.sent();
1959 _a.label = 2;
1960 case 2:
1961 if (!(this.p < this.N)) return [3 /*break*/, 5];
1962 operator = this.readOperator();
1963 if (!operator)
1964 return [2 /*return*/];
1965 operand_1 = this.readValue();
1966 if (!operand_1)
1967 return [2 /*return*/];
1968 return [4 /*yield*/, operator];
1969 case 3:
1970 _a.sent();
1971 return [4 /*yield*/, operand_1];
1972 case 4:
1973 _a.sent();
1974 return [3 /*break*/, 2];
1975 case 5: return [2 /*return*/];
1976 }
1977 });
1978 };
1979 Tokenizer.prototype.readOperator = function () {
1980 this.skipBlank();
1981 var end = matchOperator(this.input, this.p, this.trie);
1982 if (end === -1)
1983 return;
1984 return new OperatorToken(this.input, this.p, (this.p = end), this.file);
1985 };
1986 Tokenizer.prototype.readFilters = function () {
1987 var filters = [];
1988 while (true) {
1989 var filter = this.readFilter();
1990 if (!filter)
1991 return filters;
1992 filters.push(filter);
1993 }
1994 };
1995 Tokenizer.prototype.readFilter = function () {
1996 var _this = this;
1997 this.skipBlank();
1998 if (this.end())
1999 return null;
2000 assert(this.peek() === '|', function () { return "unexpected token at ".concat(_this.snapshot()); });
2001 this.p++;
2002 var begin = this.p;
2003 var name = this.readIdentifier();
2004 if (!name.size())
2005 return null;
2006 var args = [];
2007 this.skipBlank();
2008 if (this.peek() === ':') {
2009 do {
2010 ++this.p;
2011 var arg = this.readFilterArg();
2012 arg && args.push(arg);
2013 this.skipBlank();
2014 assert(this.end() || this.peek() === ',' || this.peek() === '|', function () { return "unexpected character ".concat(_this.snapshot()); });
2015 } while (this.peek() === ',');
2016 }
2017 return new FilterToken(name.getText(), args, this.input, begin, this.p, this.file);
2018 };
2019 Tokenizer.prototype.readFilterArg = function () {
2020 var key = this.readValue();
2021 if (!key)
2022 return;
2023 this.skipBlank();
2024 if (this.peek() !== ':')
2025 return key;
2026 ++this.p;
2027 var value = this.readValue();
2028 return [key.getText(), value];
2029 };
2030 Tokenizer.prototype.readTopLevelTokens = function (options) {
2031 if (options === void 0) { options = defaultOptions; }
2032 var tokens = [];
2033 while (this.p < this.N) {
2034 var token = this.readTopLevelToken(options);
2035 tokens.push(token);
2036 }
2037 whiteSpaceCtrl(tokens, options);
2038 return tokens;
2039 };
2040 Tokenizer.prototype.readTopLevelToken = function (options) {
2041 var tagDelimiterLeft = options.tagDelimiterLeft, outputDelimiterLeft = options.outputDelimiterLeft;
2042 if (this.rawBeginAt > -1)
2043 return this.readEndrawOrRawContent(options);
2044 if (this.match(tagDelimiterLeft))
2045 return this.readTagToken(options);
2046 if (this.match(outputDelimiterLeft))
2047 return this.readOutputToken(options);
2048 return this.readHTMLToken([tagDelimiterLeft, outputDelimiterLeft]);
2049 };
2050 Tokenizer.prototype.readHTMLToken = function (stopStrings) {
2051 var _this = this;
2052 var begin = this.p;
2053 while (this.p < this.N) {
2054 if (stopStrings.some(function (str) { return _this.match(str); }))
2055 break;
2056 ++this.p;
2057 }
2058 return new HTMLToken(this.input, begin, this.p, this.file);
2059 };
2060 Tokenizer.prototype.readTagToken = function (options) {
2061 if (options === void 0) { options = defaultOptions; }
2062 var _a = this, file = _a.file, input = _a.input;
2063 var begin = this.p;
2064 if (this.readToDelimiter(options.tagDelimiterRight) === -1) {
2065 throw this.mkError("tag ".concat(this.snapshot(begin), " not closed"), begin);
2066 }
2067 var token = new TagToken(input, begin, this.p, options, file);
2068 if (token.name === 'raw')
2069 this.rawBeginAt = begin;
2070 return token;
2071 };
2072 Tokenizer.prototype.readToDelimiter = function (delimiter) {
2073 while (this.p < this.N) {
2074 if ((this.peekType() & QUOTE)) {
2075 this.readQuoted();
2076 continue;
2077 }
2078 ++this.p;
2079 if (this.rmatch(delimiter))
2080 return this.p;
2081 }
2082 return -1;
2083 };
2084 Tokenizer.prototype.readOutputToken = function (options) {
2085 if (options === void 0) { options = defaultOptions; }
2086 var _a = this, file = _a.file, input = _a.input;
2087 var outputDelimiterRight = options.outputDelimiterRight;
2088 var begin = this.p;
2089 if (this.readToDelimiter(outputDelimiterRight) === -1) {
2090 throw this.mkError("output ".concat(this.snapshot(begin), " not closed"), begin);
2091 }
2092 return new OutputToken(input, begin, this.p, options, file);
2093 };
2094 Tokenizer.prototype.readEndrawOrRawContent = function (options) {
2095 var tagDelimiterLeft = options.tagDelimiterLeft, tagDelimiterRight = options.tagDelimiterRight;
2096 var begin = this.p;
2097 var leftPos = this.readTo(tagDelimiterLeft) - tagDelimiterLeft.length;
2098 while (this.p < this.N) {
2099 if (this.readIdentifier().getText() !== 'endraw') {
2100 leftPos = this.readTo(tagDelimiterLeft) - tagDelimiterLeft.length;
2101 continue;
2102 }
2103 while (this.p <= this.N) {
2104 if (this.rmatch(tagDelimiterRight)) {
2105 var end = this.p;
2106 if (begin === leftPos) {
2107 this.rawBeginAt = -1;
2108 return new TagToken(this.input, begin, end, options, this.file);
2109 }
2110 else {
2111 this.p = leftPos;
2112 return new HTMLToken(this.input, begin, leftPos, this.file);
2113 }
2114 }
2115 if (this.rmatch(tagDelimiterLeft))
2116 break;
2117 this.p++;
2118 }
2119 }
2120 throw this.mkError("raw ".concat(this.snapshot(this.rawBeginAt), " not closed"), begin);
2121 };
2122 Tokenizer.prototype.readLiquidTagTokens = function (options) {
2123 if (options === void 0) { options = defaultOptions; }
2124 var tokens = [];
2125 while (this.p < this.N) {
2126 var token = this.readLiquidTagToken(options);
2127 if (token.name)
2128 tokens.push(token);
2129 }
2130 return tokens;
2131 };
2132 Tokenizer.prototype.readLiquidTagToken = function (options) {
2133 var _a = this, file = _a.file, input = _a.input;
2134 var begin = this.p;
2135 var end = this.N;
2136 if (this.readToDelimiter('\n') !== -1)
2137 end = this.p;
2138 return new LiquidTagToken(input, begin, end, options, file);
2139 };
2140 Tokenizer.prototype.mkError = function (msg, begin) {
2141 return new TokenizationError(msg, new IdentifierToken(this.input, begin, this.N, this.file));
2142 };
2143 Tokenizer.prototype.snapshot = function (begin) {
2144 if (begin === void 0) { begin = this.p; }
2145 return JSON.stringify(ellipsis(this.input.slice(begin), 16));
2146 };
2147 /**
2148 * @deprecated
2149 */
2150 Tokenizer.prototype.readWord = function () {
2151 console.warn('Tokenizer#readWord() will be removed, use #readIdentifier instead');
2152 return this.readIdentifier();
2153 };
2154 Tokenizer.prototype.readIdentifier = function () {
2155 this.skipBlank();
2156 var begin = this.p;
2157 while (this.peekType() & IDENTIFIER)
2158 ++this.p;
2159 return new IdentifierToken(this.input, begin, this.p, this.file);
2160 };
2161 Tokenizer.prototype.readTagName = function () {
2162 this.skipBlank();
2163 // Handle inline comment tags
2164 if (this.input[this.p] === '#')
2165 return this.input.slice(this.p, ++this.p);
2166 return this.readIdentifier().getText();
2167 };
2168 Tokenizer.prototype.readHashes = function (jekyllStyle) {
2169 var hashes = [];
2170 while (true) {
2171 var hash = this.readHash(jekyllStyle);
2172 if (!hash)
2173 return hashes;
2174 hashes.push(hash);
2175 }
2176 };
2177 Tokenizer.prototype.readHash = function (jekyllStyle) {
2178 this.skipBlank();
2179 if (this.peek() === ',')
2180 ++this.p;
2181 var begin = this.p;
2182 var name = this.readIdentifier();
2183 if (!name.size())
2184 return;
2185 var value;
2186 this.skipBlank();
2187 var sep = jekyllStyle ? '=' : ':';
2188 if (this.peek() === sep) {
2189 ++this.p;
2190 value = this.readValue();
2191 }
2192 return new HashToken(this.input, begin, this.p, name, value, this.file);
2193 };
2194 Tokenizer.prototype.remaining = function () {
2195 return this.input.slice(this.p);
2196 };
2197 Tokenizer.prototype.advance = function (i) {
2198 if (i === void 0) { i = 1; }
2199 this.p += i;
2200 };
2201 Tokenizer.prototype.end = function () {
2202 return this.p >= this.N;
2203 };
2204 Tokenizer.prototype.readTo = function (end) {
2205 while (this.p < this.N) {
2206 ++this.p;
2207 if (this.rmatch(end))
2208 return this.p;
2209 }
2210 return -1;
2211 };
2212 Tokenizer.prototype.readValue = function () {
2213 var value = this.readQuoted() || this.readRange();
2214 if (value)
2215 return value;
2216 if (this.peek() === '[') {
2217 this.p++;
2218 var prop = this.readQuoted();
2219 if (!prop)
2220 return;
2221 if (this.peek() !== ']')
2222 return;
2223 this.p++;
2224 return new PropertyAccessToken(prop, [], this.p);
2225 }
2226 var variable = this.readIdentifier();
2227 if (!variable.size())
2228 return;
2229 var isNumber = variable.isNumber(true);
2230 var props = [];
2231 while (true) {
2232 if (this.peek() === '[') {
2233 isNumber = false;
2234 this.p++;
2235 var prop = this.readValue() || new IdentifierToken(this.input, this.p, this.p, this.file);
2236 this.readTo(']');
2237 props.push(prop);
2238 }
2239 else if (this.peek() === '.' && this.peek(1) !== '.') { // skip range syntax
2240 this.p++;
2241 var prop = this.readIdentifier();
2242 if (!prop.size())
2243 break;
2244 if (!prop.isNumber())
2245 isNumber = false;
2246 props.push(prop);
2247 }
2248 else
2249 break;
2250 }
2251 if (!props.length && literalValues.hasOwnProperty(variable.content)) {
2252 return new LiteralToken(this.input, variable.begin, variable.end, this.file);
2253 }
2254 if (isNumber)
2255 return new NumberToken(variable, props[0]);
2256 return new PropertyAccessToken(variable, props, this.p);
2257 };
2258 Tokenizer.prototype.readRange = function () {
2259 this.skipBlank();
2260 var begin = this.p;
2261 if (this.peek() !== '(')
2262 return;
2263 ++this.p;
2264 var lhs = this.readValueOrThrow();
2265 this.p += 2;
2266 var rhs = this.readValueOrThrow();
2267 ++this.p;
2268 return new RangeToken(this.input, begin, this.p, lhs, rhs, this.file);
2269 };
2270 Tokenizer.prototype.readValueOrThrow = function () {
2271 var _this = this;
2272 var value = this.readValue();
2273 assert(value, function () { return "unexpected token ".concat(_this.snapshot(), ", value expected"); });
2274 return value;
2275 };
2276 Tokenizer.prototype.readQuoted = function () {
2277 this.skipBlank();
2278 var begin = this.p;
2279 if (!(this.peekType() & QUOTE))
2280 return;
2281 ++this.p;
2282 var escaped = false;
2283 while (this.p < this.N) {
2284 ++this.p;
2285 if (this.input[this.p - 1] === this.input[begin] && !escaped)
2286 break;
2287 if (escaped)
2288 escaped = false;
2289 else if (this.input[this.p - 1] === '\\')
2290 escaped = true;
2291 }
2292 return new QuotedToken(this.input, begin, this.p, this.file);
2293 };
2294 Tokenizer.prototype.readFileNameTemplate = function (options) {
2295 var outputDelimiterLeft, htmlStopStrings, htmlStopStringSet;
2296 return __generator(this, function (_a) {
2297 switch (_a.label) {
2298 case 0:
2299 outputDelimiterLeft = options.outputDelimiterLeft;
2300 htmlStopStrings = [',', ' ', outputDelimiterLeft];
2301 htmlStopStringSet = new Set(htmlStopStrings);
2302 _a.label = 1;
2303 case 1:
2304 if (!(this.p < this.N && !htmlStopStringSet.has(this.peek()))) return [3 /*break*/, 3];
2305 return [4 /*yield*/, this.match(outputDelimiterLeft)
2306 ? this.readOutputToken(options)
2307 : this.readHTMLToken(htmlStopStrings)];
2308 case 2:
2309 _a.sent();
2310 return [3 /*break*/, 1];
2311 case 3: return [2 /*return*/];
2312 }
2313 });
2314 };
2315 Tokenizer.prototype.match = function (word) {
2316 for (var i = 0; i < word.length; i++) {
2317 if (word[i] !== this.input[this.p + i])
2318 return false;
2319 }
2320 return true;
2321 };
2322 Tokenizer.prototype.rmatch = function (pattern) {
2323 for (var i = 0; i < pattern.length; i++) {
2324 if (pattern[pattern.length - 1 - i] !== this.input[this.p - 1 - i])
2325 return false;
2326 }
2327 return true;
2328 };
2329 Tokenizer.prototype.peekType = function (n) {
2330 if (n === void 0) { n = 0; }
2331 return TYPES[this.input.charCodeAt(this.p + n)];
2332 };
2333 Tokenizer.prototype.peek = function (n) {
2334 if (n === void 0) { n = 0; }
2335 return this.input[this.p + n];
2336 };
2337 Tokenizer.prototype.skipBlank = function () {
2338 while (this.peekType() & BLANK)
2339 ++this.p;
2340 };
2341 return Tokenizer;
2342}());
2343
2344var TagToken = /** @class */ (function (_super) {
2345 __extends(TagToken, _super);
2346 function TagToken(input, begin, end, options, file) {
2347 var _this = this;
2348 var trimTagLeft = options.trimTagLeft, trimTagRight = options.trimTagRight, tagDelimiterLeft = options.tagDelimiterLeft, tagDelimiterRight = options.tagDelimiterRight;
2349 var value = input.slice(begin + tagDelimiterLeft.length, end - tagDelimiterRight.length);
2350 _this = _super.call(this, exports.TokenKind.Tag, value, input, begin, end, trimTagLeft, trimTagRight, file) || this;
2351 var tokenizer = new Tokenizer(_this.content, options.operatorsTrie);
2352 _this.name = tokenizer.readTagName();
2353 if (!_this.name)
2354 throw new TokenizationError("illegal tag syntax", _this);
2355 tokenizer.skipBlank();
2356 _this.args = tokenizer.remaining();
2357 return _this;
2358 }
2359 return TagToken;
2360}(DelimitedToken));
2361
2362var ParseStream = /** @class */ (function () {
2363 function ParseStream(tokens, parseToken) {
2364 this.handlers = {};
2365 this.stopRequested = false;
2366 this.tokens = tokens;
2367 this.parseToken = parseToken;
2368 }
2369 ParseStream.prototype.on = function (name, cb) {
2370 this.handlers[name] = cb;
2371 return this;
2372 };
2373 ParseStream.prototype.trigger = function (event, arg) {
2374 var h = this.handlers[event];
2375 return h ? (h.call(this, arg), true) : false;
2376 };
2377 ParseStream.prototype.start = function () {
2378 this.trigger('start');
2379 var token;
2380 while (!this.stopRequested && (token = this.tokens.shift())) {
2381 if (this.trigger('token', token))
2382 continue;
2383 if (isTagToken(token) && this.trigger("tag:".concat(token.name), token)) {
2384 continue;
2385 }
2386 var template = this.parseToken(token, this.tokens);
2387 this.trigger('template', template);
2388 }
2389 if (!this.stopRequested)
2390 this.trigger('end');
2391 return this;
2392 };
2393 ParseStream.prototype.stop = function () {
2394 this.stopRequested = true;
2395 return this;
2396 };
2397 return ParseStream;
2398}());
2399
2400/**
2401 * Key-Value Pairs Representing Tag Arguments
2402 * Example:
2403 * For the markup `, foo:'bar', coo:2 reversed %}`,
2404 * hash['foo'] === 'bar'
2405 * hash['coo'] === 2
2406 * hash['reversed'] === undefined
2407 */
2408var Hash = /** @class */ (function () {
2409 function Hash(markup, jekyllStyle) {
2410 var e_1, _a;
2411 this.hash = {};
2412 var tokenizer = new Tokenizer(markup, {});
2413 try {
2414 for (var _b = __values(tokenizer.readHashes(jekyllStyle)), _c = _b.next(); !_c.done; _c = _b.next()) {
2415 var hash = _c.value;
2416 this.hash[hash.name.content] = hash.value;
2417 }
2418 }
2419 catch (e_1_1) { e_1 = { error: e_1_1 }; }
2420 finally {
2421 try {
2422 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2423 }
2424 finally { if (e_1) throw e_1.error; }
2425 }
2426 }
2427 Hash.prototype.render = function (ctx) {
2428 var hash, _a, _b, key, _c, _d, _e, e_2_1;
2429 var e_2, _f;
2430 return __generator(this, function (_g) {
2431 switch (_g.label) {
2432 case 0:
2433 hash = {};
2434 _g.label = 1;
2435 case 1:
2436 _g.trys.push([1, 8, 9, 10]);
2437 _a = __values(Object.keys(this.hash)), _b = _a.next();
2438 _g.label = 2;
2439 case 2:
2440 if (!!_b.done) return [3 /*break*/, 7];
2441 key = _b.value;
2442 _c = hash;
2443 _d = key;
2444 if (!(this.hash[key] === undefined)) return [3 /*break*/, 3];
2445 _e = true;
2446 return [3 /*break*/, 5];
2447 case 3: return [4 /*yield*/, evalToken(this.hash[key], ctx)];
2448 case 4:
2449 _e = _g.sent();
2450 _g.label = 5;
2451 case 5:
2452 _c[_d] = _e;
2453 _g.label = 6;
2454 case 6:
2455 _b = _a.next();
2456 return [3 /*break*/, 2];
2457 case 7: return [3 /*break*/, 10];
2458 case 8:
2459 e_2_1 = _g.sent();
2460 e_2 = { error: e_2_1 };
2461 return [3 /*break*/, 10];
2462 case 9:
2463 try {
2464 if (_b && !_b.done && (_f = _a.return)) _f.call(_a);
2465 }
2466 finally { if (e_2) throw e_2.error; }
2467 return [7 /*endfinally*/];
2468 case 10: return [2 /*return*/, hash];
2469 }
2470 });
2471 };
2472 return Hash;
2473}());
2474
2475function isKeyValuePair(arr) {
2476 return isArray(arr);
2477}
2478
2479var Filter = /** @class */ (function () {
2480 function Filter(name, impl, args, liquid) {
2481 this.name = name;
2482 this.impl = impl || identify;
2483 this.args = args;
2484 this.liquid = liquid;
2485 }
2486 Filter.prototype.render = function (value, context) {
2487 var e_1, _a;
2488 var argv = [];
2489 try {
2490 for (var _b = __values(this.args), _c = _b.next(); !_c.done; _c = _b.next()) {
2491 var arg = _c.value;
2492 if (isKeyValuePair(arg))
2493 argv.push([arg[0], evalToken(arg[1], context)]);
2494 else
2495 argv.push(evalToken(arg, context));
2496 }
2497 }
2498 catch (e_1_1) { e_1 = { error: e_1_1 }; }
2499 finally {
2500 try {
2501 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2502 }
2503 finally { if (e_1) throw e_1.error; }
2504 }
2505 return this.impl.apply({ context: context, liquid: this.liquid }, __spreadArray([value], __read(argv), false));
2506 };
2507 return Filter;
2508}());
2509
2510var Value = /** @class */ (function () {
2511 /**
2512 * @param str the value to be valuated, eg.: "foobar" | truncate: 3
2513 */
2514 function Value(str, liquid) {
2515 this.filters = [];
2516 var tokenizer = new Tokenizer(str, liquid.options.operatorsTrie);
2517 this.initial = tokenizer.readExpression();
2518 this.filters = tokenizer.readFilters().map(function (_a) {
2519 var name = _a.name, args = _a.args;
2520 return new Filter(name, liquid.filters.get(name), args, liquid);
2521 });
2522 }
2523 Value.prototype.value = function (ctx, lenient) {
2524 var val, _a, _b, filter, e_1_1;
2525 var e_1, _c;
2526 return __generator(this, function (_d) {
2527 switch (_d.label) {
2528 case 0:
2529 lenient = lenient || (ctx.opts.lenientIf && this.filters.length > 0 && this.filters[0].name === 'default');
2530 return [4 /*yield*/, this.initial.evaluate(ctx, lenient)];
2531 case 1:
2532 val = _d.sent();
2533 _d.label = 2;
2534 case 2:
2535 _d.trys.push([2, 7, 8, 9]);
2536 _a = __values(this.filters), _b = _a.next();
2537 _d.label = 3;
2538 case 3:
2539 if (!!_b.done) return [3 /*break*/, 6];
2540 filter = _b.value;
2541 return [4 /*yield*/, filter.render(val, ctx)];
2542 case 4:
2543 val = _d.sent();
2544 _d.label = 5;
2545 case 5:
2546 _b = _a.next();
2547 return [3 /*break*/, 3];
2548 case 6: return [3 /*break*/, 9];
2549 case 7:
2550 e_1_1 = _d.sent();
2551 e_1 = { error: e_1_1 };
2552 return [3 /*break*/, 9];
2553 case 8:
2554 try {
2555 if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
2556 }
2557 finally { if (e_1) throw e_1.error; }
2558 return [7 /*endfinally*/];
2559 case 9: return [2 /*return*/, val];
2560 }
2561 });
2562 };
2563 return Value;
2564}());
2565
2566// convert an async iterator to a Promise
2567function toPromise(val) {
2568 return __awaiter(this, void 0, void 0, function () {
2569 var value, done, next, state, err_1;
2570 return __generator(this, function (_a) {
2571 switch (_a.label) {
2572 case 0:
2573 if (!isIterator(val))
2574 return [2 /*return*/, val];
2575 done = false;
2576 next = 'next';
2577 _a.label = 1;
2578 case 1:
2579 state = val[next](value);
2580 done = state.done;
2581 value = state.value;
2582 next = 'next';
2583 _a.label = 2;
2584 case 2:
2585 _a.trys.push([2, 5, , 6]);
2586 if (isIterator(value))
2587 value = toPromise(value);
2588 if (!isPromise(value)) return [3 /*break*/, 4];
2589 return [4 /*yield*/, value];
2590 case 3:
2591 value = _a.sent();
2592 _a.label = 4;
2593 case 4: return [3 /*break*/, 6];
2594 case 5:
2595 err_1 = _a.sent();
2596 next = 'throw';
2597 value = err_1;
2598 return [3 /*break*/, 6];
2599 case 6:
2600 if (!done) return [3 /*break*/, 1];
2601 _a.label = 7;
2602 case 7: return [2 /*return*/, value];
2603 }
2604 });
2605 });
2606}
2607// convert an async iterator to a value in a synchronous manner
2608function toValueSync(val) {
2609 if (!isIterator(val))
2610 return val;
2611 var value;
2612 var done = false;
2613 var next = 'next';
2614 do {
2615 var state = val[next](value);
2616 done = state.done;
2617 value = state.value;
2618 next = 'next';
2619 if (isIterator(value)) {
2620 try {
2621 value = toValueSync(value);
2622 }
2623 catch (err) {
2624 next = 'throw';
2625 value = err;
2626 }
2627 }
2628 } while (!done);
2629 return value;
2630}
2631var toThenable = toPromise;
2632
2633var assign = {
2634 parse: function (token) {
2635 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
2636 this.key = tokenizer.readIdentifier().content;
2637 tokenizer.skipBlank();
2638 assert(tokenizer.peek() === '=', function () { return "illegal token ".concat(token.getText()); });
2639 tokenizer.advance();
2640 this.value = new Value(tokenizer.remaining(), this.liquid);
2641 },
2642 render: function (ctx) {
2643 var _a, _b;
2644 return __generator(this, function (_c) {
2645 switch (_c.label) {
2646 case 0:
2647 _a = ctx.bottom();
2648 _b = this.key;
2649 return [4 /*yield*/, this.value.value(ctx, this.liquid.options.lenientIf)];
2650 case 1:
2651 _a[_b] = _c.sent();
2652 return [2 /*return*/];
2653 }
2654 });
2655 }
2656};
2657
2658var ForloopDrop = /** @class */ (function (_super) {
2659 __extends(ForloopDrop, _super);
2660 function ForloopDrop(length, collection, variable) {
2661 var _this = _super.call(this) || this;
2662 _this.i = 0;
2663 _this.length = length;
2664 _this.name = "".concat(variable, "-").concat(collection);
2665 return _this;
2666 }
2667 ForloopDrop.prototype.next = function () {
2668 this.i++;
2669 };
2670 ForloopDrop.prototype.index0 = function () {
2671 return this.i;
2672 };
2673 ForloopDrop.prototype.index = function () {
2674 return this.i + 1;
2675 };
2676 ForloopDrop.prototype.first = function () {
2677 return this.i === 0;
2678 };
2679 ForloopDrop.prototype.last = function () {
2680 return this.i === this.length - 1;
2681 };
2682 ForloopDrop.prototype.rindex = function () {
2683 return this.length - this.i;
2684 };
2685 ForloopDrop.prototype.rindex0 = function () {
2686 return this.length - this.i - 1;
2687 };
2688 ForloopDrop.prototype.valueOf = function () {
2689 return JSON.stringify(this);
2690 };
2691 return ForloopDrop;
2692}(Drop));
2693
2694var MODIFIERS = ['offset', 'limit', 'reversed'];
2695var For = {
2696 type: 'block',
2697 parse: function (token, remainTokens) {
2698 var _this = this;
2699 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
2700 var variable = tokenizer.readIdentifier();
2701 var inStr = tokenizer.readIdentifier();
2702 var collection = tokenizer.readValue();
2703 assert(variable.size() && inStr.content === 'in' && collection, function () { return "illegal tag: ".concat(token.getText()); });
2704 this.variable = variable.content;
2705 this.collection = collection;
2706 this.hash = new Hash(tokenizer.remaining());
2707 this.templates = [];
2708 this.elseTemplates = [];
2709 var p;
2710 var stream = this.liquid.parser.parseStream(remainTokens)
2711 .on('start', function () { return (p = _this.templates); })
2712 .on('tag:else', function () { return (p = _this.elseTemplates); })
2713 .on('tag:endfor', function () { return stream.stop(); })
2714 .on('template', function (tpl) { return p.push(tpl); })
2715 .on('end', function () {
2716 throw new Error("tag ".concat(token.getText(), " not closed"));
2717 });
2718 stream.start();
2719 },
2720 render: function (ctx, emitter) {
2721 var r, collection, _a, continueKey, hash, modifiers, scope, collection_1, collection_1_1, item, e_1_1;
2722 var e_1, _b;
2723 return __generator(this, function (_c) {
2724 switch (_c.label) {
2725 case 0:
2726 r = this.liquid.renderer;
2727 _a = toEnumerable;
2728 return [4 /*yield*/, evalToken(this.collection, ctx)];
2729 case 1:
2730 collection = _a.apply(void 0, [_c.sent()]);
2731 if (!!collection.length) return [3 /*break*/, 3];
2732 return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
2733 case 2:
2734 _c.sent();
2735 return [2 /*return*/];
2736 case 3:
2737 continueKey = 'continue-' + this.variable + '-' + this.collection.getText();
2738 ctx.push({ continue: ctx.getRegister(continueKey) });
2739 return [4 /*yield*/, this.hash.render(ctx)];
2740 case 4:
2741 hash = _c.sent();
2742 ctx.pop();
2743 modifiers = this.liquid.options.orderedFilterParameters
2744 ? Object.keys(hash).filter(function (x) { return MODIFIERS.includes(x); })
2745 : MODIFIERS.filter(function (x) { return hash[x] !== undefined; });
2746 collection = modifiers.reduce(function (collection, modifier) {
2747 if (modifier === 'offset')
2748 return offset(collection, hash['offset']);
2749 if (modifier === 'limit')
2750 return limit(collection, hash['limit']);
2751 return reversed(collection);
2752 }, collection);
2753 ctx.setRegister(continueKey, (hash['offset'] || 0) + collection.length);
2754 scope = { forloop: new ForloopDrop(collection.length, this.collection.getText(), this.variable) };
2755 ctx.push(scope);
2756 _c.label = 5;
2757 case 5:
2758 _c.trys.push([5, 10, 11, 12]);
2759 collection_1 = __values(collection), collection_1_1 = collection_1.next();
2760 _c.label = 6;
2761 case 6:
2762 if (!!collection_1_1.done) return [3 /*break*/, 9];
2763 item = collection_1_1.value;
2764 scope[this.variable] = item;
2765 return [4 /*yield*/, r.renderTemplates(this.templates, ctx, emitter)];
2766 case 7:
2767 _c.sent();
2768 if (emitter['break']) {
2769 emitter['break'] = false;
2770 return [3 /*break*/, 9];
2771 }
2772 emitter['continue'] = false;
2773 scope.forloop.next();
2774 _c.label = 8;
2775 case 8:
2776 collection_1_1 = collection_1.next();
2777 return [3 /*break*/, 6];
2778 case 9: return [3 /*break*/, 12];
2779 case 10:
2780 e_1_1 = _c.sent();
2781 e_1 = { error: e_1_1 };
2782 return [3 /*break*/, 12];
2783 case 11:
2784 try {
2785 if (collection_1_1 && !collection_1_1.done && (_b = collection_1.return)) _b.call(collection_1);
2786 }
2787 finally { if (e_1) throw e_1.error; }
2788 return [7 /*endfinally*/];
2789 case 12:
2790 ctx.pop();
2791 return [2 /*return*/];
2792 }
2793 });
2794 }
2795};
2796function reversed(arr) {
2797 return __spreadArray([], __read(arr), false).reverse();
2798}
2799function offset(arr, count) {
2800 return arr.slice(count);
2801}
2802function limit(arr, count) {
2803 return arr.slice(0, count);
2804}
2805
2806var capture = {
2807 parse: function (tagToken, remainTokens) {
2808 var _this = this;
2809 var tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operatorsTrie);
2810 this.variable = readVariableName(tokenizer);
2811 assert(this.variable, function () { return "".concat(tagToken.args, " not valid identifier"); });
2812 this.templates = [];
2813 var stream = this.liquid.parser.parseStream(remainTokens);
2814 stream.on('tag:endcapture', function () { return stream.stop(); })
2815 .on('template', function (tpl) { return _this.templates.push(tpl); })
2816 .on('end', function () {
2817 throw new Error("tag ".concat(tagToken.getText(), " not closed"));
2818 });
2819 stream.start();
2820 },
2821 render: function (ctx) {
2822 var r, html;
2823 return __generator(this, function (_a) {
2824 switch (_a.label) {
2825 case 0:
2826 r = this.liquid.renderer;
2827 return [4 /*yield*/, r.renderTemplates(this.templates, ctx)];
2828 case 1:
2829 html = _a.sent();
2830 ctx.bottom()[this.variable] = html;
2831 return [2 /*return*/];
2832 }
2833 });
2834 }
2835};
2836function readVariableName(tokenizer) {
2837 var word = tokenizer.readIdentifier().content;
2838 if (word)
2839 return word;
2840 var quoted = tokenizer.readQuoted();
2841 if (quoted)
2842 return evalQuotedToken(quoted);
2843}
2844
2845var Case = {
2846 parse: function (tagToken, remainTokens) {
2847 var _this = this;
2848 this.cond = new Value(tagToken.args, this.liquid);
2849 this.cases = [];
2850 this.elseTemplates = [];
2851 var p = [];
2852 var stream = this.liquid.parser.parseStream(remainTokens)
2853 .on('tag:when', function (token) {
2854 p = [];
2855 var tokenizer = new Tokenizer(token.args, _this.liquid.options.operatorsTrie);
2856 while (!tokenizer.end()) {
2857 var value = tokenizer.readValue();
2858 _this.cases.push({
2859 val: value,
2860 templates: p
2861 });
2862 tokenizer.readTo(',');
2863 }
2864 })
2865 .on('tag:else', function () { return (p = _this.elseTemplates); })
2866 .on('tag:endcase', function () { return stream.stop(); })
2867 .on('template', function (tpl) { return p.push(tpl); })
2868 .on('end', function () {
2869 throw new Error("tag ".concat(tagToken.getText(), " not closed"));
2870 });
2871 stream.start();
2872 },
2873 render: function (ctx, emitter) {
2874 var r, cond, _a, _b, _c, branch, val, e_1_1;
2875 var e_1, _d;
2876 return __generator(this, function (_e) {
2877 switch (_e.label) {
2878 case 0:
2879 r = this.liquid.renderer;
2880 _a = toValue;
2881 return [4 /*yield*/, this.cond.value(ctx, ctx.opts.lenientIf)];
2882 case 1:
2883 cond = _a.apply(void 0, [_e.sent()]);
2884 _e.label = 2;
2885 case 2:
2886 _e.trys.push([2, 7, 8, 9]);
2887 _b = __values(this.cases), _c = _b.next();
2888 _e.label = 3;
2889 case 3:
2890 if (!!_c.done) return [3 /*break*/, 6];
2891 branch = _c.value;
2892 val = evalToken(branch.val, ctx, ctx.opts.lenientIf);
2893 if (!(val === cond)) return [3 /*break*/, 5];
2894 return [4 /*yield*/, r.renderTemplates(branch.templates, ctx, emitter)];
2895 case 4:
2896 _e.sent();
2897 return [2 /*return*/];
2898 case 5:
2899 _c = _b.next();
2900 return [3 /*break*/, 3];
2901 case 6: return [3 /*break*/, 9];
2902 case 7:
2903 e_1_1 = _e.sent();
2904 e_1 = { error: e_1_1 };
2905 return [3 /*break*/, 9];
2906 case 8:
2907 try {
2908 if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
2909 }
2910 finally { if (e_1) throw e_1.error; }
2911 return [7 /*endfinally*/];
2912 case 9: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
2913 case 10:
2914 _e.sent();
2915 return [2 /*return*/];
2916 }
2917 });
2918 }
2919};
2920
2921var comment = {
2922 parse: function (tagToken, remainTokens) {
2923 var stream = this.liquid.parser.parseStream(remainTokens);
2924 stream
2925 .on('token', function (token) {
2926 if (token.name === 'endcomment')
2927 stream.stop();
2928 })
2929 .on('end', function () {
2930 throw new Error("tag ".concat(tagToken.getText(), " not closed"));
2931 });
2932 stream.start();
2933 }
2934};
2935
2936var BlockMode;
2937(function (BlockMode) {
2938 /* store rendered html into blocks */
2939 BlockMode[BlockMode["OUTPUT"] = 0] = "OUTPUT";
2940 /* output rendered html directly */
2941 BlockMode[BlockMode["STORE"] = 1] = "STORE";
2942})(BlockMode || (BlockMode = {}));
2943var BlockMode$1 = BlockMode;
2944
2945var render = {
2946 parseFilePath: parseFilePath,
2947 renderFilePath: renderFilePath,
2948 parse: function (token) {
2949 var args = token.args;
2950 var tokenizer = new Tokenizer(args, this.liquid.options.operatorsTrie);
2951 this['file'] = this.parseFilePath(tokenizer, this.liquid);
2952 this['currentFile'] = token.file;
2953 while (!tokenizer.end()) {
2954 tokenizer.skipBlank();
2955 var begin = tokenizer.p;
2956 var keyword = tokenizer.readIdentifier();
2957 if (keyword.content === 'with' || keyword.content === 'for') {
2958 tokenizer.skipBlank();
2959 // can be normal key/value pair, like "with: true"
2960 if (tokenizer.peek() !== ':') {
2961 var value = tokenizer.readValue();
2962 // can be normal key, like "with,"
2963 if (value) {
2964 var beforeAs = tokenizer.p;
2965 var asStr = tokenizer.readIdentifier();
2966 var alias = void 0;
2967 if (asStr.content === 'as')
2968 alias = tokenizer.readIdentifier();
2969 else
2970 tokenizer.p = beforeAs;
2971 this[keyword.content] = { value: value, alias: alias && alias.content };
2972 tokenizer.skipBlank();
2973 if (tokenizer.peek() === ',')
2974 tokenizer.advance();
2975 // matched!
2976 continue;
2977 }
2978 }
2979 }
2980 /**
2981 * restore cursor if with/for not matched
2982 */
2983 tokenizer.p = begin;
2984 break;
2985 }
2986 this.hash = new Hash(tokenizer.remaining());
2987 },
2988 render: function (ctx, emitter) {
2989 var _a, liquid, hash, filepath, childCtx, scope, _b, _c, _d, value, alias, _e, value, alias, collection, collection_1, collection_1_1, item, templates, e_1_1, templates;
2990 var e_1, _f;
2991 return __generator(this, function (_g) {
2992 switch (_g.label) {
2993 case 0:
2994 _a = this, liquid = _a.liquid, hash = _a.hash;
2995 return [4 /*yield*/, this.renderFilePath(this['file'], ctx, liquid)];
2996 case 1:
2997 filepath = _g.sent();
2998 assert(filepath, function () { return "illegal filename \"".concat(filepath, "\""); });
2999 childCtx = new Context({}, ctx.opts, { sync: ctx.sync, globals: ctx.globals, strictVariables: ctx.strictVariables });
3000 scope = childCtx.bottom();
3001 _b = __assign;
3002 _c = [scope];
3003 return [4 /*yield*/, hash.render(ctx)];
3004 case 2:
3005 _b.apply(void 0, _c.concat([_g.sent()]));
3006 if (this['with']) {
3007 _d = this['with'], value = _d.value, alias = _d.alias;
3008 scope[alias || filepath] = evalToken(value, ctx);
3009 }
3010 if (!this['for']) return [3 /*break*/, 12];
3011 _e = this['for'], value = _e.value, alias = _e.alias;
3012 collection = evalToken(value, ctx);
3013 collection = toEnumerable(collection);
3014 scope['forloop'] = new ForloopDrop(collection.length, value.getText(), alias);
3015 _g.label = 3;
3016 case 3:
3017 _g.trys.push([3, 9, 10, 11]);
3018 collection_1 = __values(collection), collection_1_1 = collection_1.next();
3019 _g.label = 4;
3020 case 4:
3021 if (!!collection_1_1.done) return [3 /*break*/, 8];
3022 item = collection_1_1.value;
3023 scope[alias] = item;
3024 return [4 /*yield*/, liquid._parsePartialFile(filepath, childCtx.sync, this['currentFile'])];
3025 case 5:
3026 templates = _g.sent();
3027 return [4 /*yield*/, liquid.renderer.renderTemplates(templates, childCtx, emitter)];
3028 case 6:
3029 _g.sent();
3030 scope['forloop'].next();
3031 _g.label = 7;
3032 case 7:
3033 collection_1_1 = collection_1.next();
3034 return [3 /*break*/, 4];
3035 case 8: return [3 /*break*/, 11];
3036 case 9:
3037 e_1_1 = _g.sent();
3038 e_1 = { error: e_1_1 };
3039 return [3 /*break*/, 11];
3040 case 10:
3041 try {
3042 if (collection_1_1 && !collection_1_1.done && (_f = collection_1.return)) _f.call(collection_1);
3043 }
3044 finally { if (e_1) throw e_1.error; }
3045 return [7 /*endfinally*/];
3046 case 11: return [3 /*break*/, 15];
3047 case 12: return [4 /*yield*/, liquid._parsePartialFile(filepath, childCtx.sync, this['currentFile'])];
3048 case 13:
3049 templates = _g.sent();
3050 return [4 /*yield*/, liquid.renderer.renderTemplates(templates, childCtx, emitter)];
3051 case 14:
3052 _g.sent();
3053 _g.label = 15;
3054 case 15: return [2 /*return*/];
3055 }
3056 });
3057 }
3058};
3059/**
3060 * @return null for "none",
3061 * @return Template[] for quoted with tags and/or filters
3062 * @return Token for expression (not quoted)
3063 * @throws TypeError if cannot read next token
3064 */
3065function parseFilePath(tokenizer, liquid) {
3066 if (liquid.options.dynamicPartials) {
3067 var file = tokenizer.readValue();
3068 if (file === undefined)
3069 throw new TypeError("illegal argument \"".concat(tokenizer.input, "\""));
3070 if (file.getText() === 'none')
3071 return null;
3072 if (isQuotedToken(file)) {
3073 // for filenames like "files/{{file}}", eval as liquid template
3074 var templates_1 = liquid.parse(evalQuotedToken(file));
3075 return optimize(templates_1);
3076 }
3077 return file;
3078 }
3079 var tokens = __spreadArray([], __read(tokenizer.readFileNameTemplate(liquid.options)), false);
3080 var templates = optimize(liquid.parser.parseTokens(tokens));
3081 return templates === 'none' ? null : templates;
3082}
3083function optimize(templates) {
3084 // for filenames like "files/file.liquid", extract the string directly
3085 if (templates.length === 1 && isHTMLToken(templates[0].token))
3086 return templates[0].token.getContent();
3087 return templates;
3088}
3089function renderFilePath(file, ctx, liquid) {
3090 if (typeof file === 'string')
3091 return file;
3092 if (Array.isArray(file))
3093 return liquid.renderer.renderTemplates(file, ctx);
3094 return evalToken(file, ctx);
3095}
3096
3097var include = {
3098 parseFilePath: parseFilePath,
3099 renderFilePath: renderFilePath,
3100 parse: function (token) {
3101 var args = token.args;
3102 var tokenizer = new Tokenizer(args, this.liquid.options.operatorsTrie);
3103 this['file'] = this.parseFilePath(tokenizer, this.liquid);
3104 this['currentFile'] = token.file;
3105 var begin = tokenizer.p;
3106 var withStr = tokenizer.readIdentifier();
3107 if (withStr.content === 'with') {
3108 tokenizer.skipBlank();
3109 if (tokenizer.peek() !== ':') {
3110 this.withVar = tokenizer.readValue();
3111 }
3112 else
3113 tokenizer.p = begin;
3114 }
3115 else
3116 tokenizer.p = begin;
3117 this.hash = new Hash(tokenizer.remaining(), this.liquid.options.jekyllInclude);
3118 },
3119 render: function (ctx, emitter) {
3120 var _a, liquid, hash, withVar, renderer, filepath, saved, scope, templates;
3121 return __generator(this, function (_b) {
3122 switch (_b.label) {
3123 case 0:
3124 _a = this, liquid = _a.liquid, hash = _a.hash, withVar = _a.withVar;
3125 renderer = liquid.renderer;
3126 return [4 /*yield*/, this.renderFilePath(this['file'], ctx, liquid)];
3127 case 1:
3128 filepath = _b.sent();
3129 assert(filepath, function () { return "illegal filename \"".concat(filepath, "\""); });
3130 saved = ctx.saveRegister('blocks', 'blockMode');
3131 ctx.setRegister('blocks', {});
3132 ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
3133 return [4 /*yield*/, hash.render(ctx)];
3134 case 2:
3135 scope = _b.sent();
3136 if (withVar)
3137 scope[filepath] = evalToken(withVar, ctx);
3138 return [4 /*yield*/, liquid._parsePartialFile(filepath, ctx.sync, this['currentFile'])];
3139 case 3:
3140 templates = _b.sent();
3141 ctx.push(ctx.opts.jekyllInclude ? { include: scope } : scope);
3142 return [4 /*yield*/, renderer.renderTemplates(templates, ctx, emitter)];
3143 case 4:
3144 _b.sent();
3145 ctx.pop();
3146 ctx.restoreRegister(saved);
3147 return [2 /*return*/];
3148 }
3149 });
3150 }
3151};
3152
3153var decrement = {
3154 parse: function (token) {
3155 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
3156 this.variable = tokenizer.readIdentifier().content;
3157 },
3158 render: function (context, emitter) {
3159 var scope = context.environments;
3160 if (!isNumber(scope[this.variable])) {
3161 scope[this.variable] = 0;
3162 }
3163 emitter.write(stringify(--scope[this.variable]));
3164 }
3165};
3166
3167var cycle = {
3168 parse: function (tagToken) {
3169 var tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operatorsTrie);
3170 var group = tokenizer.readValue();
3171 tokenizer.skipBlank();
3172 this.candidates = [];
3173 if (group) {
3174 if (tokenizer.peek() === ':') {
3175 this.group = group;
3176 tokenizer.advance();
3177 }
3178 else
3179 this.candidates.push(group);
3180 }
3181 while (!tokenizer.end()) {
3182 var value = tokenizer.readValue();
3183 if (value)
3184 this.candidates.push(value);
3185 tokenizer.readTo(',');
3186 }
3187 assert(this.candidates.length, function () { return "empty candidates: ".concat(tagToken.getText()); });
3188 },
3189 render: function (ctx, emitter) {
3190 var group = evalToken(this.group, ctx);
3191 var fingerprint = "cycle:".concat(group, ":") + this.candidates.join(',');
3192 var groups = ctx.getRegister('cycle');
3193 var idx = groups[fingerprint];
3194 if (idx === undefined) {
3195 idx = groups[fingerprint] = 0;
3196 }
3197 var candidate = this.candidates[idx];
3198 idx = (idx + 1) % this.candidates.length;
3199 groups[fingerprint] = idx;
3200 var html = evalToken(candidate, ctx);
3201 emitter.write(html);
3202 }
3203};
3204
3205var If = {
3206 parse: function (tagToken, remainTokens) {
3207 var _this = this;
3208 this.branches = [];
3209 this.elseTemplates = [];
3210 var p;
3211 this.liquid.parser.parseStream(remainTokens)
3212 .on('start', function () { return _this.branches.push({
3213 predicate: new Value(tagToken.args, _this.liquid),
3214 templates: (p = [])
3215 }); })
3216 .on('tag:elsif', function (token) { return _this.branches.push({
3217 predicate: new Value(token.args, _this.liquid),
3218 templates: (p = [])
3219 }); })
3220 .on('tag:else', function () { return (p = _this.elseTemplates); })
3221 .on('tag:endif', function () { this.stop(); })
3222 .on('template', function (tpl) { return p.push(tpl); })
3223 .on('end', function () { throw new Error("tag ".concat(tagToken.getText(), " not closed")); })
3224 .start();
3225 },
3226 render: function (ctx, emitter) {
3227 var r, _a, _b, _c, predicate, templates, value, e_1_1;
3228 var e_1, _d;
3229 return __generator(this, function (_e) {
3230 switch (_e.label) {
3231 case 0:
3232 r = this.liquid.renderer;
3233 _e.label = 1;
3234 case 1:
3235 _e.trys.push([1, 7, 8, 9]);
3236 _a = __values(this.branches), _b = _a.next();
3237 _e.label = 2;
3238 case 2:
3239 if (!!_b.done) return [3 /*break*/, 6];
3240 _c = _b.value, predicate = _c.predicate, templates = _c.templates;
3241 return [4 /*yield*/, predicate.value(ctx, ctx.opts.lenientIf)];
3242 case 3:
3243 value = _e.sent();
3244 if (!isTruthy(value, ctx)) return [3 /*break*/, 5];
3245 return [4 /*yield*/, r.renderTemplates(templates, ctx, emitter)];
3246 case 4:
3247 _e.sent();
3248 return [2 /*return*/];
3249 case 5:
3250 _b = _a.next();
3251 return [3 /*break*/, 2];
3252 case 6: return [3 /*break*/, 9];
3253 case 7:
3254 e_1_1 = _e.sent();
3255 e_1 = { error: e_1_1 };
3256 return [3 /*break*/, 9];
3257 case 8:
3258 try {
3259 if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
3260 }
3261 finally { if (e_1) throw e_1.error; }
3262 return [7 /*endfinally*/];
3263 case 9: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
3264 case 10:
3265 _e.sent();
3266 return [2 /*return*/];
3267 }
3268 });
3269 }
3270};
3271
3272var increment = {
3273 parse: function (token) {
3274 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
3275 this.variable = tokenizer.readIdentifier().content;
3276 },
3277 render: function (context, emitter) {
3278 var scope = context.environments;
3279 if (!isNumber(scope[this.variable])) {
3280 scope[this.variable] = 0;
3281 }
3282 var val = scope[this.variable];
3283 scope[this.variable]++;
3284 emitter.write(stringify(val));
3285 }
3286};
3287
3288var layout = {
3289 parseFilePath: parseFilePath,
3290 renderFilePath: renderFilePath,
3291 parse: function (token, remainTokens) {
3292 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
3293 this['file'] = this.parseFilePath(tokenizer, this.liquid);
3294 this['currentFile'] = token.file;
3295 this.hash = new Hash(tokenizer.remaining());
3296 this.tpls = this.liquid.parser.parseTokens(remainTokens);
3297 },
3298 render: function (ctx, emitter) {
3299 var _a, liquid, hash, file, renderer, filepath, templates, html, blocks, _b, _c;
3300 return __generator(this, function (_d) {
3301 switch (_d.label) {
3302 case 0:
3303 _a = this, liquid = _a.liquid, hash = _a.hash, file = _a.file;
3304 renderer = liquid.renderer;
3305 if (!(file === null)) return [3 /*break*/, 2];
3306 ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
3307 return [4 /*yield*/, renderer.renderTemplates(this.tpls, ctx, emitter)];
3308 case 1:
3309 _d.sent();
3310 return [2 /*return*/];
3311 case 2: return [4 /*yield*/, this.renderFilePath(this['file'], ctx, liquid)];
3312 case 3:
3313 filepath = _d.sent();
3314 assert(filepath, function () { return "illegal filename \"".concat(filepath, "\""); });
3315 return [4 /*yield*/, liquid._parseLayoutFile(filepath, ctx.sync, this['currentFile'])
3316 // render remaining contents and store rendered results
3317 ];
3318 case 4:
3319 templates = _d.sent();
3320 // render remaining contents and store rendered results
3321 ctx.setRegister('blockMode', BlockMode$1.STORE);
3322 return [4 /*yield*/, renderer.renderTemplates(this.tpls, ctx)];
3323 case 5:
3324 html = _d.sent();
3325 blocks = ctx.getRegister('blocks');
3326 // set whole content to anonymous block if anonymous doesn't specified
3327 if (blocks[''] === undefined)
3328 blocks[''] = function (parent, emitter) { return emitter.write(html); };
3329 ctx.setRegister('blockMode', BlockMode$1.OUTPUT);
3330 // render the layout file use stored blocks
3331 _c = (_b = ctx).push;
3332 return [4 /*yield*/, hash.render(ctx)];
3333 case 6:
3334 // render the layout file use stored blocks
3335 _c.apply(_b, [_d.sent()]);
3336 return [4 /*yield*/, renderer.renderTemplates(templates, ctx, emitter)];
3337 case 7:
3338 _d.sent();
3339 ctx.pop();
3340 return [2 /*return*/];
3341 }
3342 });
3343 }
3344};
3345
3346var BlockDrop = /** @class */ (function (_super) {
3347 __extends(BlockDrop, _super);
3348 function BlockDrop(
3349 // the block render from layout template
3350 superBlockRender) {
3351 if (superBlockRender === void 0) { superBlockRender = function () { return ''; }; }
3352 var _this = _super.call(this) || this;
3353 _this.superBlockRender = superBlockRender;
3354 return _this;
3355 }
3356 /**
3357 * Provide parent access in child block by
3358 * {{ block.super }}
3359 */
3360 BlockDrop.prototype.super = function () {
3361 return this.superBlockRender();
3362 };
3363 return BlockDrop;
3364}(Drop));
3365
3366var block = {
3367 parse: function (token, remainTokens) {
3368 var _this = this;
3369 var match = /\w+/.exec(token.args);
3370 this.block = match ? match[0] : '';
3371 this.tpls = [];
3372 this.liquid.parser.parseStream(remainTokens)
3373 .on('tag:endblock', function () { this.stop(); })
3374 .on('template', function (tpl) { return _this.tpls.push(tpl); })
3375 .on('end', function () { throw new Error("tag ".concat(token.getText(), " not closed")); })
3376 .start();
3377 },
3378 render: function (ctx, emitter) {
3379 var blockRender;
3380 return __generator(this, function (_a) {
3381 switch (_a.label) {
3382 case 0:
3383 blockRender = this.getBlockRender(ctx);
3384 if (!(ctx.getRegister('blockMode') === BlockMode$1.STORE)) return [3 /*break*/, 1];
3385 ctx.getRegister('blocks')[this.block] = blockRender;
3386 return [3 /*break*/, 3];
3387 case 1: return [4 /*yield*/, blockRender(new BlockDrop(), emitter)];
3388 case 2:
3389 _a.sent();
3390 _a.label = 3;
3391 case 3: return [2 /*return*/];
3392 }
3393 });
3394 },
3395 getBlockRender: function (ctx) {
3396 var _a = this, liquid = _a.liquid, tpls = _a.tpls;
3397 var renderChild = ctx.getRegister('blocks')[this.block];
3398 var renderCurrent = function (superBlock, emitter) {
3399 return __generator(this, function (_a) {
3400 switch (_a.label) {
3401 case 0:
3402 // add {{ block.super }} support when rendering
3403 ctx.push({ block: superBlock });
3404 return [4 /*yield*/, liquid.renderer.renderTemplates(tpls, ctx, emitter)];
3405 case 1:
3406 _a.sent();
3407 ctx.pop();
3408 return [2 /*return*/];
3409 }
3410 });
3411 };
3412 return renderChild
3413 ? function (superBlock, emitter) { return renderChild(new BlockDrop(function () { return renderCurrent(superBlock, emitter); }), emitter); }
3414 : renderCurrent;
3415 }
3416};
3417
3418var raw = {
3419 parse: function (tagToken, remainTokens) {
3420 var _this = this;
3421 this.tokens = [];
3422 var stream = this.liquid.parser.parseStream(remainTokens);
3423 stream
3424 .on('token', function (token) {
3425 if (token.name === 'endraw')
3426 stream.stop();
3427 else
3428 _this.tokens.push(token);
3429 })
3430 .on('end', function () {
3431 throw new Error("tag ".concat(tagToken.getText(), " not closed"));
3432 });
3433 stream.start();
3434 },
3435 render: function () {
3436 return this.tokens.map(function (token) { return token.getText(); }).join('');
3437 }
3438};
3439
3440var TablerowloopDrop = /** @class */ (function (_super) {
3441 __extends(TablerowloopDrop, _super);
3442 function TablerowloopDrop(length, cols, collection, variable) {
3443 var _this = _super.call(this, length, collection, variable) || this;
3444 _this.length = length;
3445 _this.cols = cols;
3446 return _this;
3447 }
3448 TablerowloopDrop.prototype.row = function () {
3449 return Math.floor(this.i / this.cols) + 1;
3450 };
3451 TablerowloopDrop.prototype.col0 = function () {
3452 return (this.i % this.cols);
3453 };
3454 TablerowloopDrop.prototype.col = function () {
3455 return this.col0() + 1;
3456 };
3457 TablerowloopDrop.prototype.col_first = function () {
3458 return this.col0() === 0;
3459 };
3460 TablerowloopDrop.prototype.col_last = function () {
3461 return this.col() === this.cols;
3462 };
3463 return TablerowloopDrop;
3464}(ForloopDrop));
3465
3466var tablerow = {
3467 parse: function (tagToken, remainTokens) {
3468 var _this = this;
3469 var tokenizer = new Tokenizer(tagToken.args, this.liquid.options.operatorsTrie);
3470 var variable = tokenizer.readIdentifier();
3471 tokenizer.skipBlank();
3472 var tmp = tokenizer.readIdentifier();
3473 assert(tmp && tmp.content === 'in', function () { return "illegal tag: ".concat(tagToken.getText()); });
3474 this.variable = variable.content;
3475 this.collection = tokenizer.readValue();
3476 this.hash = new Hash(tokenizer.remaining());
3477 this.templates = [];
3478 var p;
3479 var stream = this.liquid.parser.parseStream(remainTokens)
3480 .on('start', function () { return (p = _this.templates); })
3481 .on('tag:endtablerow', function () { return stream.stop(); })
3482 .on('template', function (tpl) { return p.push(tpl); })
3483 .on('end', function () {
3484 throw new Error("tag ".concat(tagToken.getText(), " not closed"));
3485 });
3486 stream.start();
3487 },
3488 render: function (ctx, emitter) {
3489 var collection, _a, hash, offset, limit, cols, r, tablerowloop, scope, idx;
3490 return __generator(this, function (_b) {
3491 switch (_b.label) {
3492 case 0:
3493 _a = toEnumerable;
3494 return [4 /*yield*/, evalToken(this.collection, ctx)];
3495 case 1:
3496 collection = _a.apply(void 0, [_b.sent()]);
3497 return [4 /*yield*/, this.hash.render(ctx)];
3498 case 2:
3499 hash = _b.sent();
3500 offset = hash.offset || 0;
3501 limit = (hash.limit === undefined) ? collection.length : hash.limit;
3502 collection = collection.slice(offset, offset + limit);
3503 cols = hash.cols || collection.length;
3504 r = this.liquid.renderer;
3505 tablerowloop = new TablerowloopDrop(collection.length, cols, this.collection.getText(), this.variable);
3506 scope = { tablerowloop: tablerowloop };
3507 ctx.push(scope);
3508 idx = 0;
3509 _b.label = 3;
3510 case 3:
3511 if (!(idx < collection.length)) return [3 /*break*/, 6];
3512 scope[this.variable] = collection[idx];
3513 if (tablerowloop.col0() === 0) {
3514 if (tablerowloop.row() !== 1)
3515 emitter.write('</tr>');
3516 emitter.write("<tr class=\"row".concat(tablerowloop.row(), "\">"));
3517 }
3518 emitter.write("<td class=\"col".concat(tablerowloop.col(), "\">"));
3519 return [4 /*yield*/, r.renderTemplates(this.templates, ctx, emitter)];
3520 case 4:
3521 _b.sent();
3522 emitter.write('</td>');
3523 _b.label = 5;
3524 case 5:
3525 idx++, tablerowloop.next();
3526 return [3 /*break*/, 3];
3527 case 6:
3528 if (collection.length)
3529 emitter.write('</tr>');
3530 ctx.pop();
3531 return [2 /*return*/];
3532 }
3533 });
3534 }
3535};
3536
3537var unless = {
3538 parse: function (tagToken, remainTokens) {
3539 var _this = this;
3540 this.branches = [];
3541 this.elseTemplates = [];
3542 var p;
3543 this.liquid.parser.parseStream(remainTokens)
3544 .on('start', function () { return _this.branches.push({
3545 predicate: new Value(tagToken.args, _this.liquid),
3546 test: isFalsy,
3547 templates: (p = [])
3548 }); })
3549 .on('tag:elsif', function (token) { return _this.branches.push({
3550 predicate: new Value(token.args, _this.liquid),
3551 test: isTruthy,
3552 templates: (p = [])
3553 }); })
3554 .on('tag:else', function () { return (p = _this.elseTemplates); })
3555 .on('tag:endunless', function () { this.stop(); })
3556 .on('template', function (tpl) { return p.push(tpl); })
3557 .on('end', function () { throw new Error("tag ".concat(tagToken.getText(), " not closed")); })
3558 .start();
3559 },
3560 render: function (ctx, emitter) {
3561 var r, _a, _b, _c, predicate, test_1, templates, value, e_1_1;
3562 var e_1, _d;
3563 return __generator(this, function (_e) {
3564 switch (_e.label) {
3565 case 0:
3566 r = this.liquid.renderer;
3567 _e.label = 1;
3568 case 1:
3569 _e.trys.push([1, 7, 8, 9]);
3570 _a = __values(this.branches), _b = _a.next();
3571 _e.label = 2;
3572 case 2:
3573 if (!!_b.done) return [3 /*break*/, 6];
3574 _c = _b.value, predicate = _c.predicate, test_1 = _c.test, templates = _c.templates;
3575 return [4 /*yield*/, predicate.value(ctx, ctx.opts.lenientIf)];
3576 case 3:
3577 value = _e.sent();
3578 if (!test_1(value, ctx)) return [3 /*break*/, 5];
3579 return [4 /*yield*/, r.renderTemplates(templates, ctx, emitter)];
3580 case 4:
3581 _e.sent();
3582 return [2 /*return*/];
3583 case 5:
3584 _b = _a.next();
3585 return [3 /*break*/, 2];
3586 case 6: return [3 /*break*/, 9];
3587 case 7:
3588 e_1_1 = _e.sent();
3589 e_1 = { error: e_1_1 };
3590 return [3 /*break*/, 9];
3591 case 8:
3592 try {
3593 if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
3594 }
3595 finally { if (e_1) throw e_1.error; }
3596 return [7 /*endfinally*/];
3597 case 9: return [4 /*yield*/, r.renderTemplates(this.elseTemplates, ctx, emitter)];
3598 case 10:
3599 _e.sent();
3600 return [2 /*return*/];
3601 }
3602 });
3603 }
3604};
3605
3606var Break = {
3607 render: function (ctx, emitter) {
3608 emitter['break'] = true;
3609 }
3610};
3611
3612var Continue = {
3613 render: function (ctx, emitter) {
3614 emitter['continue'] = true;
3615 }
3616};
3617
3618var echo = {
3619 parse: function (token) {
3620 this.value = new Value(token.args, this.liquid);
3621 },
3622 render: function (ctx, emitter) {
3623 var val;
3624 return __generator(this, function (_a) {
3625 switch (_a.label) {
3626 case 0: return [4 /*yield*/, this.value.value(ctx, false)];
3627 case 1:
3628 val = _a.sent();
3629 emitter.write(val);
3630 return [2 /*return*/];
3631 }
3632 });
3633 }
3634};
3635
3636var liquid = {
3637 parse: function (token) {
3638 var tokenizer = new Tokenizer(token.args, this.liquid.options.operatorsTrie);
3639 var tokens = tokenizer.readLiquidTagTokens(this.liquid.options);
3640 this.tpls = this.liquid.parser.parseTokens(tokens);
3641 },
3642 render: function (ctx, emitter) {
3643 return __generator(this, function (_a) {
3644 switch (_a.label) {
3645 case 0: return [4 /*yield*/, this.liquid.renderer.renderTemplates(this.tpls, ctx, emitter)];
3646 case 1:
3647 _a.sent();
3648 return [2 /*return*/];
3649 }
3650 });
3651 }
3652};
3653
3654var inlineComment = {
3655 parse: function (tagToken, remainTokens) {
3656 if (tagToken.args.search(/\n\s*[^#\s]/g) !== -1) {
3657 throw new Error('every line of an inline comment must start with a \'#\' character');
3658 }
3659 }
3660};
3661
3662var tags = {
3663 assign: assign,
3664 'for': For,
3665 capture: capture,
3666 'case': Case,
3667 comment: comment,
3668 include: include,
3669 render: render,
3670 decrement: decrement,
3671 increment: increment,
3672 cycle: cycle,
3673 'if': If,
3674 layout: layout,
3675 block: block,
3676 raw: raw,
3677 tablerow: tablerow,
3678 unless: unless,
3679 'break': Break, 'continue': Continue,
3680 echo: echo,
3681 liquid: liquid,
3682 '#': inlineComment
3683};
3684
3685var index = /*#__PURE__*/Object.freeze({
3686 __proto__: null,
3687 'default': tags
3688});
3689
3690var filters = new Map();
3691forOwn(builtinFilters, function (conf, name) {
3692 filters.set(snakeCase(name), conf);
3693});
3694var defaultOptions = {
3695 root: ['.'],
3696 layouts: ['.'],
3697 partials: ['.'],
3698 relativeReference: true,
3699 jekyllInclude: false,
3700 cache: undefined,
3701 extname: '',
3702 fs: fs,
3703 dynamicPartials: true,
3704 jsTruthy: false,
3705 trimTagRight: false,
3706 trimTagLeft: false,
3707 trimOutputRight: false,
3708 trimOutputLeft: false,
3709 greedy: true,
3710 tagDelimiterLeft: '{%',
3711 tagDelimiterRight: '%}',
3712 outputDelimiterLeft: '{{',
3713 outputDelimiterRight: '}}',
3714 preserveTimezones: false,
3715 strictFilters: false,
3716 strictVariables: false,
3717 ownPropertyOnly: false,
3718 lenientIf: false,
3719 globals: {},
3720 keepOutputType: false,
3721 operators: defaultOperators,
3722 operatorsTrie: createTrie(defaultOperators)
3723};
3724function normalize(options) {
3725 if (options.hasOwnProperty('operators')) {
3726 options.operatorsTrie = createTrie(options.operators);
3727 }
3728 if (options.hasOwnProperty('root')) {
3729 if (!options.hasOwnProperty('partials'))
3730 options.partials = options.root;
3731 if (!options.hasOwnProperty('layouts'))
3732 options.layouts = options.root;
3733 }
3734 if (options.hasOwnProperty('cache')) {
3735 var cache = void 0;
3736 if (typeof options.cache === 'number')
3737 cache = options.cache > 0 ? new LRU(options.cache) : undefined;
3738 else if (typeof options.cache === 'object')
3739 cache = options.cache;
3740 else
3741 cache = options.cache ? new LRU(1024) : undefined;
3742 options.cache = cache;
3743 }
3744 options = __assign(__assign(__assign({}, defaultOptions), (options.jekyllInclude ? { dynamicPartials: false } : {})), options);
3745 if (!options.fs.dirname && options.relativeReference) {
3746 console.warn('[LiquidJS] `fs.dirname` is required for relativeReference, set relativeReference to `false` to suppress this warning, or provide implementation for `fs.dirname`');
3747 options.relativeReference = false;
3748 }
3749 options.root = normalizeDirectoryList(options.root);
3750 options.partials = normalizeDirectoryList(options.partials);
3751 options.layouts = normalizeDirectoryList(options.layouts);
3752 options.outputEscape = options.outputEscape && getOutputEscapeFunction(options.outputEscape);
3753 return options;
3754}
3755function getOutputEscapeFunction(nameOrFunction) {
3756 if (isString(nameOrFunction)) {
3757 var filterImpl = filters.get(nameOrFunction);
3758 assert(isFunction(filterImpl), "filter \"".concat(nameOrFunction, "\" not found"));
3759 return filterImpl;
3760 }
3761 else {
3762 assert(isFunction(nameOrFunction), '`outputEscape` need to be of type string or function');
3763 return nameOrFunction;
3764 }
3765}
3766function normalizeDirectoryList(value) {
3767 var list = [];
3768 if (isArray(value))
3769 list = value;
3770 if (isString(value))
3771 list = [value];
3772 return list;
3773}
3774
3775var Context = /** @class */ (function () {
3776 function Context(env, opts, renderOptions) {
3777 if (env === void 0) { env = {}; }
3778 if (opts === void 0) { opts = defaultOptions; }
3779 if (renderOptions === void 0) { renderOptions = {}; }
3780 var _a, _b;
3781 /**
3782 * insert a Context-level empty scope,
3783 * for tags like `{% capture %}` `{% assign %}` to operate
3784 */
3785 this.scopes = [{}];
3786 this.registers = {};
3787 this.sync = !!renderOptions.sync;
3788 this.opts = opts;
3789 this.globals = (_a = renderOptions.globals) !== null && _a !== void 0 ? _a : opts.globals;
3790 this.environments = env;
3791 this.strictVariables = (_b = renderOptions.strictVariables) !== null && _b !== void 0 ? _b : this.opts.strictVariables;
3792 }
3793 Context.prototype.getRegister = function (key) {
3794 return (this.registers[key] = this.registers[key] || {});
3795 };
3796 Context.prototype.setRegister = function (key, value) {
3797 return (this.registers[key] = value);
3798 };
3799 Context.prototype.saveRegister = function () {
3800 var _this = this;
3801 var keys = [];
3802 for (var _i = 0; _i < arguments.length; _i++) {
3803 keys[_i] = arguments[_i];
3804 }
3805 return keys.map(function (key) { return [key, _this.getRegister(key)]; });
3806 };
3807 Context.prototype.restoreRegister = function (keyValues) {
3808 var _this = this;
3809 return keyValues.forEach(function (_a) {
3810 var _b = __read(_a, 2), key = _b[0], value = _b[1];
3811 return _this.setRegister(key, value);
3812 });
3813 };
3814 Context.prototype.getAll = function () {
3815 return __spreadArray([this.globals, this.environments], __read(this.scopes), false).reduce(function (ctx, val) { return __assign(ctx, val); }, {});
3816 };
3817 Context.prototype.get = function (paths) {
3818 var scope = this.findScope(paths[0]);
3819 return this.getFromScope(scope, paths);
3820 };
3821 Context.prototype.getFromScope = function (scope, paths) {
3822 var _this = this;
3823 if (isString(paths))
3824 paths = paths.split('.');
3825 return paths.reduce(function (scope, path, i) {
3826 scope = readProperty(scope, path, _this.opts.ownPropertyOnly);
3827 if (isNil(scope) && _this.strictVariables) {
3828 throw new InternalUndefinedVariableError(paths.slice(0, i + 1).join('.'));
3829 }
3830 return scope;
3831 }, scope);
3832 };
3833 Context.prototype.push = function (ctx) {
3834 return this.scopes.push(ctx);
3835 };
3836 Context.prototype.pop = function () {
3837 return this.scopes.pop();
3838 };
3839 Context.prototype.bottom = function () {
3840 return this.scopes[0];
3841 };
3842 Context.prototype.findScope = function (key) {
3843 for (var i = this.scopes.length - 1; i >= 0; i--) {
3844 var candidate = this.scopes[i];
3845 if (key in candidate)
3846 return candidate;
3847 }
3848 if (key in this.environments)
3849 return this.environments;
3850 return this.globals;
3851 };
3852 return Context;
3853}());
3854function readProperty(obj, key, ownPropertyOnly) {
3855 if (isNil(obj))
3856 return obj;
3857 obj = toLiquid(obj);
3858 if (isArray(obj) && key < 0)
3859 return obj[obj.length + +key];
3860 var jsProperty = readJSProperty(obj, key, ownPropertyOnly);
3861 if (jsProperty === undefined && obj instanceof Drop)
3862 return obj.liquidMethodMissing(key);
3863 if (isFunction(jsProperty))
3864 return jsProperty.call(obj);
3865 if (key === 'size')
3866 return readSize(obj);
3867 else if (key === 'first')
3868 return readFirst(obj);
3869 else if (key === 'last')
3870 return readLast(obj);
3871 return jsProperty;
3872}
3873function readJSProperty(obj, key, ownPropertyOnly) {
3874 if (ownPropertyOnly && !Object.hasOwnProperty.call(obj, key))
3875 return undefined;
3876 return obj[key];
3877}
3878function readFirst(obj) {
3879 if (isArray(obj))
3880 return obj[0];
3881 return obj['first'];
3882}
3883function readLast(obj) {
3884 if (isArray(obj))
3885 return obj[obj.length - 1];
3886 return obj['last'];
3887}
3888function readSize(obj) {
3889 if (obj.hasOwnProperty('size') || obj['size'] !== undefined)
3890 return obj['size'];
3891 if (isArray(obj) || isString(obj))
3892 return obj.length;
3893 if (typeof obj === 'object')
3894 return Object.keys(obj).length;
3895}
3896
3897var LookupType;
3898(function (LookupType) {
3899 LookupType["Partials"] = "partials";
3900 LookupType["Layouts"] = "layouts";
3901 LookupType["Root"] = "root";
3902})(LookupType || (LookupType = {}));
3903var Loader = /** @class */ (function () {
3904 function Loader(options) {
3905 this.options = options;
3906 if (options.relativeReference) {
3907 var sep = options.fs.sep;
3908 assert(sep, '`fs.sep` is required for relative reference');
3909 var rRelativePath_1 = new RegExp(['.' + sep, '..' + sep, './', '../'].map(function (prefix) { return escapeRegex(prefix); }).join('|'));
3910 this.shouldLoadRelative = function (referencedFile) { return rRelativePath_1.test(referencedFile); };
3911 }
3912 else {
3913 this.shouldLoadRelative = function (referencedFile) { return false; };
3914 }
3915 this.contains = this.options.fs.contains || (function () { return true; });
3916 }
3917 Loader.prototype.lookup = function (file, type, sync, currentFile) {
3918 var fs, dirs, _a, _b, filepath, _c, e_1_1;
3919 var e_1, _d;
3920 return __generator(this, function (_e) {
3921 switch (_e.label) {
3922 case 0:
3923 fs = this.options.fs;
3924 dirs = this.options[type];
3925 _e.label = 1;
3926 case 1:
3927 _e.trys.push([1, 8, 9, 10]);
3928 _a = __values(this.candidates(file, dirs, currentFile, type !== LookupType.Root)), _b = _a.next();
3929 _e.label = 2;
3930 case 2:
3931 if (!!_b.done) return [3 /*break*/, 7];
3932 filepath = _b.value;
3933 if (!sync) return [3 /*break*/, 3];
3934 _c = fs.existsSync(filepath);
3935 return [3 /*break*/, 5];
3936 case 3: return [4 /*yield*/, fs.exists(filepath)];
3937 case 4:
3938 _c = _e.sent();
3939 _e.label = 5;
3940 case 5:
3941 if (_c)
3942 return [2 /*return*/, filepath];
3943 _e.label = 6;
3944 case 6:
3945 _b = _a.next();
3946 return [3 /*break*/, 2];
3947 case 7: return [3 /*break*/, 10];
3948 case 8:
3949 e_1_1 = _e.sent();
3950 e_1 = { error: e_1_1 };
3951 return [3 /*break*/, 10];
3952 case 9:
3953 try {
3954 if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
3955 }
3956 finally { if (e_1) throw e_1.error; }
3957 return [7 /*endfinally*/];
3958 case 10: throw this.lookupError(file, dirs);
3959 }
3960 });
3961 };
3962 Loader.prototype.candidates = function (file, dirs, currentFile, enforceRoot) {
3963 var _a, fs, extname, referenced, dirs_1, dirs_1_1, dir, e_2_1, dirs_2, dirs_2_1, dir, referenced, e_3_1, filepath;
3964 var e_2, _b, e_3, _c;
3965 return __generator(this, function (_d) {
3966 switch (_d.label) {
3967 case 0:
3968 _a = this.options, fs = _a.fs, extname = _a.extname;
3969 if (!(this.shouldLoadRelative(file) && currentFile)) return [3 /*break*/, 8];
3970 referenced = fs.resolve(this.dirname(currentFile), file, extname);
3971 _d.label = 1;
3972 case 1:
3973 _d.trys.push([1, 6, 7, 8]);
3974 dirs_1 = __values(dirs), dirs_1_1 = dirs_1.next();
3975 _d.label = 2;
3976 case 2:
3977 if (!!dirs_1_1.done) return [3 /*break*/, 5];
3978 dir = dirs_1_1.value;
3979 if (!(!enforceRoot || this.contains(dir, referenced))) return [3 /*break*/, 4];
3980 // the relatively referenced file is within one of root dirs
3981 return [4 /*yield*/, referenced];
3982 case 3:
3983 // the relatively referenced file is within one of root dirs
3984 _d.sent();
3985 return [3 /*break*/, 5];
3986 case 4:
3987 dirs_1_1 = dirs_1.next();
3988 return [3 /*break*/, 2];
3989 case 5: return [3 /*break*/, 8];
3990 case 6:
3991 e_2_1 = _d.sent();
3992 e_2 = { error: e_2_1 };
3993 return [3 /*break*/, 8];
3994 case 7:
3995 try {
3996 if (dirs_1_1 && !dirs_1_1.done && (_b = dirs_1.return)) _b.call(dirs_1);
3997 }
3998 finally { if (e_2) throw e_2.error; }
3999 return [7 /*endfinally*/];
4000 case 8:
4001 _d.trys.push([8, 13, 14, 15]);
4002 dirs_2 = __values(dirs), dirs_2_1 = dirs_2.next();
4003 _d.label = 9;
4004 case 9:
4005 if (!!dirs_2_1.done) return [3 /*break*/, 12];
4006 dir = dirs_2_1.value;
4007 referenced = fs.resolve(dir, file, extname);
4008 if (!(!enforceRoot || this.contains(dir, referenced))) return [3 /*break*/, 11];
4009 return [4 /*yield*/, referenced];
4010 case 10:
4011 _d.sent();
4012 _d.label = 11;
4013 case 11:
4014 dirs_2_1 = dirs_2.next();
4015 return [3 /*break*/, 9];
4016 case 12: return [3 /*break*/, 15];
4017 case 13:
4018 e_3_1 = _d.sent();
4019 e_3 = { error: e_3_1 };
4020 return [3 /*break*/, 15];
4021 case 14:
4022 try {
4023 if (dirs_2_1 && !dirs_2_1.done && (_c = dirs_2.return)) _c.call(dirs_2);
4024 }
4025 finally { if (e_3) throw e_3.error; }
4026 return [7 /*endfinally*/];
4027 case 15:
4028 if (!(fs.fallback !== undefined)) return [3 /*break*/, 17];
4029 filepath = fs.fallback(file);
4030 if (!(filepath !== undefined)) return [3 /*break*/, 17];
4031 return [4 /*yield*/, filepath];
4032 case 16:
4033 _d.sent();
4034 _d.label = 17;
4035 case 17: return [2 /*return*/];
4036 }
4037 });
4038 };
4039 Loader.prototype.dirname = function (path) {
4040 var fs = this.options.fs;
4041 assert(fs.dirname, '`fs.dirname` is required for relative reference');
4042 return fs.dirname(path);
4043 };
4044 Loader.prototype.lookupError = function (file, roots) {
4045 var err = new Error('ENOENT');
4046 err.message = "ENOENT: Failed to lookup \"".concat(file, "\" in \"").concat(roots, "\"");
4047 err.code = 'ENOENT';
4048 return err;
4049 };
4050 return Loader;
4051}());
4052
4053var SimpleEmitter = /** @class */ (function () {
4054 function SimpleEmitter() {
4055 this.buffer = '';
4056 }
4057 SimpleEmitter.prototype.write = function (html) {
4058 this.buffer += stringify(html);
4059 };
4060 return SimpleEmitter;
4061}());
4062
4063var StreamedEmitter = /** @class */ (function () {
4064 function StreamedEmitter() {
4065 this.buffer = '';
4066 this.stream = new stream.PassThrough();
4067 }
4068 StreamedEmitter.prototype.write = function (html) {
4069 this.stream.write(stringify(html));
4070 };
4071 StreamedEmitter.prototype.error = function (err) {
4072 this.stream.emit('error', err);
4073 };
4074 StreamedEmitter.prototype.end = function () {
4075 this.stream.end();
4076 };
4077 return StreamedEmitter;
4078}());
4079
4080var KeepingTypeEmitter = /** @class */ (function () {
4081 function KeepingTypeEmitter() {
4082 this.buffer = '';
4083 }
4084 KeepingTypeEmitter.prototype.write = function (html) {
4085 html = toValue(html);
4086 // This will only preserve the type if the value is isolated.
4087 // I.E:
4088 // {{ my-port }} -> 42
4089 // {{ my-host }}:{{ my-port }} -> 'host:42'
4090 if (typeof html !== 'string' && this.buffer === '') {
4091 this.buffer = html;
4092 }
4093 else {
4094 this.buffer = stringify(this.buffer) + stringify(html);
4095 }
4096 };
4097 return KeepingTypeEmitter;
4098}());
4099
4100var Render = /** @class */ (function () {
4101 function Render() {
4102 }
4103 Render.prototype.renderTemplatesToNodeStream = function (templates, ctx) {
4104 var _this = this;
4105 var emitter = new StreamedEmitter();
4106 Promise.resolve().then(function () { return toPromise(_this.renderTemplates(templates, ctx, emitter)); })
4107 .then(function () { return emitter.end(); }, function (err) { return emitter.error(err); });
4108 return emitter.stream;
4109 };
4110 Render.prototype.renderTemplates = function (templates, ctx, emitter) {
4111 var templates_1, templates_1_1, tpl, html, e_1, err, e_2_1;
4112 var e_2, _a;
4113 return __generator(this, function (_b) {
4114 switch (_b.label) {
4115 case 0:
4116 if (!emitter) {
4117 emitter = ctx.opts.keepOutputType ? new KeepingTypeEmitter() : new SimpleEmitter();
4118 }
4119 _b.label = 1;
4120 case 1:
4121 _b.trys.push([1, 8, 9, 10]);
4122 templates_1 = __values(templates), templates_1_1 = templates_1.next();
4123 _b.label = 2;
4124 case 2:
4125 if (!!templates_1_1.done) return [3 /*break*/, 7];
4126 tpl = templates_1_1.value;
4127 _b.label = 3;
4128 case 3:
4129 _b.trys.push([3, 5, , 6]);
4130 return [4 /*yield*/, tpl.render(ctx, emitter)
4131 // if not, it'll return an `html`, write to the emitter for it
4132 ];
4133 case 4:
4134 html = _b.sent();
4135 // if not, it'll return an `html`, write to the emitter for it
4136 html && emitter.write(html);
4137 if (emitter['break'] || emitter['continue'])
4138 return [3 /*break*/, 7];
4139 return [3 /*break*/, 6];
4140 case 5:
4141 e_1 = _b.sent();
4142 err = RenderError.is(e_1) ? e_1 : new RenderError(e_1, tpl);
4143 throw err;
4144 case 6:
4145 templates_1_1 = templates_1.next();
4146 return [3 /*break*/, 2];
4147 case 7: return [3 /*break*/, 10];
4148 case 8:
4149 e_2_1 = _b.sent();
4150 e_2 = { error: e_2_1 };
4151 return [3 /*break*/, 10];
4152 case 9:
4153 try {
4154 if (templates_1_1 && !templates_1_1.done && (_a = templates_1.return)) _a.call(templates_1);
4155 }
4156 finally { if (e_2) throw e_2.error; }
4157 return [7 /*endfinally*/];
4158 case 10: return [2 /*return*/, emitter.buffer];
4159 }
4160 });
4161 };
4162 return Render;
4163}());
4164
4165var TemplateImpl = /** @class */ (function () {
4166 function TemplateImpl(token) {
4167 this.token = token;
4168 }
4169 return TemplateImpl;
4170}());
4171
4172var Tag = /** @class */ (function (_super) {
4173 __extends(Tag, _super);
4174 function Tag(token, tokens, liquid) {
4175 var _this = _super.call(this, token) || this;
4176 _this.name = token.name;
4177 var impl = liquid.tags.get(token.name);
4178 _this.impl = Object.create(impl);
4179 _this.impl.liquid = liquid;
4180 if (_this.impl.parse) {
4181 _this.impl.parse(token, tokens);
4182 }
4183 return _this;
4184 }
4185 Tag.prototype.render = function (ctx, emitter) {
4186 var hash, impl;
4187 return __generator(this, function (_a) {
4188 switch (_a.label) {
4189 case 0: return [4 /*yield*/, new Hash(this.token.args).render(ctx)];
4190 case 1:
4191 hash = (_a.sent());
4192 impl = this.impl;
4193 if (!isFunction(impl.render)) return [3 /*break*/, 3];
4194 return [4 /*yield*/, impl.render(ctx, emitter, hash)];
4195 case 2: return [2 /*return*/, _a.sent()];
4196 case 3: return [2 /*return*/];
4197 }
4198 });
4199 };
4200 return Tag;
4201}(TemplateImpl));
4202
4203var Output = /** @class */ (function (_super) {
4204 __extends(Output, _super);
4205 function Output(token, liquid) {
4206 var _this = _super.call(this, token) || this;
4207 _this.value = new Value(token.content, liquid);
4208 var filters = _this.value.filters;
4209 var outputEscape = liquid.options.outputEscape;
4210 if (filters.length && filters[filters.length - 1].name === 'raw') {
4211 filters.pop();
4212 }
4213 else if (outputEscape) {
4214 filters.push(new Filter(toString.call(outputEscape), outputEscape, [], liquid));
4215 }
4216 return _this;
4217 }
4218 Output.prototype.render = function (ctx, emitter) {
4219 var val;
4220 return __generator(this, function (_a) {
4221 switch (_a.label) {
4222 case 0: return [4 /*yield*/, this.value.value(ctx, false)];
4223 case 1:
4224 val = _a.sent();
4225 emitter.write(val);
4226 return [2 /*return*/];
4227 }
4228 });
4229 };
4230 return Output;
4231}(TemplateImpl));
4232
4233var HTML = /** @class */ (function (_super) {
4234 __extends(HTML, _super);
4235 function HTML(token) {
4236 var _this = _super.call(this, token) || this;
4237 _this.str = token.getContent();
4238 return _this;
4239 }
4240 HTML.prototype.render = function (ctx, emitter) {
4241 return __generator(this, function (_a) {
4242 emitter.write(this.str);
4243 return [2 /*return*/];
4244 });
4245 };
4246 return HTML;
4247}(TemplateImpl));
4248
4249var Parser = /** @class */ (function () {
4250 function Parser(liquid) {
4251 this.liquid = liquid;
4252 this.cache = this.liquid.options.cache;
4253 this.fs = this.liquid.options.fs;
4254 this.parseFile = this.cache ? this._parseFileCached : this._parseFile;
4255 this.loader = new Loader(this.liquid.options);
4256 }
4257 Parser.prototype.parse = function (html, filepath) {
4258 var tokenizer = new Tokenizer(html, this.liquid.options.operatorsTrie, filepath);
4259 var tokens = tokenizer.readTopLevelTokens(this.liquid.options);
4260 return this.parseTokens(tokens);
4261 };
4262 Parser.prototype.parseTokens = function (tokens) {
4263 var token;
4264 var templates = [];
4265 while ((token = tokens.shift())) {
4266 templates.push(this.parseToken(token, tokens));
4267 }
4268 return templates;
4269 };
4270 Parser.prototype.parseToken = function (token, remainTokens) {
4271 try {
4272 if (isTagToken(token)) {
4273 return new Tag(token, remainTokens, this.liquid);
4274 }
4275 if (isOutputToken(token)) {
4276 return new Output(token, this.liquid);
4277 }
4278 return new HTML(token);
4279 }
4280 catch (e) {
4281 throw new ParseError(e, token);
4282 }
4283 };
4284 Parser.prototype.parseStream = function (tokens) {
4285 var _this = this;
4286 return new ParseStream(tokens, function (token, tokens) { return _this.parseToken(token, tokens); });
4287 };
4288 Parser.prototype._parseFileCached = function (file, sync, type, currentFile) {
4289 var cache, key, tpls, task, taskOrTpl, _a, err_1;
4290 if (type === void 0) { type = LookupType.Root; }
4291 return __generator(this, function (_b) {
4292 switch (_b.label) {
4293 case 0:
4294 cache = this.cache;
4295 key = this.loader.shouldLoadRelative(file) ? currentFile + ',' + file : type + ':' + file;
4296 return [4 /*yield*/, cache.read(key)];
4297 case 1:
4298 tpls = _b.sent();
4299 if (tpls)
4300 return [2 /*return*/, tpls];
4301 task = this._parseFile(file, sync, type, currentFile);
4302 if (!sync) return [3 /*break*/, 3];
4303 return [4 /*yield*/, task];
4304 case 2:
4305 _a = _b.sent();
4306 return [3 /*break*/, 4];
4307 case 3:
4308 _a = toPromise(task);
4309 _b.label = 4;
4310 case 4:
4311 taskOrTpl = _a;
4312 cache.write(key, taskOrTpl);
4313 _b.label = 5;
4314 case 5:
4315 _b.trys.push([5, 7, , 8]);
4316 return [4 /*yield*/, taskOrTpl];
4317 case 6: return [2 /*return*/, _b.sent()];
4318 case 7:
4319 err_1 = _b.sent();
4320 cache.remove(key);
4321 throw err_1;
4322 case 8: return [2 /*return*/];
4323 }
4324 });
4325 };
4326 Parser.prototype._parseFile = function (file, sync, type, currentFile) {
4327 var filepath, _a, _b, _c;
4328 if (type === void 0) { type = LookupType.Root; }
4329 return __generator(this, function (_d) {
4330 switch (_d.label) {
4331 case 0: return [4 /*yield*/, this.loader.lookup(file, type, sync, currentFile)];
4332 case 1:
4333 filepath = _d.sent();
4334 _b = (_a = this.liquid).parse;
4335 if (!sync) return [3 /*break*/, 2];
4336 _c = this.fs.readFileSync(filepath);
4337 return [3 /*break*/, 4];
4338 case 2: return [4 /*yield*/, this.fs.readFile(filepath)];
4339 case 3:
4340 _c = _d.sent();
4341 _d.label = 4;
4342 case 4: return [2 /*return*/, _b.apply(_a, [_c, filepath])];
4343 }
4344 });
4345 };
4346 return Parser;
4347}());
4348
4349var TagMap = /** @class */ (function () {
4350 function TagMap() {
4351 this.impls = {};
4352 }
4353 TagMap.prototype.get = function (name) {
4354 var impl = this.impls[name];
4355 assert(impl, function () { return "tag \"".concat(name, "\" not found"); });
4356 return impl;
4357 };
4358 TagMap.prototype.set = function (name, impl) {
4359 this.impls[name] = impl;
4360 };
4361 return TagMap;
4362}());
4363
4364var FilterMap = /** @class */ (function () {
4365 function FilterMap(strictFilters, liquid) {
4366 this.strictFilters = strictFilters;
4367 this.liquid = liquid;
4368 this.impls = {};
4369 }
4370 FilterMap.prototype.get = function (name) {
4371 var impl = this.impls[name];
4372 assert(impl || !this.strictFilters, function () { return "undefined filter: ".concat(name); });
4373 return impl;
4374 };
4375 FilterMap.prototype.set = function (name, impl) {
4376 this.impls[name] = impl;
4377 };
4378 FilterMap.prototype.create = function (name, args) {
4379 return new Filter(name, this.get(name), args, this.liquid);
4380 };
4381 return FilterMap;
4382}());
4383
4384var version = '9.40.0';
4385var Liquid = /** @class */ (function () {
4386 function Liquid(opts) {
4387 var _this = this;
4388 if (opts === void 0) { opts = {}; }
4389 this.options = normalize(opts);
4390 this.parser = new Parser(this);
4391 this.renderer = new Render();
4392 this.filters = new FilterMap(this.options.strictFilters, this);
4393 this.tags = new TagMap();
4394 forOwn(tags, function (conf, name) { return _this.registerTag(snakeCase(name), conf); });
4395 forOwn(builtinFilters, function (handler, name) { return _this.registerFilter(snakeCase(name), handler); });
4396 }
4397 Liquid.prototype.parse = function (html, filepath) {
4398 return this.parser.parse(html, filepath);
4399 };
4400 Liquid.prototype._render = function (tpl, scope, renderOptions) {
4401 var ctx = new Context(scope, this.options, renderOptions);
4402 return this.renderer.renderTemplates(tpl, ctx);
4403 };
4404 Liquid.prototype.render = function (tpl, scope, renderOptions) {
4405 return __awaiter(this, void 0, void 0, function () {
4406 return __generator(this, function (_a) {
4407 return [2 /*return*/, toPromise(this._render(tpl, scope, __assign(__assign({}, renderOptions), { sync: false })))];
4408 });
4409 });
4410 };
4411 Liquid.prototype.renderSync = function (tpl, scope, renderOptions) {
4412 return toValueSync(this._render(tpl, scope, __assign(__assign({}, renderOptions), { sync: true })));
4413 };
4414 Liquid.prototype.renderToNodeStream = function (tpl, scope, renderOptions) {
4415 if (renderOptions === void 0) { renderOptions = {}; }
4416 var ctx = new Context(scope, this.options, renderOptions);
4417 return this.renderer.renderTemplatesToNodeStream(tpl, ctx);
4418 };
4419 Liquid.prototype._parseAndRender = function (html, scope, renderOptions) {
4420 var tpl = this.parse(html);
4421 return this._render(tpl, scope, renderOptions);
4422 };
4423 Liquid.prototype.parseAndRender = function (html, scope, renderOptions) {
4424 return __awaiter(this, void 0, void 0, function () {
4425 return __generator(this, function (_a) {
4426 return [2 /*return*/, toPromise(this._parseAndRender(html, scope, __assign(__assign({}, renderOptions), { sync: false })))];
4427 });
4428 });
4429 };
4430 Liquid.prototype.parseAndRenderSync = function (html, scope, renderOptions) {
4431 return toValueSync(this._parseAndRender(html, scope, __assign(__assign({}, renderOptions), { sync: true })));
4432 };
4433 Liquid.prototype._parsePartialFile = function (file, sync, currentFile) {
4434 return this.parser.parseFile(file, sync, LookupType.Partials, currentFile);
4435 };
4436 Liquid.prototype._parseLayoutFile = function (file, sync, currentFile) {
4437 return this.parser.parseFile(file, sync, LookupType.Layouts, currentFile);
4438 };
4439 Liquid.prototype.parseFile = function (file) {
4440 return __awaiter(this, void 0, void 0, function () {
4441 return __generator(this, function (_a) {
4442 return [2 /*return*/, toPromise(this.parser.parseFile(file, false))];
4443 });
4444 });
4445 };
4446 Liquid.prototype.parseFileSync = function (file) {
4447 return toValueSync(this.parser.parseFile(file, true));
4448 };
4449 Liquid.prototype.renderFile = function (file, ctx, renderOptions) {
4450 return __awaiter(this, void 0, void 0, function () {
4451 var templates;
4452 return __generator(this, function (_a) {
4453 switch (_a.label) {
4454 case 0: return [4 /*yield*/, this.parseFile(file)];
4455 case 1:
4456 templates = _a.sent();
4457 return [2 /*return*/, this.render(templates, ctx, renderOptions)];
4458 }
4459 });
4460 });
4461 };
4462 Liquid.prototype.renderFileSync = function (file, ctx, renderOptions) {
4463 var templates = this.parseFileSync(file);
4464 return this.renderSync(templates, ctx, renderOptions);
4465 };
4466 Liquid.prototype.renderFileToNodeStream = function (file, scope, renderOptions) {
4467 return __awaiter(this, void 0, void 0, function () {
4468 var templates;
4469 return __generator(this, function (_a) {
4470 switch (_a.label) {
4471 case 0: return [4 /*yield*/, this.parseFile(file)];
4472 case 1:
4473 templates = _a.sent();
4474 return [2 /*return*/, this.renderToNodeStream(templates, scope, renderOptions)];
4475 }
4476 });
4477 });
4478 };
4479 Liquid.prototype._evalValue = function (str, ctx) {
4480 var value = new Value(str, this);
4481 return value.value(ctx, false);
4482 };
4483 Liquid.prototype.evalValue = function (str, ctx) {
4484 return __awaiter(this, void 0, void 0, function () {
4485 return __generator(this, function (_a) {
4486 return [2 /*return*/, toPromise(this._evalValue(str, ctx))];
4487 });
4488 });
4489 };
4490 Liquid.prototype.evalValueSync = function (str, ctx) {
4491 return toValueSync(this._evalValue(str, ctx));
4492 };
4493 Liquid.prototype.registerFilter = function (name, filter) {
4494 this.filters.set(name, filter);
4495 };
4496 Liquid.prototype.registerTag = function (name, tag) {
4497 this.tags.set(name, tag);
4498 };
4499 Liquid.prototype.plugin = function (plugin) {
4500 return plugin.call(this, Liquid);
4501 };
4502 Liquid.prototype.express = function () {
4503 var self = this; // eslint-disable-line
4504 var firstCall = true;
4505 return function (filePath, ctx, callback) {
4506 var _a, _b, _c;
4507 if (firstCall) {
4508 firstCall = false;
4509 var dirs = normalizeDirectoryList(this.root);
4510 (_a = self.options.root).unshift.apply(_a, __spreadArray([], __read(dirs), false));
4511 (_b = self.options.layouts).unshift.apply(_b, __spreadArray([], __read(dirs), false));
4512 (_c = self.options.partials).unshift.apply(_c, __spreadArray([], __read(dirs), false));
4513 }
4514 self.renderFile(filePath, ctx).then(function (html) { return callback(null, html); }, callback);
4515 };
4516 };
4517 return Liquid;
4518}());
4519
4520exports.AssertionError = AssertionError;
4521exports.Context = Context;
4522exports.Drop = Drop;
4523exports.Expression = Expression;
4524exports.Hash = Hash;
4525exports.InternalUndefinedVariableError = InternalUndefinedVariableError;
4526exports.Liquid = Liquid;
4527exports.LiquidError = LiquidError;
4528exports.ParseError = ParseError;
4529exports.ParseStream = ParseStream;
4530exports.RenderError = RenderError;
4531exports.TagToken = TagToken;
4532exports.TimezoneDate = TimezoneDate;
4533exports.Token = Token;
4534exports.TokenizationError = TokenizationError;
4535exports.Tokenizer = Tokenizer;
4536exports.TypeGuards = typeGuards;
4537exports.UndefinedVariableError = UndefinedVariableError;
4538exports.Value = Value;
4539exports.assert = assert;
4540exports.createTrie = createTrie;
4541exports.defaultOperators = defaultOperators;
4542exports.defaultOptions = defaultOptions;
4543exports.evalQuotedToken = evalQuotedToken;
4544exports.evalToken = evalToken;
4545exports.filters = builtinFilters;
4546exports.isFalsy = isFalsy;
4547exports.isTruthy = isTruthy;
4548exports.tags = index;
4549exports.toPromise = toPromise;
4550exports.toThenable = toThenable;
4551exports.toValue = toValue;
4552exports.toValueSync = toValueSync;
4553exports.version = version;