UNPKG

284 kBJavaScriptView Raw
1/*!
2 * Snakeskin v7.3.0
3 * https://github.com/SnakeskinTpl/Snakeskin
4 *
5 * Released under the MIT license
6 * https://github.com/SnakeskinTpl/Snakeskin/blob/master/LICENSE
7 *
8 * Date: 'Thu, 14 Jun 2018 10:04:56 GMT
9 */
10
11(function (global, factory) {
12 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
13 typeof define === 'function' && define.amd ? define('Snakeskin', factory) :
14 (global.Snakeskin = factory());
15}(this, (function () { 'use strict';
16
17var Snakeskin = void 0;
18var Snakeskin$1 = Snakeskin = {
19 VERSION: [7, 3, 0]
20};
21
22/**
23 * The operation UID
24 * @type {?string}
25 */
26Snakeskin.UID = null;
27
28/**
29 * The namespace for directives
30 * @const
31 */
32Snakeskin.Directives = {};
33
34/**
35 * The namespace for filters
36 * @const
37 */
38Snakeskin.Filters = {};
39
40/**
41 * The namespace for super-global variables
42 * @const
43 */
44Snakeskin.Vars = {};
45
46/**
47 * The namespace for local variables
48 * @const
49 */
50Snakeskin.LocalVars = {};
51
52/**
53 * The cache of templates
54 * @const
55 */
56Snakeskin.cache = {};
57
58Array.isArray = Array.isArray || function (obj) {
59 return {}.call(obj) === '[object Array]';
60};
61
62String.prototype.trim = String.prototype.trim || function () {
63 var str = this.replace(/^\s\s*/, '');
64
65 var i = str.length;
66
67 for (var rgxp = /\s/; rgxp.test(str.charAt(--i));) {
68 // Do nothing
69 }
70
71 return str.substring(0, i + 1);
72};
73
74/**
75 * Returns true if the specified value is a function
76 *
77 * @param {?} obj - source value
78 * @return {boolean}
79 */
80function isFunction(obj) {
81 return typeof obj === 'function';
82}
83
84/**
85 * Returns true if the specified value is a number
86 *
87 * @param {?} obj - source value
88 * @return {boolean}
89 */
90
91
92/**
93 * Returns true if the specified value is a string
94 *
95 * @param {?} obj - source value
96 * @return {boolean}
97 */
98function isString(obj) {
99 return typeof obj === 'string';
100}
101
102/**
103 * Returns true if the specified value is a boolean
104 *
105 * @param {?} obj - source value
106 * @return {boolean}
107 */
108
109
110/**
111 * Returns true if the specified value is an array
112 *
113 * @param {?} obj - source value
114 * @return {boolean}
115 */
116function isArray(obj) {
117 return Array.isArray(obj);
118}
119
120/**
121 * Returns true if the specified value is a plain object
122 *
123 * @param {?} obj - source value
124 * @return {boolean}
125 */
126function isObject(obj) {
127 return Boolean(obj) && obj.constructor === Object;
128}
129
130/**
131 * Special Snakeskin class for escaping HTML entities from an object
132 *
133 * @constructor
134 * @param {?} obj - source object
135 * @param {?string=} [opt_attr] - type of attribute declaration
136 */
137Snakeskin$1.HTMLObject = function (obj, opt_attr) {
138 this.value = obj;
139 this.attr = opt_attr;
140};
141
142/**
143 * StringBuffer constructor
144 *
145 * @constructor
146 * @return {!Array}
147 */
148Snakeskin$1.StringBuffer = function () {
149 return [];
150};
151
152/**
153 * @param {!Function} child
154 * @param {!Function} parent
155 */
156function inherit(child, parent) {
157 /** @constructor */
158 var F = function F() {
159 this.constructor = child;
160 };
161
162 F.prototype = parent.prototype;
163 child.prototype = new F();
164}
165
166/**
167 * Node constructor
168 * @constructor
169 */
170Snakeskin$1.Node = function () {};
171
172/**
173 * Returns the number of child elements
174 * @return {number}
175 */
176Snakeskin$1.Node.prototype.length = function () {
177 return this.value.childNodes.length;
178};
179
180/**
181 * Returns text content
182 * @return {string}
183 */
184Snakeskin$1.Node.prototype.textContent = function () {
185 return this.value.textContent;
186};
187
188/**
189 * DocumentFragment constructor
190 *
191 * @constructor
192 * @extends {Snakeskin.Node}
193 * @param {string} renderMode - rendering mode of templates
194 */
195Snakeskin$1.DocumentFragment = function (renderMode) {
196 this.renderMode = renderMode;
197 this.value = document.createDocumentFragment();
198};
199
200inherit(Snakeskin$1.DocumentFragment, Snakeskin$1.Node);
201
202/**
203 * Appends a child to the document fragment
204 * @param {?} el - element for appending
205 */
206Snakeskin$1.DocumentFragment.prototype.appendChild = function (el) {
207 this.value.appendChild(el);
208};
209
210/**
211 * Returns text content
212 * @return {string}
213 */
214Snakeskin$1.DocumentFragment.prototype.textContent = function () {
215 var children = this.value.childNodes;
216
217 var res = '';
218 for (var i = 0; i < children.length; i++) {
219 res += children[i].outerHTML || children[i].textContent;
220 }
221
222 return res;
223};
224
225/**
226 * Element constructor
227 *
228 * @constructor
229 * @extends {Snakeskin.Node}
230 *
231 * @param {string} name - element name
232 * @param {string} renderMode - rendering mode of templates
233 */
234Snakeskin$1.Element = function (name, renderMode) {
235 this.renderMode = renderMode;
236 this.value = document.createElement(name);
237};
238
239inherit(Snakeskin$1.Element, Snakeskin$1.Node);
240
241/**
242 * Appends a child to the element
243 * @param {?} el - element for appending
244 */
245Snakeskin$1.Element.prototype.appendChild = function (el) {
246 this.value.appendChild(el);
247};
248
249/**
250 * Sets an attribute to the element
251 *
252 * @param {string} name - attribute name
253 * @param {string} val - attribute value
254 */
255Snakeskin$1.Element.prototype.setAttribute = function (name, val) {
256 this.value.setAttribute(name, val);
257};
258
259/**
260 * Returns text content
261 * @return {string}
262 */
263Snakeskin$1.Element.prototype.textContent = function () {
264 return this.value.outerHTML;
265};
266
267/**
268 * Comment constructor
269 *
270 * @constructor
271 * @extends {Snakeskin.Node}
272 *
273 * @param {string} text - comment text
274 * @param {string} renderMode - rendering mode of templates
275 */
276Snakeskin$1.Comment = function (text, renderMode) {
277 this.renderMode = renderMode;
278 this.value = document.createComment(text);
279};
280
281inherit(Snakeskin$1.Comment, Snakeskin$1.Node);
282
283/**
284 * Text constructor
285 *
286 * @constructor
287 * @extends {Snakeskin.Node}
288 *
289 * @param {string} text
290 * @param {string} renderMode - rendering mode of templates
291 */
292Snakeskin$1.Text = function (text, renderMode) {
293 this.renderMode = renderMode;
294 this.value = document.createTextNode(text);
295};
296
297inherit(Snakeskin$1.Text, Snakeskin$1.Node);
298
299/**
300 * Map of inline tag names
301 * @const
302 */
303Snakeskin$1.inlineTags = {
304 'html': {
305 'area': 'href',
306 'base': 'href',
307 'br': true,
308 'col': true,
309 'embed': 'src',
310 'hr': true,
311 'img': 'src',
312 'input': 'value',
313 'link': 'href',
314 'meta': 'content',
315 'param': 'value',
316 'source': 'src',
317 'track': 'src',
318 'wbr': true
319 },
320
321 'xml': {}
322};
323
324/**
325 * Appends a value to the specified element
326 *
327 * @param {(!Snakeskin.DocumentFragment|!Snakeskin.Element)} el - base element
328 * @param {?} val - value for appending
329 * @param {string} renderMode - rendering mode of templates
330 * @return {(!Snakeskin.Element|!Snakeskin.Comment|!Snakeskin.Text)}
331 */
332Snakeskin$1.appendChild = function (el, val, renderMode) {
333 if (val instanceof Snakeskin$1.Node === false) {
334 val = new Snakeskin$1.Text(String(val), renderMode);
335 }
336
337 if (el) {
338 el.appendChild(val.value);
339 }
340
341 return val;
342};
343
344/**
345 * Sets an attribute to the specified element
346 *
347 * @param {!Snakeskin.Node} node - source element
348 * @param {string} name - attribute name
349 * @param {?} val - attribute value
350 */
351Snakeskin$1.setAttribute = function (node, name, val) {
352 node.setAttribute(name, val instanceof Snakeskin$1.Node ? val.textContent() : String(val));
353};
354
355var keys = function () {
356 return (/\[native code]/.test(Object.keys && Object.keys.toString()) && Object.keys
357 );
358}();
359
360/**
361 * Common iterator
362 * (with hasOwnProperty for objects)
363 *
364 * @param {(Array|Object|undefined)} obj - source object
365 * @param {(
366 * function(?, ?, !Array, {isFirst: boolean, isLast: boolean, length: number})|
367 * function(?, ?, !Object, {i: number, isFirst: boolean, isLast: boolean, length: number})
368 * )} callback - callback function
369 */
370Snakeskin$1.forEach = function (obj, callback) {
371 if (!obj) {
372 return;
373 }
374
375 var length = 0;
376
377 if (isArray(obj)) {
378 length = obj.length;
379 for (var i = 0; i < length; i++) {
380 if (callback(obj[i], i, obj, { isFirst: i === 0, isLast: i === length - 1, length: length }) === false) {
381 break;
382 }
383 }
384 } else if (keys) {
385 var arr = keys(obj);
386
387 length = arr.length;
388 for (var _i = 0; _i < length; _i++) {
389 if (callback(obj[arr[_i]], arr[_i], obj, { i: _i, isFirst: _i === 0, isLast: _i === length - 1, length: length }) === false) {
390 break;
391 }
392 }
393 } else {
394 if (callback.length >= 4) {
395 for (var key in obj) {
396 if (!obj.hasOwnProperty(key)) {
397 break;
398 }
399
400 length++;
401 }
402 }
403
404 var _i2 = 0;
405 for (var _key in obj) {
406 if (!obj.hasOwnProperty(_key)) {
407 break;
408 }
409
410 if (callback(obj[_key], _key, obj, { i: _i2, isFirst: _i2 === 0, isLast: _i2 === length - 1, length: length }) === false) {
411 break;
412 }
413
414 _i2++;
415 }
416 }
417};
418
419/**
420 * Object iterator
421 * (without hasOwnProperty)
422 *
423 * @param {(Object|undefined)} obj - source object
424 * @param {function(?, string, !Object, {i: number, isFirst: boolean, isLast: boolean, length: number})} callback - callback function
425 */
426Snakeskin$1.forIn = function (obj, callback) {
427 if (!obj) {
428 return;
429 }
430
431 var length = 0,
432 i = 0;
433
434 if (callback.length >= 4) {
435 /* eslint-disable guard-for-in */
436 for (var ignore in obj) {
437 length++;
438 }
439 /* eslint-enable guard-for-in */
440 }
441
442 for (var key in obj) {
443 if (callback(obj[key], key, obj, { i: i, isFirst: i === 0, isLast: i === length - 1, length: length }) === false) {
444 break;
445 }
446
447 i++;
448 }
449};
450
451/**
452 * Decorates a function by another functions
453 *
454 * @param {!Array<!Function>} decorators - array of decorator functions
455 * @param {!Function} fn - source function
456 * @return {!Function}
457 */
458Snakeskin$1.decorate = function (decorators, fn) {
459 Snakeskin$1.forEach(decorators, function (decorator) {
460 return fn = decorator(fn) || fn;
461 });
462 fn.decorators = decorators;
463 return fn;
464};
465
466/**
467 * Gets an object with an undefined type
468 * (for the GCC)
469 *
470 * @param {?} val - source object
471 * @return {?}
472 */
473function any(val) {
474 return val;
475}
476
477var wsRgxp = /^\s+|[\r\n]+/mg;
478
479/**
480 * String tag (for ES6 string templates) for truncate starting whitespaces and eol-s
481 *
482 * @param {!Array<string>} strings
483 * @param {...?} expr
484 * @return {string}
485 */
486function ws(strings, expr) {
487 expr = Array.from(arguments).slice(1);
488
489 var res = '';
490
491 for (var i = 0; i < strings.length; i++) {
492 res += strings[i].replace(wsRgxp, ' ') + (i in expr ? expr[i] : '');
493 }
494
495 return res;
496}
497
498var rRgxp = /([\\/'*+?|()[\]{}.^$-])/g;
499
500/**
501 * Escapes RegExp characters in a string
502 *
503 * @param {string} str - source string
504 * @return {string}
505 */
506function r(str) {
507 return str.replace(rRgxp, '\\$1');
508}
509
510var isNotPrimitiveRgxp = /^\(*\s*(.*?)\s*\)*$/;
511var isNotPrimitiveMap = { 'false': true, 'null': true, 'true': true, 'undefined': true };
512
513/**
514 * Returns true if the specified string can't be parse as a primitive value
515 *
516 * @param {string} str - source string
517 * @param {Object<string, boolean>=} opt_map - map of primitives
518 * @return {boolean}
519 */
520function isNotPrimitive(str, opt_map) {
521 str = ((isNotPrimitiveRgxp.exec(str) || [])[1] || '').trim();
522 return Boolean(str && isNaN(Number(str)) && !(opt_map || isNotPrimitiveMap)[str]);
523}
524
525var templateRank = {
526 'interface': 1,
527 'placeholder': 0,
528 'template': 2
529};
530
531var stringRender = {
532 'stringBuffer': true,
533 'stringConcat': true
534};
535
536var attrSeparators = {
537 '-': true,
538 ':': true,
539 '_': true
540};
541
542var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
543 return typeof obj;
544} : function (obj) {
545 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
546};
547
548
549
550
551
552var asyncGenerator = function () {
553 function AwaitValue(value) {
554 this.value = value;
555 }
556
557 function AsyncGenerator(gen) {
558 var front, back;
559
560 function send(key, arg) {
561 return new Promise(function (resolve, reject) {
562 var request = {
563 key: key,
564 arg: arg,
565 resolve: resolve,
566 reject: reject,
567 next: null
568 };
569
570 if (back) {
571 back = back.next = request;
572 } else {
573 front = back = request;
574 resume(key, arg);
575 }
576 });
577 }
578
579 function resume(key, arg) {
580 try {
581 var result = gen[key](arg);
582 var value = result.value;
583
584 if (value instanceof AwaitValue) {
585 Promise.resolve(value.value).then(function (arg) {
586 resume("next", arg);
587 }, function (arg) {
588 resume("throw", arg);
589 });
590 } else {
591 settle(result.done ? "return" : "normal", result.value);
592 }
593 } catch (err) {
594 settle("throw", err);
595 }
596 }
597
598 function settle(type, value) {
599 switch (type) {
600 case "return":
601 front.resolve({
602 value: value,
603 done: true
604 });
605 break;
606
607 case "throw":
608 front.reject(value);
609 break;
610
611 default:
612 front.resolve({
613 value: value,
614 done: false
615 });
616 break;
617 }
618
619 front = front.next;
620
621 if (front) {
622 resume(front.key, front.arg);
623 } else {
624 back = null;
625 }
626 }
627
628 this._invoke = send;
629
630 if (typeof gen.return !== "function") {
631 this.return = undefined;
632 }
633 }
634
635 if (typeof Symbol === "function" && Symbol.asyncIterator) {
636 AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
637 return this;
638 };
639 }
640
641 AsyncGenerator.prototype.next = function (arg) {
642 return this._invoke("next", arg);
643 };
644
645 AsyncGenerator.prototype.throw = function (arg) {
646 return this._invoke("throw", arg);
647 };
648
649 AsyncGenerator.prototype.return = function (arg) {
650 return this._invoke("return", arg);
651 };
652
653 return {
654 wrap: function (fn) {
655 return function () {
656 return new AsyncGenerator(fn.apply(this, arguments));
657 };
658 },
659 await: function (value) {
660 return new AwaitValue(value);
661 }
662 };
663}();
664
665
666
667
668
669var classCallCheck = function (instance, Constructor) {
670 if (!(instance instanceof Constructor)) {
671 throw new TypeError("Cannot call a class as a function");
672 }
673};
674
675
676
677
678
679
680
681var defineProperty = function (obj, key, value) {
682 if (key in obj) {
683 Object.defineProperty(obj, key, {
684 value: value,
685 enumerable: true,
686 configurable: true,
687 writable: true
688 });
689 } else {
690 obj[key] = value;
691 }
692
693 return obj;
694};
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716var slicedToArray = function () {
717 function sliceIterator(arr, i) {
718 var _arr = [];
719 var _n = true;
720 var _d = false;
721 var _e = undefined;
722
723 try {
724 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
725 _arr.push(_s.value);
726
727 if (i && _arr.length === i) break;
728 }
729 } catch (err) {
730 _d = true;
731 _e = err;
732 } finally {
733 try {
734 if (!_n && _i["return"]) _i["return"]();
735 } finally {
736 if (_d) throw _e;
737 }
738 }
739
740 return _arr;
741 }
742
743 return function (arr, i) {
744 if (Array.isArray(arr)) {
745 return arr;
746 } else if (Symbol.iterator in Object(arr)) {
747 return sliceIterator(arr, i);
748 } else {
749 throw new TypeError("Invalid attempt to destructure non-iterable instance");
750 }
751 };
752}();
753
754
755
756var taggedTemplateLiteral = function (strings, raw) {
757 return Object.freeze(Object.defineProperties(strings, {
758 raw: {
759 value: Object.freeze(raw)
760 }
761 }));
762};
763
764var _COMMENTS;
765var _BASE_SYS_ESCAPES;
766var _SYS_ESCAPES;
767var _STRONG_SYS_ESCAPES;
768
769// The base directive separators
770// >>>
771
772var LEFT_BOUND = '{';
773var RIGHT_BOUND = '}';
774var ADV_LEFT_BOUND = '#';
775
776// <<<
777// The additional directive separators
778// >>>
779
780var I18N = '`';
781
782var JS_DOC = '/**';
783var SINGLE_COMMENT = '///';
784var MULT_COMMENT_START = '/*';
785var MULT_COMMENT_END = '*/';
786
787var COMMENTS = (_COMMENTS = {}, defineProperty(_COMMENTS, SINGLE_COMMENT, SINGLE_COMMENT), defineProperty(_COMMENTS, MULT_COMMENT_START, MULT_COMMENT_START), defineProperty(_COMMENTS, MULT_COMMENT_END, MULT_COMMENT_END), _COMMENTS);
788
789var MICRO_TEMPLATE = '${';
790
791var BASE_SHORTS = defineProperty({
792 '-': true
793}, ADV_LEFT_BOUND, true);
794
795var SHORTS = {};
796
797Snakeskin$1.forEach(BASE_SHORTS, function (el, key) {
798 return SHORTS[key] = true;
799});
800
801// <<<
802// The context modifiers
803// >>>
804
805var G_MOD = '@';
806
807// <<<
808// Jade-Like
809// >>>
810
811var CONCAT = '&';
812var CONCAT_END = '.';
813var IGNORE = '|';
814var INLINE = ' :: ';
815
816// <<<
817// The filter modifiers
818// >>>
819
820var FILTER = '|';
821
822// <<<
823// Escaping
824// >>>
825
826var BASE_SYS_ESCAPES = (_BASE_SYS_ESCAPES = {
827 '\\': true,
828 '"': true,
829 '\'': true,
830 '/': true
831}, defineProperty(_BASE_SYS_ESCAPES, I18N, true), defineProperty(_BASE_SYS_ESCAPES, LEFT_BOUND, true), defineProperty(_BASE_SYS_ESCAPES, SINGLE_COMMENT.charAt(0), true), defineProperty(_BASE_SYS_ESCAPES, MULT_COMMENT_START.charAt(0), true), _BASE_SYS_ESCAPES);
832
833var SYS_ESCAPES = (_SYS_ESCAPES = {
834 '\\': true
835}, defineProperty(_SYS_ESCAPES, I18N, true), defineProperty(_SYS_ESCAPES, LEFT_BOUND, true), defineProperty(_SYS_ESCAPES, ADV_LEFT_BOUND, true), defineProperty(_SYS_ESCAPES, SINGLE_COMMENT.charAt(0), true), defineProperty(_SYS_ESCAPES, MULT_COMMENT_START.charAt(0), true), defineProperty(_SYS_ESCAPES, CONCAT, true), defineProperty(_SYS_ESCAPES, CONCAT_END, true), defineProperty(_SYS_ESCAPES, IGNORE, true), defineProperty(_SYS_ESCAPES, INLINE.trim().charAt(0), true), _SYS_ESCAPES);
836
837Snakeskin$1.forEach(BASE_SHORTS, function (el, key) {
838 return SYS_ESCAPES[key.charAt(0)] = true;
839});
840
841var STRONG_SYS_ESCAPES = (_STRONG_SYS_ESCAPES = {
842 '\\': true
843}, defineProperty(_STRONG_SYS_ESCAPES, I18N, true), defineProperty(_STRONG_SYS_ESCAPES, SINGLE_COMMENT.charAt(0), true), defineProperty(_STRONG_SYS_ESCAPES, MULT_COMMENT_START.charAt(0), true), _STRONG_SYS_ESCAPES);
844
845var MICRO_TEMPLATE_ESCAPES = defineProperty({
846 '\\': true
847}, MICRO_TEMPLATE.charAt(0), true);
848
849var ESCAPES = {
850 '"': true,
851 '\'': true,
852 '/': true
853};
854
855var ESCAPES_END = {
856 '-': true,
857 '+': true,
858 '*': true,
859 '%': true,
860 '~': true,
861 '>': true,
862 '<': true,
863 '^': true,
864 ',': true,
865 ';': true,
866 '=': true,
867 '|': true,
868 '&': true,
869 '!': true,
870 '?': true,
871 ':': true,
872 '(': true,
873 '{': true,
874 '[': true
875};
876
877var ESCAPES_END_WORD = {
878 'return': true,
879 'yield': true,
880 'await': true,
881 'typeof': true,
882 'void': true,
883 'instanceof': true,
884 'delete': true,
885 'in': true,
886 'new': true
887};
888
889var B_OPEN = {
890 '(': true,
891 '[': true,
892 '{': true
893};
894
895var B_CLOSE = {
896 ')': true,
897 ']': true,
898 '}': true
899};
900
901var P_OPEN = {
902 '(': true,
903 '[': true
904};
905
906var P_CLOSE = {
907 ')': true,
908 ']': true
909};
910
911// <<<
912// The reserved names
913// >>>
914
915var SYS_CONSTS = {
916 '__REQUIRE__': true,
917 '__RESULT__': true,
918 '__STRING_RESULT__': true,
919 '__CDATA__': true,
920 '__RETURN__': true,
921 '__RETURN_VAL__': true,
922 '__LENGTH__': true,
923 '__ESCAPE_D_Q__': true,
924 '__ATTR_STR__': true,
925 '__ATTR_CONCAT_MAP__': true,
926 '__TARGET_REF__': true,
927 '__CALL_POS__': true,
928 '__CALL_TMP__': true,
929 '__CALL_CACHE__': true,
930 '__FILTERS__': true,
931 '__VARS__': true,
932 '__LOCAL__': true,
933 '__THIS__': true,
934 '__INCLUDE__': true,
935 '__INLINE_TAG__': true,
936 '__INLINE_TAGS__': true,
937 '__NODE__': true,
938 '__JOIN__': true,
939 '__GET_XML_ATTR_KEY_DECL__': true,
940 '__APPEND_XML_ATTR_VAL__': true,
941 '__GET_XML_ATTRS_DECL_START__': true,
942 '__GET_XML_TAG_DECL_END__': true,
943 '__GET_END_XML_TAG_DECL__': true,
944 '__TARGET_END__': true,
945 '__PUTIN_CALL__': true,
946 '__PUTIN_TARGET__': true,
947 '__SNAKESKIN_MODULES__': true,
948 '__SNAKESKIN_MODULES_DECL__': true,
949 'GLOBAL': true,
950 'TRUE': true,
951 'FALSE': true,
952 'module': true,
953 'exports': true,
954 'require': true,
955 '__dirname': true,
956 '__filename': true,
957 'TPL_NAME': true,
958 'PARENT_TPL_NAME': true,
959 'EOL': true,
960 'Raw': true,
961 'Unsafe': true,
962 'Snakeskin': true,
963 'getTplResult': true,
964 'clearTplResult': true,
965 'arguments': true,
966 'self': true,
967 'callee': true,
968 '$_': true,
969 '$0': true,
970 '$class': true,
971 '$tagName': true,
972 '$attrKey': true,
973 '$attrType': true,
974 '$attrs': true
975};
976
977var scopeMod = new RegExp('^' + r(G_MOD) + '+');
978var escaperPart = /^(?:__ESCAPER_QUOT__|__CDATA__)\d+_/;
979
980var tmpSep = [];
981
982Snakeskin$1.forEach(attrSeparators, function (el, key) {
983 tmpSep.push(r(key));
984});
985
986var emptyCommandParams = new RegExp('^([^\\s]+?[' + tmpSep.join('') + ']\\(|\\()');
987
988var eol = /\r?\n|\r/;
989var ws$1 = /\s/;
990var lineWs = / |\t/;
991var wsStart = new RegExp('^[ \\t]*(?:' + eol.source + ')');
992var wsEnd = new RegExp('^(?:' + eol.source + ')[ \\t]*$');
993
994var bEnd = /[^\s\/]/;
995var sysWord = /[a-z]/;
996var attrKey = /([^\s=]+)/;
997
998var backSlashes = /\\/g;
999var singleQuotes = /'/g;
1000var doubleQuotes = /"/g;
1001
1002var symbols = '\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1' + '\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C' + '\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0525\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA' + '\\u05F0-\\u05F2\\u0621-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC' + '\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA' + '\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971\\u0972\\u0979-\\u097F' + '\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD' + '\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35' + '\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8' + '\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10' + '\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83' + '\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA' + '\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58' + '\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE' + '\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F' + '\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46' + '\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7' + '\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47' + '\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066' + '\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10D0-\\u10FA\\u10FC\\u1100-\\u1248\\u124A-\\u124D' + '\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE' + '\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4' + '\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731' + '\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA' + '\\u18B0-\\u18F5\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16' + '\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F' + '\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45' + '\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE' + '\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071' + '\\u207F\\u2090-\\u2094\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D' + '\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4' + '\\u2CEB-\\u2CEE\\u2D00-\\u2D25\\u2D30-\\u2D65\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6' + '\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035' + '\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E' + '\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCB\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C' + '\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA65F\\uA662-\\uA66E\\uA67F-\\uA697\\uA6A0-\\uA6E5\\uA717-\\uA71F' + '\\uA722-\\uA788\\uA78B\\uA78C\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873' + '\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF' + '\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA80-\\uAAAF\\uAAB1\\uAAB5\\uAAB6' + '\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB' + '\\uF900-\\uFA2D\\uFA30-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36' + '\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7' + '\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7' + '\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC';
1003
1004var filterStart = new RegExp('[!$' + symbols + '_]');
1005var w = '$' + symbols + '0-9_';
1006
1007var Filters = Snakeskin$1.Filters;
1008
1009/**
1010 * Imports an object to Filters
1011 *
1012 * @param {!Object} filters - import object
1013 * @param {?string=} [opt_namespace] - namespace for saving, for example foo.bar
1014 * @return {!Object}
1015 */
1016
1017Snakeskin$1.importFilters = function (filters, opt_namespace) {
1018 var obj = Filters;
1019
1020 if (opt_namespace) {
1021 Snakeskin$1.forEach(opt_namespace.split('.'), function (el) {
1022 obj[el] = obj[el] || {};
1023 obj = obj[el];
1024 });
1025 }
1026
1027 Snakeskin$1.forEach(filters, function (el, key) {
1028 return obj[key] = el;
1029 });
1030
1031 return this;
1032};
1033
1034/**
1035 * Sets parameters to the specified Snakeskin filter
1036 *
1037 * @param {(string|!Function)} filter - filter name or the filter function
1038 * @param {Object} params - parameters
1039 * @return {!Function}
1040 */
1041Snakeskin$1.setFilterParams = function (filter, params) {
1042 var safe = params['safe'];
1043
1044 if (safe) {
1045 params['bind'] = ['Unsafe'].concat(params['bind'] || []);
1046 }
1047
1048 var tmp = void 0;
1049 function wrapper(val, Unsafe) {
1050 var _tmp2;
1051
1052 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
1053 args[_key - 2] = arguments[_key];
1054 }
1055
1056 if (val && isFunction(Unsafe) && val instanceof Unsafe) {
1057 var _tmp;
1058
1059 val.value = (_tmp = tmp).call.apply(_tmp, [this, val.value].concat(args));
1060 return val;
1061 }
1062
1063 return (_tmp2 = tmp).call.apply(_tmp2, [this, val].concat(args));
1064 }
1065
1066 if (isString(filter)) {
1067 if (safe) {
1068 tmp = Filters[filter];
1069 Filters[filter] = wrapper;
1070 }
1071
1072 Filters[filter] = Filters[filter] || function (str) {
1073 return str;
1074 };
1075 Filters[filter]['ssFilterParams'] = params;
1076 return Filters[filter];
1077 }
1078
1079 if (safe) {
1080 tmp = filter;
1081 filter = wrapper;
1082 }
1083
1084 filter['ssFilterParams'] = params;
1085 return any(filter);
1086};
1087
1088/**
1089 * Console API
1090 * @const
1091 */
1092Filters['console'] = {
1093 /**
1094 * @param {?} val
1095 * @return {?}
1096 */
1097 'dir': function dir(val) {
1098 var _console;
1099
1100 (_console = console).dir.apply(_console, arguments);
1101 return val;
1102 },
1103
1104
1105 /**
1106 * @param {?} val
1107 * @return {?}
1108 */
1109 'error': function error(val) {
1110 var _console2;
1111
1112 (_console2 = console).error.apply(_console2, arguments);
1113 return val;
1114 },
1115
1116
1117 /**
1118 * @param {?} val
1119 * @return {?}
1120 */
1121 'info': function info(val) {
1122 var _console3;
1123
1124 (_console3 = console).info.apply(_console3, arguments);
1125 return val;
1126 },
1127
1128
1129 /**
1130 * @param {?} val
1131 * @return {?}
1132 */
1133 'log': function log(val) {
1134 var _console4;
1135
1136 (_console4 = console).log.apply(_console4, arguments);
1137 return val;
1138 },
1139
1140
1141 /**
1142 * @param {?} val
1143 * @return {?}
1144 */
1145 'table': function table(val) {
1146 var _console5;
1147
1148 (_console5 = console).table.apply(_console5, arguments);
1149 return val;
1150 },
1151
1152
1153 /**
1154 * @param {?} val
1155 * @return {?}
1156 */
1157 'warn': function warn(val) {
1158 var _console6;
1159
1160 (_console6 = console).warn.apply(_console6, arguments);
1161 return val;
1162 }
1163};
1164
1165var entityMap = {
1166 '"': '&quot;',
1167 '&': '&amp;',
1168 '\'': '&#39;',
1169 '<': '&lt;',
1170 '>': '&gt;'
1171};
1172
1173var escapeHTMLRgxp = /[<>"'/]|&(?!#|[a-z]+;)/g;
1174var escapeHTML = function escapeHTML(s) {
1175 return entityMap[s] || s;
1176};
1177
1178var uentityMap = {
1179 '&#39;': '\'',
1180 '&#x2F;': '/',
1181 '&amp;': '&',
1182 '&gt;': '>',
1183 '&lt;': '<',
1184 '&quot;': '"'
1185};
1186
1187var uescapeHTMLRgxp = /&amp;|&lt;|&gt;|&quot;|&#39;|&#x2F;/g;
1188var uescapeHTML = function uescapeHTML(s) {
1189 return uentityMap[s];
1190};
1191
1192/**
1193 * Escapes HTML entities from a string
1194 *
1195 * @param {?} val - source value
1196 * @param {?=} [opt_Unsafe] - unsafe class constructor
1197 * @param {?string=} [opt_attr] - type of attribute declaration
1198 * @param {Object=} [opt_attrCache] - attribute cache object
1199 * @param {?=} [opt_true] - true value
1200 * @return {(string|!Snakeskin.HTMLObject|!Snakeskin.Node)}
1201 */
1202Filters['html'] = function (val, opt_Unsafe, opt_attr, opt_attrCache, opt_true) {
1203 if (!val || val instanceof Snakeskin$1.Node) {
1204 return val;
1205 }
1206
1207 if (val instanceof Snakeskin$1.HTMLObject) {
1208 Snakeskin$1.forEach(val.value, function (el, key, data) {
1209 if (val.attr) {
1210 opt_attrCache[key] = data[key] = el[0] !== opt_true ? [Filters['html'](el[0], opt_Unsafe, val.attr, opt_attrCache, opt_true)] : el;
1211 } else {
1212 data[key] = Filters['html'](el, opt_Unsafe);
1213 }
1214 });
1215
1216 return val;
1217 }
1218
1219 if (isFunction(opt_Unsafe) && val instanceof opt_Unsafe) {
1220 return val.value;
1221 }
1222
1223 return String(opt_attr ? Filters[opt_attr](val) : val).replace(escapeHTMLRgxp, escapeHTML);
1224};
1225
1226Snakeskin$1.setFilterParams('html', {
1227 bind: ['Unsafe', '$attrType', function (o) {
1228 return o.getVar('$attrs');
1229 }, 'TRUE'],
1230 test: function test(val) {
1231 return isNotPrimitive(val);
1232 }
1233});
1234
1235Filters['htmlObject'] = function (val) {
1236 if (val instanceof Snakeskin$1.HTMLObject) {
1237 return '';
1238 }
1239
1240 return val;
1241};
1242
1243Snakeskin$1.setFilterParams('htmlObject', {
1244 test: function test(val) {
1245 return isNotPrimitive(val);
1246 }
1247});
1248
1249/**
1250 * Replaces undefined to ''
1251 *
1252 * @param {?} val - source value
1253 * @return {?}
1254 */
1255Filters['undef'] = function (val) {
1256 return val !== undefined ? val : '';
1257};
1258
1259Snakeskin$1.setFilterParams('undef', {
1260 test: function test(val) {
1261 return isNotPrimitive(val, { 'false': true, 'null': true, 'true': true });
1262 }
1263});
1264
1265/**
1266 * Replaces escaped HTML entities to real content
1267 *
1268 * @param {?} val - source value
1269 * @return {string}
1270 */
1271Filters['uhtml'] = function (val) {
1272 return String(val).replace(uescapeHTMLRgxp, uescapeHTML);
1273};
1274
1275var stripTagsRgxp = /<\/?[^>]+>/g;
1276
1277/**
1278 * Removes < > from a string
1279 *
1280 * @param {?} val - source value
1281 * @return {string}
1282 */
1283Filters['stripTags'] = function (val) {
1284 return String(val).replace(stripTagsRgxp, '');
1285};
1286
1287var uriO = /%5B/g;
1288var uriC = /%5D/g;
1289
1290/**
1291 * Encodes URL
1292 *
1293 * @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURI
1294 * @param {?} val - source value
1295 * @return {string}
1296 */
1297Filters['uri'] = function (val) {
1298 return encodeURI(String(val)).replace(uriO, '[').replace(uriC, ']');
1299};
1300
1301Snakeskin$1.setFilterParams('uri', {
1302 safe: true
1303});
1304
1305/**
1306 * Converts a string to uppercase
1307 *
1308 * @param {?} val - source value
1309 * @return {string}
1310 */
1311Filters['upper'] = function (val) {
1312 return String(val).toUpperCase();
1313};
1314
1315Snakeskin$1.setFilterParams('upper', {
1316 safe: true
1317});
1318
1319/**
1320 * Converts the first letter of a string to uppercase
1321 *
1322 * @param {?} val - source value
1323 * @return {string}
1324 */
1325Filters['ucfirst'] = function (val) {
1326 val = String(val);
1327 return val.charAt(0).toUpperCase() + val.slice(1);
1328};
1329
1330Snakeskin$1.setFilterParams('ucfirst', {
1331 safe: true
1332});
1333
1334/**
1335 * Converts a string to lowercase
1336 *
1337 * @param {?} val - source value
1338 * @return {string}
1339 */
1340Filters['lower'] = function (val) {
1341 return String(val).toLowerCase();
1342};
1343
1344Snakeskin$1.setFilterParams('lower', {
1345 safe: true
1346});
1347
1348/**
1349 * Converts the first letter of a string to lowercase
1350 *
1351 * @param {?} val - source value
1352 * @return {string}
1353 */
1354Filters['lcfirst'] = function (val) {
1355 val = String(val);
1356 return val.charAt(0).toLowerCase() + val.slice(1);
1357};
1358
1359Snakeskin$1.setFilterParams('lcfirst', {
1360 safe: true
1361});
1362
1363/**
1364 * Removes whitespace from both ends of a string
1365 *
1366 * @param {?} val - source value
1367 * @return {string}
1368 */
1369Filters['trim'] = function (val) {
1370 return String(val).trim();
1371};
1372
1373Snakeskin$1.setFilterParams('trim', {
1374 safe: true
1375});
1376
1377var spaceCollapseRgxp = /\s{2,}/g;
1378
1379/**
1380 * Removes whitespace from both ends of a string
1381 * and collapses whitespace
1382 *
1383 * @param {?} val - source value
1384 * @return {string}
1385 */
1386Filters['collapse'] = function (val) {
1387 return String(val).replace(spaceCollapseRgxp, ' ').trim();
1388};
1389
1390Snakeskin$1.setFilterParams('collapse', {
1391 safe: true
1392});
1393
1394/**
1395 * Truncates a string to the specified length
1396 * (at the end puts three dots)
1397 *
1398 * @param {?} val - source value
1399 * @param {number} length - maximum length
1400 * @param {?boolean=} opt_wordOnly - if is false, then the string will be truncated without
1401 * taking into account the integrity of the words
1402 *
1403 * @param {?boolean=} opt_html - if is true, then the dots will be inserted as HTML-mnemonic
1404 * @return {string}
1405 */
1406Filters['truncate'] = function (val, length, opt_wordOnly, opt_html) {
1407 val = String(val);
1408 if (!val || val.length <= length) {
1409 return val;
1410 }
1411
1412 var tmp = val.slice(0, length - 1);
1413
1414 var i = tmp.length,
1415 lastInd = void 0;
1416
1417 while (i-- && opt_wordOnly) {
1418 if (tmp.charAt(i) === ' ') {
1419 lastInd = i;
1420 } else if (lastInd !== undefined) {
1421 break;
1422 }
1423 }
1424
1425 return (lastInd !== undefined ? tmp.slice(0, lastInd) : tmp) + (opt_html ? '&#8230;' : '…');
1426};
1427
1428/**
1429 * Returns a new string of repetitions of a string
1430 *
1431 * @param {?} val - source value
1432 * @param {?number=} opt_num - number of repetitions
1433 * @return {string}
1434 */
1435Filters['repeat'] = function (val, opt_num) {
1436 return new Array(opt_num != null ? opt_num + 1 : 3).join(val);
1437};
1438
1439Snakeskin$1.setFilterParams('repeat', {
1440 safe: true
1441});
1442
1443/**
1444 * Removes a slice from a string
1445 *
1446 * @param {?} val - source value
1447 * @param {(string|RegExp)} search - searching slice
1448 * @return {string}
1449 */
1450Filters['remove'] = function (val, search) {
1451 return String(val).replace(search, '');
1452};
1453
1454/**
1455 * Replaces a slice from a string to a new string
1456 *
1457 * @param {?} val - source value
1458 * @param {(string|!RegExp)} search - searching slice
1459 * @param {string} replace - string for replacing
1460 * @return {string}
1461 */
1462Filters['replace'] = function (val, search, replace) {
1463 return String(val).replace(search, replace);
1464};
1465
1466var tplRgxp = /\${(.*?)}/g;
1467
1468/**
1469 * Returns a string result of the specified template
1470 *
1471 * @example
1472 * 'hello ${name}' |tpl {name: 'Kobezzza'}
1473 *
1474 * @param {?} tpl - source template
1475 * @param {!Object} map - map of values
1476 * @return {string}
1477 */
1478Filters['tpl'] = function (tpl, map) {
1479 return String(tpl).replace(tplRgxp, function (str, $0) {
1480 return $0 in map ? map[$0] : '';
1481 });
1482};
1483
1484/**
1485 * Converts a value to JSON
1486 *
1487 * @param {(Object|Array|string|number|boolean)} val - source value
1488 * @return {string}
1489 */
1490Filters['json'] = function (val) {
1491 return JSON.stringify(val);
1492};
1493
1494/**
1495 * Converts a value to a string
1496 *
1497 * @param {(Object|Array|string|number|boolean)} val - source value
1498 * @return {string}
1499 */
1500Filters['string'] = function (val) {
1501 if ((typeof val === 'undefined' ? 'undefined' : _typeof(val)) === 'object' && val instanceof String === false) {
1502 return JSON.stringify(val);
1503 }
1504
1505 return String(val);
1506};
1507
1508/**
1509 * Parses a string as JSON
1510 *
1511 * @param {?} val - source value
1512 * @return {?}
1513 */
1514Filters['parse'] = function (val) {
1515 if (!isString(val)) {
1516 return val;
1517 }
1518
1519 return JSON.parse(val);
1520};
1521
1522/**
1523 * Sets a default value for the specified parameter
1524 *
1525 * @param {?} val - source value
1526 * @param {?} def - value
1527 * @return {?}
1528 */
1529Filters['default'] = function (val, def) {
1530 return val === undefined ? def : val;
1531};
1532
1533Snakeskin$1.setFilterParams('default', {
1534 '!undef': true
1535});
1536
1537var nl2brRgxp = /\r?\n|\n/g;
1538
1539/**
1540 * Replaces EOL symbols from a string to <br>
1541 *
1542 * @param {?} val - source value
1543 * @param {(!Snakeskin.DocumentFragment|!Snakeskin.Element|undefined)} node - source node
1544 * @param {string} renderMode - rendering mode of templates
1545 * @param {boolean} stringResult - if is true, then the output will be saved to __STRING_RESULT__ as a string
1546 * @param {string} doctype - document type
1547 * @return {?}
1548 */
1549Filters['nl2br'] = function (val, node, renderMode, stringResult, doctype) {
1550 var arr = val.split(nl2brRgxp);
1551
1552 var res = '';
1553 for (var i = 0; i < arr.length; i++) {
1554 var el = arr[i],
1555 last = i === arr.length - 1;
1556
1557 if (!stringResult && !stringRender[renderMode]) {
1558 Snakeskin$1.appendChild(any(node), el, renderMode);
1559 if (!last) {
1560 Snakeskin$1.appendChild(any(node), new Snakeskin$1.Element('br', renderMode), renderMode);
1561 }
1562 } else {
1563 res += Filters['html'](el);
1564 if (!last) {
1565 res += '<br' + (doctype === 'xml' ? '/' : '') + '>';
1566 }
1567 }
1568 }
1569
1570 return res;
1571};
1572
1573Snakeskin$1.setFilterParams('nl2br', {
1574 '!html': true,
1575 bind: ['$0', function (o) {
1576 return '\'' + o.renderMode + '\'';
1577 }, function (o) {
1578 return o.stringResult;
1579 }, '$0', function (o) {
1580 return '\'' + o.doctype + '\'';
1581 }]
1582});
1583
1584/**
1585 * @param str
1586 * @return {string}
1587 */
1588function dasherize(str) {
1589 var res = str[0].toLowerCase();
1590
1591 for (var i = 1; i < str.length; i++) {
1592 var el = str.charAt(i),
1593 up = el.toUpperCase();
1594
1595 if (up === el && up !== el.toLowerCase()) {
1596 res += '-' + el;
1597 } else {
1598 res += el;
1599 }
1600 }
1601
1602 return res.toLowerCase();
1603}
1604
1605/**
1606 * Escapes HTML entities from an attribute name
1607 *
1608 * @param {?} val - source value
1609 * @return {string}
1610 */
1611Filters['attrKey'] = function (val) {
1612 var tmp = attrKey.exec(String(val));
1613 return tmp && tmp[1] || 'undefined';
1614};
1615
1616/**
1617 * Escapes HTML entities from an attribute group
1618 *
1619 * @param {?} val - source value
1620 * @return {string}
1621 */
1622Filters['attrKeyGroup'] = function (val) {
1623 var tmp = attrKey.exec(String(val));
1624 return tmp && tmp[1] || '';
1625};
1626
1627var attrValRgxp = /(javascript)(:|;)/g;
1628
1629/**
1630 * Escapes HTML entities from an attribute value
1631 *
1632 * @param {?} val - source value
1633 * @return {string}
1634 */
1635Filters['attrValue'] = function (val) {
1636 return String(val).replace(attrValRgxp, '$1&#31;$2');
1637};
1638
1639/**
1640 * Sets attributes to a node
1641 *
1642 * @param {?} val - source value
1643 * @param {?} Unsafe - unsafe class constructor
1644 * @param {string} doctype - document type
1645 * @param {string} type - type of attribute declaration
1646 * @param {!Object} cache - attribute cache object
1647 * @param {!Boolean} TRUE - true value
1648 * @param {!Boolean} FALSE - false value
1649 * @return {(string|Unsafe|Snakeskin.HTMLObject)}
1650 */
1651Filters['attr'] = function (val, Unsafe, doctype, type, cache, TRUE, FALSE) {
1652 if (type !== 'attrKey' || !isObject(val)) {
1653 if (isFunction(Unsafe) && val instanceof Unsafe) {
1654 return val;
1655 }
1656
1657 return String(val);
1658 }
1659
1660 var localCache = {};
1661
1662 /**
1663 * @param {Object} obj
1664 * @param {?string=} opt_prfx
1665 * @return {Snakeskin.HTMLObject}
1666 */
1667 function convert(obj, opt_prfx) {
1668 opt_prfx = opt_prfx || '';
1669 Snakeskin$1.forEach(obj, function (el, key) {
1670 if (el === FALSE) {
1671 return;
1672 }
1673
1674 if (isObject(el)) {
1675 var group = Filters['attrKeyGroup'](key);
1676 return convert(el, opt_prfx + (!group.length || attrSeparators[group.slice(-1)] ? group : group + '-'));
1677 }
1678
1679 var tmp = dasherize(opt_prfx + key);
1680 cache[tmp] = localCache[tmp] = [el];
1681 });
1682
1683 return new Snakeskin$1.HTMLObject(localCache, 'attrValue');
1684 }
1685
1686 return convert(val);
1687};
1688
1689Snakeskin$1.setFilterParams('attr', {
1690 '!html': true,
1691 bind: ['Unsafe', function (o) {
1692 return '\'' + o.doctype + '\'';
1693 }, '$attrType', function (o) {
1694 return o.getVar('$attrs');
1695 }, 'TRUE', 'FALSE'],
1696 test: function test(val) {
1697 return isNotPrimitive(val);
1698 }
1699});
1700
1701var IS_NODE = function () {
1702 try {
1703 return (typeof process === 'undefined' ? 'undefined' : _typeof(process)) === 'object' && {}.toString.call(process) === '[object process]';
1704 } catch (ignore) {
1705 return false;
1706 }
1707}();
1708
1709var HAS_CONSOLE_LOG = (typeof console === 'undefined' ? 'undefined' : _typeof(console)) === 'object' && console && isFunction(console.log);
1710var HAS_CONSOLE_ERROR = (typeof console === 'undefined' ? 'undefined' : _typeof(console)) === 'object' && console && isFunction(console.error);
1711
1712if (IS_NODE) {
1713 require('core-js/es6');
1714}
1715
1716var GLOBAL = Function('return this')();
1717var ROOT = IS_NODE ? exports : GLOBAL;
1718var NULL = {};
1719
1720var beautify = GLOBAL.js_beautify || require('js-beautify');
1721
1722/**
1723 * Returns an object for require a file
1724 *
1725 * @param {string} ctxFile - context file
1726 * @return {{require: (function(string): ?|undefined), dirname: (string|undefined)}}
1727 */
1728function getRequire(ctxFile) {
1729 if (!IS_NODE) {
1730 return {};
1731 }
1732
1733 if (!ctxFile) {
1734 return { require: require };
1735 }
1736
1737 var path = require('path'),
1738 findNodeModules = require('find-node-modules');
1739
1740 var basePaths = module.paths.slice(),
1741 dirname = path.dirname(ctxFile);
1742
1743 var base = findNodeModules({ cwd: dirname, relative: false }) || [],
1744 modules = base.concat(module.paths || []);
1745
1746 var cache = {},
1747 newPaths = [];
1748
1749 for (var i = 0; i < modules.length; i++) {
1750 var el = modules[i];
1751
1752 if (!cache[el]) {
1753 cache[el] = true;
1754 newPaths.push(el);
1755 }
1756 }
1757
1758 var isRelative = { '/': true, '\\': true, '.': true };
1759
1760 return {
1761 dirname: dirname,
1762 require: function (_require) {
1763 function require(_x) {
1764 return _require.apply(this, arguments);
1765 }
1766
1767 require.toString = function () {
1768 return _require.toString();
1769 };
1770
1771 return require;
1772 }(function (file) {
1773 module.paths = newPaths;
1774
1775 var res = void 0;
1776 if (!path.isAbsolute(file) && isRelative[file[0]]) {
1777 res = require(path.resolve(dirname, file));
1778 } else {
1779 res = require(file);
1780 }
1781
1782 module.paths = basePaths;
1783 return res;
1784 })
1785 };
1786}
1787
1788var _templateObject = taggedTemplateLiteral(['\n\t\t\t\t', '\n\t\t\t\timport Snakeskin from \'', '\';\n\t\t\t\tvar exports = {};\n\t\t\t\texport default exports;\n\t\t\t'], ['\n\t\t\t\t', '\n\t\t\t\timport Snakeskin from \'', '\';\n\t\t\t\tvar exports = {};\n\t\t\t\texport default exports;\n\t\t\t']);
1789var _templateObject2 = taggedTemplateLiteral(['\n\t\t\t\t(function (global, factory) {\n\t\t\t\t\t', '\n\n\t\t\t\t\t', '\n\n\t\t\t\t\t', '\n\n\t\t\t\t})(this, function (exports, Snakeskin', ') {\n\t\t\t\t\t', '\n\t\t\t'], ['\n\t\t\t\t(function (global, factory) {\n\t\t\t\t\t', '\n\n\t\t\t\t\t', '\n\n\t\t\t\t\t', '\n\n\t\t\t\t})(this, function (exports, Snakeskin', ') {\n\t\t\t\t\t', '\n\t\t\t']);
1790var _templateObject3 = taggedTemplateLiteral(['\n\t\t\t\t\t\t\t\tif (typeof exports === \'object\' && typeof module !== \'undefined\') {\n\t\t\t\t\t\t\t\t\tfactory(exports, typeof Snakeskin === \'undefined\' ? require(\'', '\') : Snakeskin);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t'], ['\n\t\t\t\t\t\t\t\tif (typeof exports === \'object\' && typeof module !== \'undefined\') {\n\t\t\t\t\t\t\t\t\tfactory(exports, typeof Snakeskin === \'undefined\' ? require(\'', '\') : Snakeskin);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t']);
1791var _templateObject4 = taggedTemplateLiteral(['\n\t\t\t\t\t\t\t\tif (typeof define === \'function\' && define.amd) {\n\t\t\t\t\t\t\t\t\tdefine(\'', '\', [\'exports\', \'snakeskin\'/*#__SNAKESKIN_MODULES_DECL__*/], factory);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t'], ['\n\t\t\t\t\t\t\t\tif (typeof define === \'function\' && define.amd) {\n\t\t\t\t\t\t\t\t\tdefine(\'', '\', [\'exports\', \'snakeskin\'/*#__SNAKESKIN_MODULES_DECL__*/], factory);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t']);
1792var _templateObject5 = taggedTemplateLiteral(['\n\t\t\tvar\n\t\t\t\tGLOBAL = Function(\'return this\')(),\n\t\t\t\t__FILTERS__ = Snakeskin.Filters,\n\t\t\t\t__VARS__ = Snakeskin.Vars,\n\t\t\t\t__LOCAL__ = Snakeskin.LocalVars,\n\t\t\t\t__REQUIRE__;\n\n\t\t\tfunction __LENGTH__(val) {\n\t\t\t\tif (val[0] instanceof Snakeskin.Node) {\n\t\t\t\t\treturn val[0].length();\n\t\t\t\t}\n\n\t\t\t\tif (typeof val === \'string\' || Array.isArray(val)) {\n\t\t\t\t\treturn val.length;\n\t\t\t\t}\n\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tfunction __JOIN__(arr) {\n\t\t\t\tvar str = \'\';\n\t\t\t\tfor (var i = 0; i < arr.length; i++) {\n\t\t\t\t\tstr += arr[i];\n\t\t\t\t}\n\t\t\t\treturn str;\n\t\t\t}\n\n\t\t\tfunction __ESCAPE_D_Q__(str) {\n\t\t\t\treturn String(str).replace(/"/g, "&quot;")\n\t\t\t}\n\n\t\t\tvar\n\t\t\t\tTRUE = new Boolean(true),\n\t\t\t\tFALSE = new Boolean(false);\n\n\t\t\tfunction Raw(val) {\n\t\t\t\tif (!this || this.constructor !== Raw) {\n\t\t\t\t\treturn new Raw(val);\n\t\t\t\t}\n\n\t\t\t\tthis.value = val;\n\t\t\t}\n\n\t\t\tRaw.prototype.push = function (val) {\n\t\t\t\tthis.value += val;\n\t\t\t};\n\n\t\t\tfunction Unsafe(val) {\n\t\t\t\tif (!this || this.constructor !== Unsafe) {\n\t\t\t\t\tif (typeof val === \'string\') {\n\t\t\t\t\t\treturn new Unsafe(val);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn val;\n\t\t\t\t}\n\n\t\t\t\tthis.value = val;\n\t\t\t}\n\n\t\t\tUnsafe.prototype.toString = function () {\n\t\t\t\treturn this.value;\n\t\t\t};\n\n\t\t\t', '\n\t\t'], ['\n\t\t\tvar\n\t\t\t\tGLOBAL = Function(\'return this\')(),\n\t\t\t\t__FILTERS__ = Snakeskin.Filters,\n\t\t\t\t__VARS__ = Snakeskin.Vars,\n\t\t\t\t__LOCAL__ = Snakeskin.LocalVars,\n\t\t\t\t__REQUIRE__;\n\n\t\t\tfunction __LENGTH__(val) {\n\t\t\t\tif (val[0] instanceof Snakeskin.Node) {\n\t\t\t\t\treturn val[0].length();\n\t\t\t\t}\n\n\t\t\t\tif (typeof val === \'string\' || Array.isArray(val)) {\n\t\t\t\t\treturn val.length;\n\t\t\t\t}\n\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tfunction __JOIN__(arr) {\n\t\t\t\tvar str = \'\';\n\t\t\t\tfor (var i = 0; i < arr.length; i++) {\n\t\t\t\t\tstr += arr[i];\n\t\t\t\t}\n\t\t\t\treturn str;\n\t\t\t}\n\n\t\t\tfunction __ESCAPE_D_Q__(str) {\n\t\t\t\treturn String(str).replace(/"/g, "&quot;")\n\t\t\t}\n\n\t\t\tvar\n\t\t\t\tTRUE = new Boolean(true),\n\t\t\t\tFALSE = new Boolean(false);\n\n\t\t\tfunction Raw(val) {\n\t\t\t\tif (!this || this.constructor !== Raw) {\n\t\t\t\t\treturn new Raw(val);\n\t\t\t\t}\n\n\t\t\t\tthis.value = val;\n\t\t\t}\n\n\t\t\tRaw.prototype.push = function (val) {\n\t\t\t\tthis.value += val;\n\t\t\t};\n\n\t\t\tfunction Unsafe(val) {\n\t\t\t\tif (!this || this.constructor !== Unsafe) {\n\t\t\t\t\tif (typeof val === \'string\') {\n\t\t\t\t\t\treturn new Unsafe(val);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn val;\n\t\t\t\t}\n\n\t\t\t\tthis.value = val;\n\t\t\t}\n\n\t\t\tUnsafe.prototype.toString = function () {\n\t\t\t\treturn this.value;\n\t\t\t};\n\n\t\t\t', '\n\t\t']);
1793
1794/**
1795 * The class for parsing SS templates
1796 */
1797
1798var Parser =
1799/**
1800 * @constructor
1801 * @implements {$$SnakeskinParser}
1802 *
1803 * @param {string} src - source text of templates
1804 * @param {$$SnakeskinParserParams} params - additional parameters
1805 */
1806function Parser(src, params) {
1807 classCallCheck(this, Parser);
1808
1809 /** @type {boolean} */
1810 this.throws = params.throws;
1811
1812 /** @type {(?function(!Error)|undefined)} */
1813 this.onError = params.onError;
1814
1815 /** @type {(?function(string, string): string|undefined)} */
1816 this.resolveModuleSource = params.resolveModuleSource;
1817
1818 /** @type {boolean} */
1819 this.pack = params.pack;
1820
1821 /** @type {string} */
1822 this.module = params.module;
1823
1824 /** @type {(?string|undefined)} */
1825 this.moduleId = params.moduleId;
1826
1827 /** @type {(?string|undefined)} */
1828 this.moduleName = params.moduleName;
1829
1830 /** @type {boolean} */
1831 this.useStrict = params.useStrict;
1832
1833 /** @type {!Array<string>} */
1834 this.literalBounds = params.literalBounds;
1835
1836 /** @type {(Array<string>|undefined)} */
1837 this.attrLiteralBounds = params.attrLiteralBounds;
1838
1839 /** @type {(?string|undefined)} */
1840 this.tagFilter = params.tagFilter;
1841
1842 /** @type {(?string|undefined)} */
1843 this.tagNameFilter = params.tagNameFilter;
1844
1845 /** @type {(?string|undefined)} */
1846 this.attrKeyFilter = params.attrKeyFilter;
1847
1848 /** @type {(?string|undefined)} */
1849 this.attrValueFilter = params.attrValueFilter;
1850
1851 /** @type {(?string|undefined)} */
1852 this.bemFilter = params.bemFilter;
1853
1854 /** @type {!Array} */
1855 this.filters = this.appendDefaultFilters(params.filters);
1856
1857 /** @type {boolean} */
1858 this.localization = params.localization;
1859
1860 /** @type {string} */
1861 this.i18nFn = params.i18nFn;
1862
1863 /** @type {(?string|undefined)} */
1864 this.i18nFnOptions = params.i18nFnOptions;
1865
1866 /** @type {(Object|undefined)} */
1867 this.language = params.language;
1868
1869 /** @type {(Object|undefined)} */
1870 this.words = params.words;
1871
1872 /** @type {(RegExp|undefined)} */
1873 this.ignore = params.ignore;
1874
1875 /** @type {boolean} */
1876 this.tolerateWhitespaces = params.tolerateWhitespaces;
1877
1878 /** @type {string} */
1879 this.eol = params.eol;
1880
1881 /** @type {string} */
1882 this.doctype = params.doctype;
1883
1884 /** @type {(?string|undefined)} */
1885 this.renderAs = params.renderAs;
1886
1887 /** @type {string} */
1888 this.renderMode = params.renderMode;
1889
1890 /** @type {{file, line, node, template}} */
1891 this.info = params.info;
1892
1893 /**
1894 * Stack parameters that can be changed in a code
1895 * @type {!Array<!Object>}
1896 */
1897 this.params = [{
1898 '@root': true,
1899 renderMode: this.renderMode,
1900 renderAs: this.renderAs,
1901 localization: this.localization,
1902 i18nFn: this.i18nFn,
1903 i18nFnOptions: this.i18nFnOptions,
1904 literalBounds: this.literalBounds,
1905 attrLiteralBounds: this.attrLiteralBounds,
1906 tagFilter: this.tagFilter,
1907 attrKeyFilter: this.attrKeyFilter,
1908 attrValueFilter: this.attrValueFilter,
1909 bemFilter: this.bemFilter,
1910 filters: this.filters,
1911 language: this.language,
1912 ignore: this.ignore,
1913 tolerateWhitespaces: this.tolerateWhitespaces,
1914 doctype: this.doctype
1915 }];
1916
1917 /**
1918 * If is true, then for declaring directives must use advanced syntax
1919 * @type {(boolean|number)}
1920 */
1921 this.needPrfx = false;
1922
1923 /**
1924 * The source code for debugger
1925 * @type {!Array}
1926 */
1927 this.lines = [''];
1928
1929 /**
1930 * The array of errors
1931 * @type {!Array}
1932 */
1933 this.errors = [];
1934
1935 /**
1936 * If is true, then compiling will be broken
1937 * @type {boolean}
1938 */
1939 this.break = false;
1940
1941 /**
1942 * The array of declared constants
1943 * @type {Array}
1944 */
1945 this.consts = null;
1946
1947 /**
1948 * The map of declared variables
1949 * @type {!Object}
1950 */
1951 this.vars = {};
1952
1953 /**
1954 * The scope of blocks
1955 * @type {!Array<string>}
1956 */
1957 this.scope = [];
1958
1959 /**
1960 * The name of the active directive
1961 * @type {(string|undefined)}
1962 */
1963 this.name = undefined;
1964
1965 /**
1966 * If is true, then the active directive is inline
1967 * @type {!Array<boolean>}
1968 */
1969 this.inline = [];
1970
1971 /**
1972 * If is true, then the active directive has a text type
1973 * @type {boolean}
1974 */
1975 this.text = false;
1976
1977 /**
1978 * The map of register namespaces
1979 * @type {!Object<{files: Array}>}
1980 */
1981 this.namespaces = {};
1982
1983 /**
1984 * The map of register templates
1985 * @type {!Object<{file, renderAs}>}
1986 */
1987 this.templates = {};
1988
1989 /**
1990 * The name of the active template
1991 * @type {(string|undefined)}
1992 */
1993 this.tplName = undefined;
1994
1995 /**
1996 * The parent name of the active template
1997 * @type {(string|undefined)}
1998 */
1999 this.parentTplName = undefined;
2000
2001 /**
2002 * If is true, then the active template is generator
2003 * @type {boolean}
2004 */
2005 this.generator = false;
2006
2007 /**
2008 * If is true, then the active template is async
2009 * @type {boolean}
2010 */
2011 this.async = false;
2012
2013 /**
2014 * The number of deferred return calls
2015 * @type {number}
2016 */
2017 this.deferReturn = 0;
2018
2019 /**
2020 * The number of iteration, where the active template was declared
2021 * @type {number}
2022 */
2023 this.startTemplateI = 0;
2024
2025 /**
2026 * The number of a line, where the active template was declared
2027 * @type {(number|undefined)}
2028 */
2029 this.startTemplateLine = undefined;
2030
2031 /**
2032 * The name of the parent BEM class
2033 * @type {string}
2034 */
2035 this.bemRef = '';
2036
2037 /**
2038 * If the last value is true, then the this value inside functions won't be replaced to __THIS__
2039 * @type {!Array<boolean>}
2040 */
2041 this.selfThis = [false];
2042
2043 /**
2044 * If is false, then template can't be inserted into the resulting JS string
2045 * @type {boolean}
2046 */
2047 this.canWrite = true;
2048
2049 /**
2050 * The list of decorators
2051 * @type {!Array<string>}
2052 */
2053 this.decorators = [];
2054
2055 /**
2056 * The cache of outer prototypes / blocks
2057 * @type {!Object}
2058 */
2059 this.preDefs = {};
2060
2061 /**
2062 * The name of the active outer prototype / block
2063 * @type {(string|undefined)}
2064 */
2065 this.outerLink = undefined;
2066
2067 // Whitespace
2068 // >>>
2069
2070 /** @type {boolean} */
2071 this.space = false;
2072
2073 /** @type {boolean} */
2074 this.prevSpace = false;
2075
2076 /** @type {!Array<boolean>} */
2077 this.strongSpace = [false];
2078
2079 /** @type {boolean|number} */
2080 this.sysSpace = false;
2081
2082 /** @type {number} */
2083 this.freezeLine = 0;
2084
2085 // <<<
2086
2087 /**
2088 * The number of the active iteration
2089 * @type {number}
2090 */
2091 this.i = -1;
2092
2093 /**
2094 * The tree of blocks: block, const
2095 * @type {Object}
2096 */
2097 this.blockStructure = null;
2098
2099 /**
2100 * The map for blocks: block, const
2101 * @type {Object}
2102 */
2103 this.blockTable = null;
2104
2105 /**
2106 * The template structure
2107 * @type {$$SnakeskinParserStructure}
2108 */
2109 this.structure = {
2110 name: 'root',
2111 parent: null,
2112 params: {},
2113 stack: [],
2114 vars: {},
2115 children: [],
2116 logic: false,
2117 chain: false
2118 };
2119
2120 /**
2121 * If is true, then the output will be saved to __STRING_RESULT__ as a string
2122 * @type {boolean}
2123 */
2124 this.stringResult = false;
2125
2126 /**
2127 * The content of Escaper blocks
2128 * @type {!Array}
2129 */
2130 this.quotContent = [];
2131
2132 /**
2133 * The content of directives (for replaceTplVars)
2134 * @type {!Array}
2135 */
2136 this.dirContent = [];
2137
2138 /**
2139 * The content of CDATA blocks
2140 * @type {!Array}
2141 */
2142 this.cdataContent = [];
2143
2144 /**
2145 * The map of included files
2146 * @type {!Object}
2147 */
2148 this.files = {};
2149
2150 var r$$1 = getRequire(this.info.file);
2151
2152 /**
2153 * The module environment
2154 * @type {{exports, require, id, key, root, filename, parent, children, loaded, namespace}}
2155 */
2156 this.environment = {
2157 exports: {},
2158 require: r$$1.require,
2159 id: 0,
2160 key: [],
2161 root: null,
2162 filename: this.info.file,
2163 dirname: r$$1.dirname,
2164 parent: IS_NODE ? module : null,
2165 children: [],
2166 loaded: true,
2167 namespace: null
2168 };
2169
2170 /**
2171 * The source text of templates
2172 * @type {string}
2173 */
2174 this.source = this.replaceCData(src);
2175
2176 /**
2177 * The final JS string
2178 * @type {string}
2179 */
2180 this.result = 'This code is generated automatically, don\'t alter it. */';
2181
2182 /**
2183 * The list of imported AMD modules
2184 * @type {!Array}
2185 */
2186 this.amdModules = [];
2187
2188 var isAMD = { 'amd': true, 'umd': true }[this.module],
2189 ssRoot = this.pack ? 'snakeskin/dist/snakeskin.live.min.js' : 'snakeskin',
2190 useStrict = this.useStrict ? '\'use strict\';' : '';
2191
2192 if (this.module === 'native') {
2193 this.result += ws(_templateObject, useStrict, ssRoot);
2194 } else {
2195 this.result += ws(_templateObject2, { 'cjs': true, 'umd': true }[this.module] ? ws(_templateObject3, ssRoot) : '', isAMD ? ws(_templateObject4, this.moduleId) : '', { 'global': true, 'umd': true }[this.module] ? 'factory(global' + (this.moduleName ? '.' + this.moduleName + ' = {}' : '') + ', Snakeskin);' : '', isAMD ? '/*#__SNAKESKIN_MODULES__*/' : '', useStrict);
2196 }
2197
2198 this.result += ws(_templateObject5, this.declVars('$_', { sys: true }));
2199};
2200
2201var $dirNameShorthands = {};
2202var $dirNameAliases = {};
2203var $dirGroups = {};
2204
2205var $blockDirs = {};
2206var $textDirs = {};
2207var $logicDirs = {};
2208
2209var $dirChain = {};
2210var $dirParents = {};
2211var $dirEnd = {};
2212var $dirTrim = {};
2213var $dirInterpolation = {};
2214var $rgxp = {};
2215
2216var $blocks = {};
2217var $consts = {};
2218var $constPositions = {};
2219
2220var $write = {};
2221var $output = {};
2222
2223var $args = {};
2224var $argsRes = {};
2225
2226var $extMap = {};
2227var $extList = {};
2228
2229var $templates = {};
2230var $cache = {};
2231
2232var $globalCache = {};
2233var $globalFnCache = {};
2234
2235var $router = {
2236 'block': $blocks,
2237 'const': $consts
2238};
2239
2240var $routerPositions = {
2241 'const': $constPositions
2242};
2243
2244var $scope = {
2245 'block': {},
2246 'template': {}
2247};
2248
2249/**
2250 * Returns an array of function arguments from a string
2251 *
2252 * @param {string} str - source string
2253 * @return {!Array<string>}
2254 */
2255Parser.prototype.getFnArgs = function (str) {
2256 var res = [];
2257
2258 var pOpen = 0,
2259 arg = '',
2260 i = void 0;
2261
2262 for (i = 0; i < str.length; i++) {
2263 var el = str[i];
2264
2265 if (pOpen ? B_OPEN[el] : el === '(') {
2266 pOpen++;
2267 res.isCallable = true;
2268
2269 if (pOpen === 1) {
2270 continue;
2271 }
2272 } else if (pOpen ? B_CLOSE[el] : el === ')') {
2273 pOpen--;
2274
2275 if (!pOpen) {
2276 break;
2277 }
2278 }
2279
2280 if (el === ',' && pOpen === 1) {
2281 res.push(arg.trim());
2282 arg = '';
2283 continue;
2284 }
2285
2286 if (pOpen) {
2287 arg += el;
2288 }
2289 }
2290
2291 if (pOpen) {
2292 this.error('invalid "' + this.name + '" declaration');
2293 return [];
2294 }
2295
2296 if (arg) {
2297 res.push(arg.trim());
2298 }
2299
2300 res.isCallable = Boolean(res.isCallable);
2301 res.lastI = i + 1;
2302
2303 return res;
2304};
2305
2306var nullableRgxp = /[?|!]\s*$/;
2307var nullableMap = { '!': false, '?': true };
2308
2309/**
2310 * Searches and initialises function arguments from a string and returns an information object
2311 *
2312 * @param {string} str - source string
2313 * @param {?$$SnakeskinParserDeclFnArgsParams=} [opt_params] - additional parameters:
2314 *
2315 * *) [dir] - directive name (template, block etc.)
2316 * *) [tplName] - template name
2317 * *) [parentTplName] - parent template name
2318 * *) [fnName] - custom function name (for blocks)
2319 *
2320 * @return {$$SnakeskinParserDeclFnArgsResult}
2321 */
2322Parser.prototype.declFnArgs = function (str, opt_params) {
2323 var _any = any(opt_params || {}),
2324 dir = _any.dir,
2325 _any$tplName = _any.tplName,
2326 tplName = _any$tplName === undefined ? this.tplName : _any$tplName,
2327 parentTplName = _any.parentTplName,
2328 fnName = _any.fnName,
2329 structure = this.structure;
2330
2331 var argsList = this.getFnArgs(str),
2332 isLocalFunction = !dir || fnName;
2333
2334 var scope = void 0,
2335 argsMap = {},
2336 parentArgs = void 0;
2337
2338 // Initialise cache objects
2339 // for the specified block
2340 if (dir) {
2341 if (!$args[tplName]) {
2342 $args[tplName] = {};
2343 $argsRes[tplName] = {};
2344 }
2345
2346 if (!$args[tplName][dir]) {
2347 $args[tplName][dir] = {};
2348 $argsRes[tplName][dir] = {};
2349 }
2350
2351 if (fnName) {
2352 if (parentTplName && $args[parentTplName][dir]) {
2353 parentArgs = $args[parentTplName][dir][fnName];
2354 }
2355
2356 var cache = $argsRes[tplName][dir][fnName];
2357
2358 // If our parameters already exists in the cache,
2359 // then init local variables and return an information object
2360 if (cache) {
2361 var list = cache.list;
2362
2363
2364 for (var i = 0; i < list.length; i++) {
2365 var el = list[i];
2366
2367 structure.vars[el[2]] = {
2368 scope: this.scope.length,
2369 value: el[0]
2370 };
2371 }
2372
2373 if (cache.scope) {
2374 this.scope.push(cache.scope);
2375 this.structure.params['@scope'] = true;
2376 }
2377
2378 return cache;
2379 }
2380
2381 argsMap = $args[tplName][dir][fnName] = {};
2382 } else {
2383 if (parentTplName) {
2384 parentArgs = $args[parentTplName][dir];
2385 }
2386
2387 argsMap = $args[tplName][dir];
2388 }
2389 }
2390
2391 // Analise requested parameters
2392 // and save it in cache
2393 for (var _i = 0; _i < argsList.length; _i++) {
2394 var _el = argsList[_i],
2395 arg = _el.split(/\s*=\s*/);
2396
2397 if (arg.length > 1) {
2398 arg[1] = arg.slice(1).join('=');
2399 arg.splice(2, arg.length);
2400 }
2401
2402 var defFilter = '';
2403 if (arg[0][0] === '(') {
2404 arg[0] = arg[0].replace(/^\(\s*([^|]+)(.*?)\)$/, function (str, arg, filter) {
2405 defFilter = filter;
2406 return arg.trim();
2407 });
2408 }
2409
2410 if (scopeMod.test(arg[0])) {
2411 if (scope) {
2412 this.error('invalid "' + this.name + '" declaration');
2413 return {
2414 decl: '',
2415 def: '',
2416 isCallable: false,
2417 list: [],
2418 scope: undefined
2419 };
2420 }
2421
2422 scope = arg[0] = arg[0].replace(scopeMod, '');
2423
2424 scope = scope.replace(nullableRgxp, '');
2425 }
2426
2427 var nullable = void 0;
2428 arg[0] = arg[0].replace(nullableRgxp, function (str) {
2429 nullable = nullableMap[str];
2430 return '';
2431 });
2432
2433 argsMap[arg[0]] = {
2434 defFilter: defFilter,
2435 i: _i,
2436 key: arg[0],
2437 nullable: nullable,
2438 scope: scope,
2439 value: arg[1] && this.pasteDangerBlocks(arg[1].trim())
2440 };
2441 }
2442
2443 if (dir) {
2444 // Mix the requested parameters
2445 // with parent block parameters
2446 for (var key in parentArgs) {
2447 if (!parentArgs.hasOwnProperty(key)) {
2448 break;
2449 }
2450
2451 var _el2 = parentArgs[key],
2452 _arg = argsMap[key];
2453
2454 // Parameter exists in a parent function
2455 if (_arg) {
2456 _arg.defFilter = _el2.defFilter + _arg.defFilter;
2457
2458 if (!scope && _el2.scope) {
2459 scope = _el2.scope;
2460 _arg.scope = scope;
2461 }
2462
2463 if (_arg.nullable === undefined) {
2464 _arg.nullable = _el2.nullable;
2465 }
2466
2467 if (_arg.nullable === undefined) {
2468 _arg.nullable = _el2.nullable;
2469 }
2470
2471 if (_arg.value === undefined) {
2472 argsMap[key].value = _el2.value;
2473 }
2474
2475 // Parameter doesn't exists in a parent function,
2476 // set it as a local variable
2477 } else {
2478 argsMap[key] = {
2479 defFilter: _el2.defFilter,
2480 i: _el2.i,
2481 key: key,
2482 local: true,
2483 value: _el2.value !== undefined ? _el2.value : 'undefined'
2484 };
2485 }
2486 }
2487 }
2488
2489 var finalArgsList = [],
2490 localsList = [];
2491
2492 for (var _key in argsMap) {
2493 if (!argsMap.hasOwnProperty(_key)) {
2494 break;
2495 }
2496
2497 var _el3 = argsMap[_key];
2498
2499 if (_el3.local) {
2500 localsList[_el3.i] = _el3;
2501 } else {
2502 finalArgsList[_el3.i] = _el3;
2503 }
2504 }
2505
2506 var decl = '',
2507 def = '';
2508
2509 var locals = [];
2510
2511 // Initialise local variables
2512 for (var _i2 = 0; _i2 < localsList.length; _i2++) {
2513 var _el4 = localsList[_i2];
2514
2515 if (!_el4) {
2516 continue;
2517 }
2518
2519 var old = _el4.key;
2520
2521 if (isLocalFunction) {
2522 _el4.key = this.declVar(_el4.key, { fn: true });
2523 }
2524
2525 locals.push([_el4.key, _el4.value, old]);
2526
2527 def += 'var ' + _el4.key + ' = ' + this.out(this.replaceDangerBlocks(_el4.value) + _el4.defFilter, { unsafe: true }) + ';';
2528 structure.vars[_el4.key] = {
2529 scope: this.scope.length,
2530 value: _el4.key
2531 };
2532 }
2533
2534 var args = [],
2535 consts = $consts[tplName],
2536 constsCache = structure.params['@consts'] = {};
2537
2538 // Initialise arguments
2539 for (var _i3 = 0; _i3 < finalArgsList.length; _i3++) {
2540 var _el5 = finalArgsList[_i3],
2541 _old = _el5.key;
2542
2543 if (consts && consts[_old] && isLocalFunction) {
2544 constsCache[_old] = consts[_old];
2545 delete consts[_old];
2546 }
2547
2548 if (isLocalFunction) {
2549 _el5.key = this.declVar(_el5.key, { fn: true });
2550 }
2551
2552 decl += _el5.key;
2553 args.push([_el5.key, _el5.value, _old]);
2554
2555 var val = this.out(_el5.key + _el5.defFilter, { skipFirstWord: true, unsafe: true });
2556
2557 if (_el5.value !== undefined) {
2558 var defVal = this.out(this.replaceDangerBlocks(_el5.value) + _el5.defFilter, { unsafe: true });
2559 def += _el5.key + ' = ' + _el5.key + ' ' + (_el5.nullable ? '!== undefined' : '!= null') + ' ? ' + val + ' : ' + defVal + ';';
2560 } else if (_el5.defFilter) {
2561 def += _el5.key + ' = ' + val + ';';
2562 }
2563
2564 if (_i3 !== finalArgsList.length - 1) {
2565 decl += ',';
2566 }
2567 }
2568
2569 var res = {
2570 decl: decl,
2571 def: def,
2572 isCallable: argsList.isCallable,
2573 list: args.concat(locals),
2574 scope: scope
2575 };
2576
2577 if (scope) {
2578 this.scope.push(scope);
2579 this.structure.params['@scope'] = true;
2580 }
2581
2582 if (dir && fnName) {
2583 $argsRes[tplName][dir][fnName] = res;
2584 }
2585
2586 return res;
2587};
2588
2589/**
2590 * Returns a cache object for the specified block
2591 *
2592 * @param {string} type - block type
2593 * @param {?string=} [opt_tplName] - template name
2594 * @return {Object}
2595 */
2596Parser.prototype.getBlockOutput = function (type, opt_tplName) {
2597 opt_tplName = opt_tplName || this.tplName;
2598
2599 var output = $output[opt_tplName];
2600
2601 if (!output) {
2602 return null;
2603 }
2604
2605 if (!output[type]) {
2606 output[type] = {};
2607 }
2608
2609 return output[type];
2610};
2611
2612/**
2613 * (Re)initializes cache for a template
2614 *
2615 * @param {string} tplName - template name
2616 * @return {!Parser}
2617 */
2618Parser.prototype.initTemplateCache = function (tplName) {
2619 this.consts = [];
2620 this.bemRef = '';
2621
2622 this.space = !this.tolerateWhitespaces;
2623 this.strongSpace = [false];
2624 this.sysSpace = false;
2625
2626 $blocks[tplName] = {};
2627 $consts[tplName] = {};
2628 $constPositions[tplName] = 0;
2629
2630 return this;
2631};
2632
2633/**
2634 * Declares the start of a block directive
2635 *
2636 * @param {?string=} opt_name - directive name
2637 * @param {Object=} [opt_params] - additional parameters
2638 * @param {Object=} [opt_vars] - local variables
2639 * @return {!Parser}
2640 */
2641Parser.prototype.startDir = function (opt_name, opt_params, opt_vars) {
2642 opt_vars = opt_vars || {};
2643 opt_params = opt_params || {};
2644 opt_name = this.name = String(opt_name ? this.getDirName(opt_name) : this.name);
2645
2646 var structure = this.structure,
2647 vars = structure.vars;
2648
2649
2650 var arr = Object.keys(any(vars));
2651
2652 for (var i = 0; i < arr.length; i++) {
2653 var key = arr[i];
2654 opt_vars[key] = vars[key];
2655 opt_vars[key].inherited = true;
2656 }
2657
2658 var obj = {
2659 chain: false,
2660 children: [],
2661 logic: Boolean($logicDirs[opt_name]),
2662 name: opt_name,
2663 params: opt_params,
2664 parent: structure,
2665 stack: [],
2666 vars: opt_vars
2667 };
2668
2669 this.inline.push(false);
2670 this.structure = obj;
2671 structure.children.push(obj);
2672
2673 var blockStructure = this.blockStructure,
2674 blockTable = this.blockTable;
2675
2676
2677 if (blockStructure && this.getGroup('blockInherit')[opt_name]) {
2678 var parent = this.parentTplName,
2679 _key = opt_name + '_' + opt_params.name;
2680
2681 var sub = void 0;
2682 if (blockTable[_key] && blockTable[_key] !== true) {
2683 sub = blockTable[_key];
2684 sub.parent = blockStructure;
2685 } else {
2686 sub = {
2687 children: [],
2688 name: opt_name,
2689 params: opt_params,
2690 parent: blockStructure
2691 };
2692
2693 if (blockTable[_key] === true) {
2694 sub.drop = true;
2695 }
2696
2697 blockTable[_key] = sub;
2698 var deep = function deep(obj) {
2699 for (var _i = 0; _i < obj.length; _i++) {
2700 var el = obj[_i],
2701 _key2 = el.name + '_' + el.params.name;
2702
2703 if (blockTable[_key2] && blockTable[_key2] !== true) {
2704 blockTable[_key2].drop = true;
2705 } else {
2706 blockTable[_key2] = true;
2707 }
2708
2709 if (el.children) {
2710 deep(el.children);
2711 }
2712 }
2713 };
2714
2715 if (parent && $templates[parent][_key] && $templates[parent][_key].children) {
2716 deep($templates[parent][_key].children);
2717 }
2718 }
2719
2720 blockStructure.children.push(sub);
2721 this.blockStructure = sub;
2722 }
2723
2724 return this;
2725};
2726
2727/**
2728 * Declares the start of an inline directive
2729 *
2730 * @param {?string=} opt_name - directive name
2731 * @param {Object=} [opt_params] - additional parameters
2732 * @return {!Parser}
2733 */
2734Parser.prototype.startInlineDir = function (opt_name, opt_params) {
2735 opt_params = opt_params || {};
2736 opt_name = this.name = String(opt_name ? this.getDirName(opt_name) : this.name);
2737
2738 var obj = {
2739 chain: false,
2740 children: null,
2741 logic: Boolean($logicDirs[opt_name]),
2742 name: opt_name,
2743 params: opt_params,
2744 parent: this.structure,
2745 stack: [],
2746 vars: null
2747 };
2748
2749 this.inline.push(true);
2750 this.structure.children.push(obj);
2751 this.structure = obj;
2752
2753 var blockStructure = this.blockStructure,
2754 blockTable = this.blockTable;
2755
2756
2757 if (blockStructure && this.getGroup('inlineInherit')[opt_name]) {
2758 var key = opt_name + '_' + opt_params.name;
2759
2760 var sub = void 0;
2761 if (blockTable[key] && blockTable[key] !== true) {
2762 sub = blockTable[key];
2763 sub.parent = blockStructure;
2764 } else {
2765 sub = {
2766 name: opt_name,
2767 params: opt_params,
2768 parent: blockStructure
2769 };
2770
2771 if (blockTable[key] === true) {
2772 sub.drop = true;
2773 }
2774 }
2775
2776 blockTable[key] = sub;
2777 blockStructure.children.push(sub);
2778 this.blockStructure = sub;
2779 }
2780
2781 return this;
2782};
2783
2784/**
2785 * Declares the end of a directive
2786 * @return {!Parser}
2787 */
2788Parser.prototype.endDir = function () {
2789 if (this.blockStructure && this.getGroup('blockInherit', 'inlineInherit')[this.structure.name]) {
2790 this.blockStructure = this.blockStructure.parent;
2791 }
2792
2793 this.inline.pop();
2794 this.structure = this.structure.parent;
2795
2796 return this;
2797};
2798
2799var cutRgxp = /\/\*!!= (.*?) =\*\//g;
2800var privateRgxp = new RegExp(r(ADV_LEFT_BOUND) + '?' + r(LEFT_BOUND) + '__.*?__.*?' + r(RIGHT_BOUND), 'g');
2801var styleRgxp = /\t|[ ]{4}/g;
2802
2803/**
2804 * Returns additional information for an error
2805 * @return {string}
2806 */
2807Parser.prototype.getAdvInfo = function () {
2808 var eol = this.eol,
2809 info = this.info,
2810 line = this.info.line;
2811
2812
2813 if (!info) {
2814 return '';
2815 }
2816
2817 var str = '';
2818 for (var key in info) {
2819 if (!info.hasOwnProperty(key)) {
2820 break;
2821 }
2822
2823 var el = info[key];
2824 key = key[0].toUpperCase() + key.slice(1);
2825
2826 if (el != null) {
2827 str += '\n';
2828
2829 if (el.innerHTML) {
2830 str += key + ': (class: ' + (el.className || 'undefined') + ', id: ' + (el.id || 'undefined') + '); ';
2831 } else {
2832 str += key + ': ' + el + '; ';
2833 }
2834 }
2835 }
2836
2837 if (line) {
2838 var prfx = '',
2839 max = 0;
2840
2841 for (var i = 8; i--;) {
2842 var pos = line - i - 2,
2843 space = new Array(String(line - 1).length - String(pos).length + 1).join(' ');
2844
2845 var prev = this.lines[pos];
2846
2847 if (prev != null) {
2848 prev = prev.replace(styleRgxp, ' ').replace(privateRgxp, '').replace(cutRgxp, '$1');
2849
2850 var part = void 0;
2851 if (prev.trim()) {
2852 part = eol + ' ' + (pos + 1) + ' ' + space + prev;
2853 } else {
2854 part = eol + ' ...';
2855 }
2856
2857 prfx += part;
2858 if (max < part.length) {
2859 max = part.length;
2860 }
2861 }
2862 }
2863
2864 var current = (this.lines[line - 1] || '').replace(styleRgxp, ' ').replace(privateRgxp, '').replace(cutRgxp, '$1');
2865
2866 var chunk = '> ' + line + ' ' + current,
2867 sep = new Array(Math.max(max, chunk.length) || 5).join('-');
2868
2869 str += eol + sep + prfx + eol + chunk + eol + sep;
2870 }
2871
2872 return this.pasteDangerBlocks(str + eol);
2873};
2874
2875/**
2876 * Returns an error object
2877 * @param {string} msg - error message
2878 */
2879Parser.prototype.error = function (msg) {
2880 this.errors.push(msg);
2881 this.break = true;
2882
2883 var report = msg + '; ' + this.getAdvInfo(),
2884 error = any(Object.assign(new Error(report), { name: 'SnakeskinError' }));
2885
2886 if (this.onError) {
2887 this.onError(error);
2888 } else {
2889 if (!HAS_CONSOLE_ERROR || this.throws) {
2890 throw error;
2891 }
2892
2893 console.error('Error: ' + report);
2894 }
2895};
2896
2897var escaper = GLOBAL.Escaper || require('escaper');
2898escaper.snakeskinRgxp = filterStart;
2899
2900/**
2901 * @see Escaper.replace
2902 * @param {string} str
2903 * @return {string}
2904 */
2905Parser.prototype.replaceDangerBlocks = function (str) {
2906 return escaper.replace(str, true, this.quotContent, true);
2907};
2908
2909/**
2910 * @see Escaper.paste
2911 * @param {string} str
2912 * @return {string}
2913 */
2914Parser.prototype.pasteDangerBlocks = function (str) {
2915 return escaper.paste(str, this.quotContent);
2916};
2917
2918/**
2919 * Executes a string
2920 *
2921 * @param {string} str - source string
2922 * @param {?boolean=} opt_raw - if true, then the string is considered as raw
2923 * @return {?}
2924 */
2925Parser.prototype.evalStr = function (str, opt_raw) {
2926 if (!opt_raw) {
2927 str = this.pasteDangerBlocks(str);
2928 }
2929
2930 var env = this.environment;
2931
2932 if (IS_NODE) {
2933 return Function('GLOBAL', 'Snakeskin', '__FILTERS__', '__VARS__', '__LOCAL__', 'module', 'exports', 'require', '__dirname', '__filename', 'Unsafe', str).call(ROOT, GLOBAL, Snakeskin$1, Snakeskin$1.Filters, Snakeskin$1.Vars, Snakeskin$1.LocalVars, env, env.exports, env.require, env.dirname, env.filename, null);
2934 }
2935
2936 return Function('GLOBAL', 'Snakeskin', '__FILTERS__', '__VARS__', '__LOCAL__', 'module', 'exports', 'Unsafe', str).call(ROOT, GLOBAL, Snakeskin$1, Snakeskin$1.Filters, Snakeskin$1.Vars, Snakeskin$1.LocalVars, env, env.exports, null);
2937};
2938
2939/**
2940 * Executes a string and returns result
2941 *
2942 * @param {string} str - source string
2943 * @return {?}
2944 */
2945Parser.prototype.returnEvalVal = function (str) {
2946 return this.evalStr('return ' + str);
2947};
2948
2949/**
2950 * Clones an object
2951 *
2952 * @param {?} obj - source object
2953 * @return {?}
2954 */
2955function clone(obj) {
2956 return JSON.parse(JSON.stringify(obj));
2957}
2958
2959/**
2960 * Converts the specified value to an object
2961 *
2962 * @param {?} val - object, a string for parsing or a file path
2963 * @param {?string=} [opt_base] - base path
2964 * @param {?function(string)=} [opt_onFileExists] - callback function (only if val is src)
2965 * @return {!Object}
2966 */
2967function toObj(val, opt_base, opt_onFileExists) {
2968 if (!isString(val)) {
2969 return val;
2970 }
2971
2972 var res = void 0;
2973 if (IS_NODE) {
2974 var path = require('path'),
2975 fs = require('fs');
2976
2977 var old = val;
2978
2979 try {
2980 val = path.normalize(path.resolve(opt_base ? path.join(path.dirname(opt_base), val) : val));
2981
2982 if (fs.statSync(val).isFile()) {
2983 opt_onFileExists && opt_onFileExists(val);
2984
2985 var content = any(fs.readFileSync(val, 'utf8'));
2986
2987 try {
2988 res = JSON.parse(content);
2989 } catch (ignore) {
2990 try {
2991 res = Function('return ' + content)();
2992 } catch (ignore) {
2993 delete require.cache[require.resolve(val)];
2994 res = require(val);
2995 }
2996 }
2997
2998 return any(res || {});
2999 }
3000 } catch (ignore) {}
3001
3002 val = old;
3003 }
3004
3005 try {
3006 res = JSON.parse(val);
3007 } catch (ignore) {
3008 try {
3009 res = Function('return ' + val)();
3010 } catch (ignore) {
3011 try {
3012 res = Function('return {' + val + '}')();
3013 } catch (ignore) {
3014 res = {};
3015 }
3016 }
3017 }
3018
3019 return any(res || {});
3020}
3021
3022/* eslint-disable prefer-template */
3023
3024var stack = [];
3025
3026Snakeskin$1.toObj = toObj;
3027
3028/**
3029 * Adds file content by the specified path to the stack
3030 *
3031 * @param {string} base - base path
3032 * @param {string} file - file path
3033 * @param {string} eol - EOL symbol
3034 * @param {?string=} [opt_renderAs] - rendering type of templates
3035 * @return {(string|boolean)}
3036 */
3037Snakeskin$1.include = function (base, file, eol$$1, opt_renderAs) {
3038 if (!IS_NODE) {
3039 return false;
3040 }
3041
3042 var type = opt_renderAs || 'template';
3043
3044 var fs = require('fs'),
3045 path = require('path'),
3046 glob = require('glob'),
3047 findup = require('findup-sync');
3048
3049 var s = ADV_LEFT_BOUND + LEFT_BOUND,
3050 e = RIGHT_BOUND;
3051
3052 try {
3053 var extname = path.extname(file),
3054 include = Snakeskin$1.LocalVars.include;
3055
3056
3057 var dirname = path.basename(file),
3058 mainFile = '?(' + (dirname && !glob.hasMagic(dirname) ? dirname + '|' : '') + 'main|index).ss';
3059
3060 var src = /(?:\\|\/)$/.test(file) ? file + mainFile : file + (extname ? '' : '.ss');
3061
3062 if (!path.isAbsolute(src)) {
3063 if (/^\./.test(src)) {
3064 src = path.resolve(path.dirname(base), src);
3065 } else {
3066 src = path.resolve(findup('node_modules'), src);
3067 }
3068 }
3069
3070 var arr = glob.hasMagic(src) ? glob.sync(src) : [src];
3071
3072 for (var i = 0; i < arr.length; i++) {
3073 var _src = path.normalize(arr[i]);
3074
3075 if (_src in include && include[_src] >= templateRank[type]) {
3076 continue;
3077 }
3078
3079 include[_src] = templateRank[type];
3080 var _file = fs.readFileSync(_src, 'utf8');
3081
3082 stack.push(s + '__setFile__ ' + _src + e + (opt_renderAs ? s + '__set__ renderAs \'' + opt_renderAs + '\'' + e : '') + ('' + (wsStart.test(_file) ? '' : eol$$1)) + _file + ('' + (wsEnd.test(_file) ? '' : '' + eol$$1 + s + '__cutLine__' + e)) + (s + '__endSetFile__' + e));
3083 }
3084
3085 return true;
3086 } catch (err) {
3087 stack.push(s + '__setError__ ' + err.message + e);
3088 }
3089
3090 return false;
3091};
3092
3093/* eslint-disable no-use-before-define */
3094
3095/**
3096 * Transformer for a group list
3097 *
3098 * @param {Array} arr - source list
3099 * @return {string}
3100 */
3101var q = function q(arr) {
3102 var tmp = [];
3103
3104 for (var i = 0; i < arr.length; i++) {
3105 tmp.push('"' + arr[i] + '"');
3106 }
3107
3108 return tmp.join(', ');
3109};
3110
3111var GROUP = '@';
3112
3113var groupCache = {};
3114
3115/**
3116 * Initialises the specified group
3117 *
3118 * @param {string} name - group name
3119 * @return {string}
3120 */
3121Snakeskin$1.group = function (name) {
3122 return GROUP + name;
3123};
3124
3125var dirPlacement = {};
3126var dirPlacementPlain = {};
3127var dirAncestorsBlacklist = {};
3128var dirAncestorsBlacklistPlain = {};
3129var dirAncestorsWhitelist = {};
3130var dirAncestorsWhitelistPlain = {};
3131
3132/**
3133 * Adds a new directive to the SS namespace
3134 *
3135 * @param {string} name - directive name
3136 * @param {$$SnakeskinAddDirectiveParams} params - additional parameters:
3137 *
3138 * *) [params.deferInit = false] - if is true, the directive won't be started automatically
3139 * *) [params.async = false] - if is true, the directive can be used only with asyncs
3140 * *) [params.generator = false] - if is true, the directive can be used only with generators
3141 * *) [params.notEmpty = false] - if is true, then the directive can't be empty
3142 * *) [params.alias = false] - if is true, then the directive is considered as an alias
3143 * (only for private directives)
3144 *
3145 * *) [params.group] - group name, which includes the current directive
3146 * or an array of names
3147 *
3148 * *) [params.renderModesBlacklist] - rendering mode, which can't be used with the current directive
3149 * or an array of names
3150 *
3151 * *) [params.renderModesWhitelist] - rendering mode, which can be used with the current directive
3152 * or an array of names
3153 *
3154 * *) [params.placement] - placement of the directive: global or template
3155 * *) [params.ancestorsBlacklist] - directive/group name, which can't be an ancestor for the current directive
3156 * or an array of names
3157 *
3158 * *) [params.ancestorsWhitelist] - directive/group name, which can be an ancestor for the current directive
3159 * or an array of names
3160 *
3161 * *) [params.with] - directive/group name, which is a master for the current directive
3162 * or an array of names
3163 *
3164 * *) [params.parents] - directive/group name, which can be a parent for the current directive
3165 * or an array of names
3166 *
3167 * *) [params.children] - directive/group name, which can be a child of the current directive
3168 * or an array of names
3169 *
3170 * *) [params.endsWith] - directive/group name, which can be placed after the current directive
3171 * or an array of names
3172 *
3173 * *) [params.endFor] - directive/group name, which must be closed using the current directive
3174 * or an array of names
3175 *
3176 * *) [params.trim] - trim for the directive content (Jade-Like mode)
3177 * trim: {
3178 * left: true,
3179 * right: false
3180 * }
3181 *
3182 * *) [params.logic = false] - if is true, then the directive is considered as a system type
3183 * *) [params.text = false] - if is true, then the directive will be outputted as a plain text
3184 * *) [params.block = false] - if is true, then the directive is considered as a block type
3185 * *) [params.selfInclude = true] - if is false, then the directive can't be placed inside an another directive
3186 * of the same type
3187 *
3188 * *) [params.interpolation = false] - if is true, then the directive will be support interpolation
3189 * *) [params.selfThis = false] - if is true, then inside the directive block all calls of this won't
3190 * be replaced to __THIS__
3191 *
3192 * *) [params.shorthands] - shorthands for the directive
3193 * shorthands: {
3194 * // Can be no more than two symbols in the key
3195 * '?': 'void '
3196 * }
3197 *
3198 * @param {function(this:Parser, string, {
3199 * length: number,
3200 * type: string,
3201 * expr: string,
3202 * raw: string,
3203 * jsDocStart: (boolean|number)
3204 * })=} opt_constr - constructor
3205 *
3206 * @param {function(this:Parser, string, {
3207 * length: number,
3208 * type: string,
3209 * expr: string,
3210 * raw: string,
3211 * jsDocStart: (boolean|number)
3212 * })=} opt_destruct - destructor
3213 */
3214Snakeskin$1.addDirective = function (name, params, opt_constr, opt_destruct) {
3215 groupCache = {};
3216
3217 var p = Object.assign({}, params),
3218 concat = function concat(val) {
3219 return val != null ? [].concat(val) : [];
3220 };
3221
3222 var _ = function _(_ref) {
3223 var _ref2 = slicedToArray(_ref, 2),
3224 cache = _ref2[0],
3225 val = _ref2[1];
3226
3227 return { cache: cache, val: val };
3228 };
3229
3230 [_([$dirTrim, p.trim]), _([$blockDirs, p.block]), _([$logicDirs, p.logic]), _([$textDirs, p.text]), _([$dirInterpolation, p.interpolation])].forEach(function (_ref3) {
3231 var cache = _ref3.cache,
3232 val = _ref3.val;
3233
3234 if (cache === $dirTrim) {
3235 var res = void 0;
3236 switch (val) {
3237 case true:
3238 res = {
3239 left: true,
3240 right: true
3241 };
3242
3243 break;
3244
3245 case false:
3246 res = {
3247 left: false,
3248 right: false
3249 };
3250
3251 break;
3252 }
3253
3254 cache[name] = res;
3255 } else {
3256 cache[name] = Boolean(val);
3257 }
3258 });
3259
3260 [_([$dirGroups, p.group]), _([$dirChain, p.with]), _([$dirParents, p.parents]), _([$dirEnd, p.endFor])].forEach(function (_ref4) {
3261 var cache = _ref4.cache,
3262 val = _ref4.val;
3263
3264 Snakeskin$1.forEach(concat(val), function (key) {
3265 if (cache === $dirGroups && key[0] === GROUP) {
3266 throw new Error('Invalid group name "' + key + '" (group name can\'t begin with "' + GROUP + '"');
3267 }
3268
3269 cache[key] = cache[key] || {};
3270 cache[key][name] = true;
3271 });
3272 });
3273
3274 [$dirChain, $dirParents, $dirEnd].forEach(function (cache) {
3275 Snakeskin$1.forEach(cache, function (el, key) {
3276 if (key[0] !== GROUP) {
3277 return;
3278 }
3279
3280 var link = cache[key];
3281
3282 Snakeskin$1.forEach($dirGroups[key.slice(1)], function (el, group) {
3283 cache[group] = cache[group] || {};
3284 Snakeskin$1.forEach(link, function (el, dir) {
3285 return cache[group][dir] = true;
3286 });
3287 });
3288 });
3289 });
3290
3291 [_([$dirParents, p.children]), _([$dirEnd, p.endsWith])].forEach(function (_ref5) {
3292 var cache = _ref5.cache,
3293 val = _ref5.val;
3294
3295 concat(val).forEach(function (key) {
3296 cache[name] = cache[name] || {};
3297 cache[name][key] = true;
3298 });
3299 });
3300
3301 [$dirParents, $dirEnd].forEach(function (cache) {
3302 Snakeskin$1.forEach(cache, function (dir) {
3303 Snakeskin$1.forEach(dir, function (el, key) {
3304 if (key[0] !== GROUP) {
3305 return;
3306 }
3307
3308 Snakeskin$1.forEach($dirGroups[key.slice(1)], function (val, key) {
3309 return dir[key] = true;
3310 });
3311 });
3312 });
3313 });
3314
3315 _ = function _(_ref6) {
3316 var _ref7 = slicedToArray(_ref6, 3),
3317 cache = _ref7[0],
3318 plainCache = _ref7[1],
3319 val = _ref7[2];
3320
3321 return { cache: cache, plainCache: plainCache, val: val };
3322 };
3323
3324 [_([dirPlacement, dirPlacementPlain, p.placement]), _([dirAncestorsBlacklist, dirAncestorsBlacklistPlain, p.ancestorsBlacklist]), _([dirAncestorsWhitelist, dirAncestorsWhitelistPlain, p.ancestorsWhitelist])].forEach(function (_ref8) {
3325 var cache = _ref8.cache,
3326 plainCache = _ref8.plainCache,
3327 val = _ref8.val;
3328
3329 cache[name] = concat(val).reduce(function (map, el) {
3330 return map[el] = [el], map;
3331 }, {});
3332
3333 Snakeskin$1.forEach(cache, function (map, key) {
3334 Snakeskin$1.forEach(map, function (el, key) {
3335 if (key[0] !== GROUP) {
3336 return;
3337 }
3338
3339 key = key.slice(1);
3340 if ($dirGroups[key]) {
3341 map[key] = Object.keys($dirGroups[key]);
3342 }
3343 });
3344
3345 plainCache[key] = {};
3346 Snakeskin$1.forEach(map, function (el) {
3347 return Snakeskin$1.forEach(el, function (el) {
3348 if (el[0] !== GROUP) {
3349 plainCache[key][el] = true;
3350 }
3351 });
3352 });
3353 });
3354 });
3355
3356 Snakeskin$1.forEach(p.shorthands, function (el, key) {
3357 if (key.length > 2) {
3358 throw new Error('Invalid shorthand key "' + key + '" (key.length > 2)');
3359 }
3360
3361 if ($dirNameShorthands[key] && HAS_CONSOLE_LOG) {
3362 console.log('Warning: replacer "' + key + '" already exists');
3363 }
3364
3365 $dirNameShorthands[key] = isFunction(el) ? el : function (cmd) {
3366 return cmd.replace(key, el);
3367 };
3368
3369 if (key[0] !== '/') {
3370 SHORTS[key] = true;
3371 }
3372 });
3373
3374 if (p.alias) {
3375 $dirNameAliases[name] = name.replace(/__(.*?)__/, '$1');
3376 }
3377
3378 if (!(p.selfInclude = p.selfInclude !== false)) {
3379 p.block = true;
3380 }
3381
3382 if (p.filters) {
3383 var tmp = opt_destruct;
3384 opt_destruct = function opt_destruct() {
3385 this.appendDefaultFilters(p.filters);
3386 tmp && tmp.call.apply(tmp, [this].concat(Array.prototype.slice.call(arguments)));
3387 this.filters.pop();
3388 };
3389 }
3390
3391 /** @this {Parser} */
3392 Snakeskin$1.Directives[name] = function (command, params) {
3393 var structure = this.structure;
3394
3395
3396 var dirName = this.name = this.getDirName(name),
3397 prevDirName = structure.name,
3398 ignore = this.getGroup('ignore')[dirName];
3399
3400 switch (p.placement) {
3401 case 'template':
3402 if (!this.tplName) {
3403 return this.error('the directive "' + dirName + '" can be used only within directives ' + q(this.getGroupList('template')));
3404 }
3405
3406 break;
3407
3408 case 'global':
3409 if (structure.parent) {
3410 return this.error('the directive "' + dirName + '" can be used only within the global space');
3411 }
3412
3413 break;
3414 }
3415
3416 if (p.notEmpty && !command) {
3417 return this.error('the directive "' + dirName + '" must have a body');
3418 }
3419
3420 if (p.async && !this.async && !this.outerLink) {
3421 return this.error('the directive "' + dirName + '" can be used only within an async template');
3422 }
3423
3424 if (p.generator && !this.generator && !this.outerLink) {
3425 return this.error('the directive "' + dirName + '" can be used only within a generator template');
3426 }
3427
3428 var rmBlacklistList = concat(p.renderModesBlacklist),
3429 rmBlacklist = {};
3430
3431 for (var i = 0; i < rmBlacklistList.length; i++) {
3432 rmBlacklist[rmBlacklistList[i]] = true;
3433 }
3434
3435 if (p.renderModesBlacklist && rmBlacklist[this.renderMode]) {
3436 return this.error('the directive "' + dirName + '" can\'t be used with directives ' + q(rmBlacklistList) + ' rendering modes');
3437 }
3438
3439 var rmWhitelistList = concat(p.renderModesWhitelist),
3440 rmWhitelist = {};
3441
3442 for (var _i = 0; _i < rmWhitelistList.length; _i++) {
3443 rmWhitelist[rmWhitelistList[_i]] = true;
3444 }
3445
3446 if (p.renderModesWhitelist && !rmWhitelist[this.renderMode]) {
3447 return this.error('the directive "' + dirName + '" can be used only with directives ' + q(rmWhitelistList) + ' rendering modes');
3448 }
3449
3450 var prevChain = $dirChain[prevDirName] && $dirChain[prevDirName][dirName];
3451
3452 if (p.with && !prevChain) {
3453 var groups = [].concat(p.with);
3454
3455 var arr = [];
3456 for (var _i2 = 0; _i2 < groups.length; _i2++) {
3457 var el = groups[_i2];
3458 arr = arr.concat(el[0] === GROUP ? this.getGroupList(el.slice(1)) : el);
3459 }
3460
3461 return this.error('the directive "' + dirName + '" can be used only with directives ' + q(arr));
3462 }
3463
3464 if (p.ancestorsBlacklist && this.has(dirAncestorsBlacklistPlain[name])) {
3465 return this.error('the directive "' + dirName + '" can\'t be used within directives ' + q(Object.keys(dirAncestorsBlacklistPlain[name])));
3466 }
3467
3468 if (p.ancestorsWhitelist && !this.has(dirAncestorsWhitelistPlain[name])) {
3469 return this.error('the directive "' + dirName + '" can be used only within directives ' + q(Object.keys(dirAncestorsWhitelistPlain[name])));
3470 }
3471
3472 if (!p.selfInclude && this.has(dirName)) {
3473 return this.error('the directive "' + dirName + '" can\'t be used within the "' + dirName + '"');
3474 }
3475
3476 if (this.decorators.length && !ignore && !this.getGroup('rootTemplate', 'decorator')[dirName]) {
3477 return this.error('decorators can\'t be used after ' + dirName);
3478 }
3479
3480 if (p.text) {
3481 this.text = true;
3482 }
3483
3484 if (p.filters) {
3485 this.appendDefaultFilters(p.filters);
3486 }
3487
3488 var from = this.result.length;
3489
3490 if (!p.deferInit && !p.with) {
3491 if (p.block) {
3492 this.startDir();
3493 } else {
3494 this.startInlineDir();
3495 }
3496 }
3497
3498 if (p.selfThis) {
3499 this.selfThis.push(true);
3500 }
3501
3502 if (opt_constr) {
3503 opt_constr.call(this, command, params);
3504 }
3505
3506 if (structure.chain && !prevChain && !ignore && !this.isLogic()) {
3507 var parent = any(this.getNonLogicParent()).name;
3508
3509 if ($dirParents[parent] && $dirParents[parent][dirName]) {
3510 this.strongSpace.push(this.strongSpace[this.strongSpace.length - 2]);
3511 } else if (dirName !== 'end') {
3512 return this.error('the directive "' + dirName + '" can\'t be used within the "' + parent + '"');
3513 }
3514 }
3515
3516 var newStructure = this.structure;
3517
3518 if (newStructure.params['@from'] === undefined) {
3519 newStructure.params['@from'] = from;
3520 }
3521
3522 if ($dirParents[dirName]) {
3523 newStructure.chain = true;
3524 this.strongSpace.push(true);
3525 }
3526
3527 if (structure === newStructure) {
3528 if (!ignore && (!$dirChain[prevDirName] || !$dirChain[prevDirName][dirName]) && $dirEnd[prevDirName] && !$dirEnd[prevDirName][dirName]) {
3529 return this.error('the directive "' + dirName + '" can\'t be used after the "' + prevDirName + '"');
3530 }
3531 } else {
3532 var siblings = dirName === 'end' ? newStructure.children : newStructure.parent && newStructure.parent.children;
3533
3534 if (siblings) {
3535 var j = 1,
3536 prev = void 0;
3537
3538 while ((prev = siblings[siblings.length - j]) && (prev.name === 'text' || prev === newStructure)) {
3539 j++;
3540 }
3541
3542 if (!ignore && prev && (!$dirChain[prev.name] || !$dirChain[prev.name][dirName]) && $dirEnd[prev.name] && !$dirEnd[prev.name][dirName]) {
3543 return this.error('the directive "' + dirName + '" can\'t be used after the "' + prev.name + '"');
3544 }
3545 }
3546 }
3547
3548 if (p.filters) {
3549 this.filters.pop();
3550 }
3551
3552 this.applyQueue();
3553
3554 if (this.inline[this.inline.length - 1] === true) {
3555 baseEnd.call(this);
3556
3557 if (opt_destruct) {
3558 opt_destruct.call(this, command, params);
3559 }
3560
3561 this.endDir();
3562 }
3563 };
3564
3565 Snakeskin$1.Directives[name + 'End'] = opt_destruct;
3566
3567 /** @this {Parser} */
3568 var baseEnd = Snakeskin$1.Directives[name + 'BaseEnd'] = function () {
3569 var structure = this.structure,
3570 _structure = this.structure,
3571 params = _structure.params,
3572 parent = _structure.parent;
3573
3574
3575 if (params['@scope']) {
3576 this.scope.pop();
3577 }
3578
3579 var chainParent = $dirParents[any(this.getNonLogicParent()).name];
3580
3581 if ($dirParents[structure.name] || chainParent && chainParent[structure.name]) {
3582 this.strongSpace.pop();
3583 }
3584
3585 if (p.selfThis) {
3586 this.selfThis.pop();
3587 }
3588
3589 var consts = params['@consts'];
3590
3591 if (consts) {
3592 var arr = Object.keys(consts);
3593
3594 for (var i = 0; i < arr.length; i++) {
3595 $consts[this.tplName][arr[i]] = consts[arr[i]];
3596 }
3597 }
3598
3599 var res = params['@result'] != null ? params['@result'] : this.result;
3600
3601 var from = params['@from'],
3602 to = res.length;
3603
3604 if (from == null) {
3605 return;
3606 }
3607
3608 if ((!parent || parent.name === 'root') && (!{ 'amd': true, 'native': true }[this.module] || !this.getGroup('import')[name]) && !this.getGroup('define')[name] && from !== to) {
3609 try {
3610 this.evalStr(res.slice(from, to));
3611 } catch (err) {
3612 return this.error(err.message);
3613 }
3614
3615 if (stack.length) {
3616 this.source = this.source.slice(0, this.i + 1) + this.replaceCData(stack.join('')) + this.source.slice(this.i + 1);
3617
3618 stack.splice(0, stack.length);
3619 }
3620 }
3621 };
3622};
3623
3624/**
3625 * Returns a map of directive names
3626 * which belong to the specified groups
3627 *
3628 * @param {...string} names - group name
3629 * @return {!Object<string, boolean>}
3630 */
3631Parser.prototype.getGroup = function (names) {
3632 var cacheKey = Array.from(arguments).join();
3633
3634 if (groupCache[cacheKey]) {
3635 return clone(groupCache[cacheKey]);
3636 }
3637
3638 var map = {};
3639
3640 for (var i = 0; i < arguments.length; i++) {
3641 var arr = Object.keys($dirGroups[arguments[i]]);
3642
3643 for (var _i = 0; _i < arr.length; _i++) {
3644 if (arr[_i] !== GROUP) {
3645 map[arr[_i]] = true;
3646 }
3647 }
3648 }
3649
3650 groupCache[cacheKey] = clone(map);
3651 return map;
3652};
3653
3654/**
3655 * Returns an array of directive names
3656 * which belong to the specified groups
3657 *
3658 * @param {...string} names - group name
3659 * @return {!Array<string>}
3660 */
3661Parser.prototype.getGroupList = function (names) {
3662 return Object.keys(this.getGroup.apply(this, arguments));
3663};
3664
3665/**
3666 * Returns the full body of the specified template
3667 * (with inheritance)
3668 *
3669 * @param {string} name - template name
3670 * @return {string}
3671 */
3672Parser.prototype.getTplFullBody = function (name) {
3673 var parentTpl = $extMap[name],
3674 constLength = 1;
3675
3676 var isDecl = this.getGroupList('inherit'),
3677 is = {};
3678
3679 for (var i = 0; i < isDecl.length; i++) {
3680 is[i * 2] = isDecl[i];
3681 is[i * 2 + 1] = isDecl[i] + '_add';
3682 }
3683
3684 var res = $cache[parentTpl];
3685 if (!this.tolerateWhitespaces) {
3686 res += ADV_LEFT_BOUND + LEFT_BOUND + '__&-__' + RIGHT_BOUND;
3687 }
3688
3689 var length = isDecl.length * 2,
3690 tb = $templates[name],
3691 advDiff = [];
3692
3693 var from = 0,
3694 blockDiff = void 0,
3695 newFrom = void 0,
3696 prev = void 0,
3697 el = void 0,
3698 k = void 0;
3699
3700 var sort = function sort(a, b) {
3701 return a.val - b.val;
3702 };
3703
3704 for (var _i = 0; _i < length; _i++) {
3705 var type = is[_i];
3706
3707 if ($router[type]) {
3708 el = $router[type][name];
3709 prev = $router[type][parentTpl];
3710 k = type + '_';
3711
3712 if ($routerPositions[type]) {
3713 from = $routerPositions[type][parentTpl];
3714 newFrom = null;
3715 }
3716 }
3717
3718 for (var key in el) {
3719 if (!el.hasOwnProperty(key)) {
3720 break;
3721 }
3722
3723 var current = el[key],
3724 parent = !tb[k + key].drop && prev[key];
3725
3726 var adv = 0,
3727 block = $cache[name].slice(current.from, current.to);
3728
3729 if (parent) {
3730 if (parent.output != null && current.output == null && _i % 2 === 0) {
3731 current.output = parent.output;
3732
3733 if (type === 'const') {
3734 block += current.output;
3735 } else {
3736 this.getBlockOutput(type, name)[key] = current.output;
3737 }
3738 }
3739
3740 blockDiff = block.length - $cache[parentTpl].slice(parent.from, parent.to).length;
3741 }
3742
3743 var diff = parent ? parent.from : from;
3744 advDiff.sort(sort);
3745
3746 for (var _i2 = 0; _i2 < advDiff.length; _i2++) {
3747 if (advDiff[_i2].val <= diff) {
3748 adv += advDiff[_i2].adv;
3749 } else {
3750 break;
3751 }
3752 }
3753
3754 if (parent && _i % 2 === 0) {
3755 if (type !== 'block' && (type !== 'const' || !current.block)) {
3756 newFrom = parent.from + adv + block.length;
3757 from += blockDiff;
3758
3759 if (newFrom > from) {
3760 from = newFrom + constLength;
3761 }
3762 }
3763
3764 res = res.slice(0, parent.from + adv) + block + res.slice(parent.to + adv);
3765
3766 advDiff.push({
3767 adv: blockDiff,
3768 val: parent.from
3769 });
3770 } else if (!parent) {
3771 switch (type) {
3772 case 'block_add':
3773 if (!current.external) {
3774 res += block;
3775 break;
3776 }
3777
3778 case 'block_add':
3779 case 'const_add':
3780 if (newFrom === null) {
3781 newFrom = from;
3782 from += adv;
3783 }
3784
3785 block = type === 'const_add' ? '' + (current.needPrfx ? ADV_LEFT_BOUND : '') + LEFT_BOUND + block + RIGHT_BOUND : block;
3786
3787 res = res.slice(0, from) + block + res.slice(from);
3788
3789 advDiff.push({
3790 adv: block.length,
3791 val: newFrom
3792 });
3793
3794 from = from + block.length;
3795 break;
3796 }
3797 }
3798 }
3799 }
3800
3801 return res;
3802};
3803
3804var comments = Object.keys(COMMENTS);
3805
3806/**
3807 * Returns a comment type for the specified position of a string
3808 *
3809 * @param {string} str - source string
3810 * @param {number} pos - position
3811 * @return {(string|boolean)}
3812 */
3813function getCommentType(str, pos) {
3814 if (!str) {
3815 return false;
3816 }
3817
3818 for (var i = 0; i < comments.length; i++) {
3819 var el = comments[i],
3820 chunk = str.substr(pos, el.length);
3821
3822 if (COMMENTS[chunk] && chunk === el) {
3823 return el;
3824 }
3825 }
3826
3827 return false;
3828}
3829
3830/**
3831 * Returns a string of property concatenation for the specified value
3832 *
3833 * @param {string} val - source value
3834 * @return {string}
3835 */
3836function concatProp(val) {
3837 return val[0] === '[' ? val : '.' + val;
3838}
3839
3840var commandRgxp = /([^\s]+).*/;
3841var nonBlockCommentRgxp = /([^\\])\/\/\/\s?.*/;
3842var rightPartRgxp = new RegExp('(?:' + r(ADV_LEFT_BOUND) + '?' + LEFT_BOUND + '__&-__' + r(RIGHT_BOUND) + '|)\\s*$');
3843var rightWSRgxp = /\s*$/;
3844var lastSymbolRgxp = new RegExp('(' + r(ADV_LEFT_BOUND) + '|\\\\)$');
3845
3846var endDirInit = void 0;
3847var needSpace = void 0;
3848var eol$1 = void 0;
3849
3850/**
3851 * Returns a template description object from a string from the specified position
3852 * (Jade-Like to SS native)
3853 *
3854 * @param {string} str - source string
3855 * @param {number} i - start position
3856 * @return {{code: string, length: number, error: (?boolean|undefined)}}
3857 */
3858Parser.prototype.toBaseSyntax = function (str, i) {
3859 var _this = this;
3860
3861 needSpace = !this.tolerateWhitespaces;
3862 eol$1 = this.eol;
3863 endDirInit = false;
3864
3865 var clrL = 0,
3866 init = true,
3867 spaces = 0,
3868 space = '';
3869
3870 var struct = void 0,
3871 code = '';
3872
3873 var length = 0,
3874 tSpace = 0;
3875
3876 /**
3877 * @param {!Object} struct
3878 * @param {!Object} obj
3879 */
3880 function end(struct, obj) {
3881 if (struct.block) {
3882 var isChain = $dirChain[struct.name] && $dirChain[struct.name][obj.name],
3883 isEnd = $dirEnd[struct.name] && $dirEnd[struct.name][obj.name];
3884
3885 if (isChain) {
3886 obj.block = true;
3887 obj.name = struct.name;
3888 }
3889
3890 if (isEnd) {
3891 obj.block = false;
3892 }
3893
3894 if (!isChain && !isEnd) {
3895 code = appendDirEnd(code, struct);
3896 }
3897 } else {
3898 endDirInit = false;
3899 }
3900 }
3901
3902 var _loop = function _loop(_j) {
3903 length++;
3904
3905 var el = str[_j],
3906 next = str[_j + 1];
3907
3908 var next2str = str.substr(_j, 2),
3909 diff2str = str.substr(_j + 1, 2);
3910
3911 if (eol.test(el)) {
3912 tSpace++;
3913
3914 if (next2str === '\r\n') {
3915 return 'continue';
3916 }
3917
3918 if (clrL) {
3919 if (clrL === 1 && needSpace) {
3920 code += '' + ADV_LEFT_BOUND + LEFT_BOUND + '__&-__' + RIGHT_BOUND;
3921 }
3922
3923 code += el;
3924 }
3925
3926 clrL++;
3927 init = true;
3928 spaces = 0;
3929 space = eol$1;
3930 } else if (init) {
3931 if (ws$1.test(el)) {
3932 spaces++;
3933 space += el;
3934 tSpace++;
3935 } else {
3936 var adv = el === ADV_LEFT_BOUND ? ADV_LEFT_BOUND : '',
3937 nextSpace = false,
3938 diff = void 0;
3939
3940 init = false;
3941 clrL = 0;
3942
3943 if (adv) {
3944 diff = SHORTS[diff2str] ? 3 : SHORTS[next] ? 2 : 1;
3945 } else {
3946 diff = SHORTS[next2str] ? 2 : 1;
3947 }
3948
3949 var chr = str[_j + diff];
3950 nextSpace = !chr || ws$1.test(chr);
3951
3952 var dir = void 0,
3953 replacer = void 0;
3954
3955 if (adv) {
3956 dir = el === ADV_LEFT_BOUND && next !== LEFT_BOUND && nextSpace;
3957 replacer = dir && ($dirNameShorthands[diff2str] || $dirNameShorthands[next]);
3958 } else {
3959 dir = Boolean(SHORTS[el] || SHORTS[next2str]) && el !== LEFT_BOUND && nextSpace;
3960 replacer = dir && ($dirNameShorthands[next2str] || $dirNameShorthands[el]);
3961 }
3962
3963 var parentAdv = false;
3964 if (struct) {
3965 if (struct.spaces < spaces && struct.block) {
3966 if (struct.adv) {
3967 parentAdv = true;
3968 }
3969 } else if (struct.spaces === spaces || struct.spaces < spaces && !struct.block) {
3970 if (struct.parent && struct.parent.adv) {
3971 parentAdv = true;
3972 }
3973 }
3974 }
3975
3976 var decl = getLineDesc(str, dir && BASE_SHORTS[el] || el === IGNORE ? _j + 1 : _j, {
3977 adv: parentAdv,
3978 comment: next2str === MULT_COMMENT_START,
3979 dir: dir,
3980 i18n: _this.localization
3981 });
3982
3983 if (!decl) {
3984 _this.error('invalid syntax');
3985 return {
3986 v: {
3987 code: '',
3988 error: true,
3989 length: 0
3990 }
3991 };
3992 }
3993
3994 if (replacer) {
3995 decl.name = replacer(decl.name).replace(commandRgxp, '$1');
3996 }
3997
3998 var obj = {
3999 adv: adv,
4000 block: dir && $blockDirs[decl.name],
4001 dir: dir,
4002 name: decl.name,
4003 parent: null,
4004 space: space,
4005 spaces: spaces,
4006 text: !dir || $textDirs[decl.name],
4007 trim: dir && $dirTrim[decl.name] || {}
4008 };
4009
4010 var toText = function toText() {
4011 if (BASE_SHORTS[el]) {
4012 decl.command = next2str + decl.command;
4013 }
4014
4015 dir = obj.dir = obj.block = false;
4016 obj.adv = adv = ADV_LEFT_BOUND;
4017 obj.text = true;
4018 };
4019
4020 if (struct) {
4021 if (struct.spaces < spaces && struct.block) {
4022 obj.parent = struct;
4023
4024 if (!obj.adv && struct.adv) {
4025 toText();
4026 }
4027 } else if (struct.spaces === spaces || struct.spaces < spaces && !struct.block) {
4028 obj.parent = struct.parent;
4029
4030 if (!obj.adv && struct.parent && struct.parent.adv) {
4031 toText();
4032 }
4033
4034 end(struct, obj);
4035 if (!struct.parent) {
4036 return {
4037 v: {
4038 code: code,
4039 length: length - tSpace - 1
4040 }
4041 };
4042 }
4043 } else {
4044 while (struct.spaces >= spaces) {
4045 end(struct, obj);
4046 if (!(struct = struct.parent)) {
4047 return {
4048 v: {
4049 code: code,
4050 length: length - tSpace - 1
4051 }
4052 };
4053 }
4054 }
4055
4056 obj.parent = struct;
4057 if (!obj.adv && struct.adv) {
4058 toText();
4059 }
4060 }
4061 }
4062
4063 var parts = void 0,
4064 txt = void 0;
4065
4066 decl.command = decl.command.replace(lastSymbolRgxp, '\\$1');
4067
4068 if (dir) {
4069 if (decl.sComment) {
4070 parts = [decl.command];
4071 } else {
4072 parts = _this.replaceDangerBlocks(decl.command).split(INLINE);
4073
4074 for (var _i = 0; _i < parts.length; _i++) {
4075 parts[_i] = _this.pasteDangerBlocks(parts[_i]);
4076 }
4077
4078 if (obj.trim.left && !parts[1]) {
4079 parts[1] = '' + ADV_LEFT_BOUND + LEFT_BOUND + '__&+__' + RIGHT_BOUND;
4080 }
4081 }
4082
4083 txt = parts.slice(1).join(INLINE);
4084 txt = txt && txt.trim();
4085 }
4086
4087 struct = obj;
4088 code += space;
4089
4090 if (needSpace && (obj.text || !Snakeskin$1.Directives[obj.name])) {
4091 code += '' + ADV_LEFT_BOUND + LEFT_BOUND + '__&-__' + RIGHT_BOUND;
4092 }
4093
4094 var s = dir ? adv + LEFT_BOUND : '',
4095 e = dir ? RIGHT_BOUND : '';
4096
4097 code += s + (dir ? parts[0] : decl.command).replace(nonBlockCommentRgxp, '$1') + e;
4098 endDirInit = false;
4099
4100 var declDiff = decl.length - 1;
4101 tSpace = 0;
4102
4103 length += declDiff;
4104 _j += declDiff;
4105
4106 if (dir && txt) {
4107 var inline = {
4108 adv: adv,
4109 block: false,
4110 dir: false,
4111 parent: obj,
4112 space: '',
4113 spaces: spaces + 1
4114 };
4115
4116 inline.parent = obj;
4117 struct = inline;
4118 code += txt;
4119 }
4120 }
4121 }
4122 j = _j;
4123 };
4124
4125 for (var j = i; j < str.length; j++) {
4126 var _ret = _loop(j);
4127
4128 switch (_ret) {
4129 case 'continue':
4130 continue;
4131
4132 default:
4133 if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
4134 }
4135 }
4136
4137 while (struct) {
4138 code = appendDirEnd(code, struct);
4139 struct = struct.parent;
4140 }
4141
4142 return { code: code, length: length };
4143};
4144
4145/**
4146 * Appends the directive end for a resulting string
4147 * and returns a new string
4148 *
4149 * @param {string} str - resulting string
4150 * @param {!Object} struct - structure object
4151 * @return {string}
4152 */
4153function appendDirEnd(str, struct) {
4154 if (!struct.block) {
4155 return str;
4156 }
4157
4158 var _rightWSRgxp$exec = rightWSRgxp.exec(str),
4159 _rightWSRgxp$exec2 = slicedToArray(_rightWSRgxp$exec, 1),
4160 rightSpace = _rightWSRgxp$exec2[0];
4161
4162 str = str.replace(rightPartRgxp, '');
4163
4164 var s = ADV_LEFT_BOUND + LEFT_BOUND,
4165 e = RIGHT_BOUND;
4166
4167 var tmp = void 0;
4168 if (needSpace) {
4169 tmp = '' + (struct.trim.right ? '' : eol$1) + (endDirInit ? '' : s + '__&+__' + e) + (struct.trim.right ? eol$1 : '');
4170 } else {
4171 tmp = eol$1 + struct.space.slice(1);
4172 }
4173
4174 endDirInit = true;
4175 str += '' + tmp + (struct.adv + LEFT_BOUND) + '__end__' + e + s + '__cutLine__' + e;
4176
4177 if (rightSpace && needSpace) {
4178 str += s + '__&-__' + RIGHT_BOUND;
4179 }
4180
4181 return str + rightSpace;
4182}
4183
4184/**
4185 * Returns an object description for a Jade-Like syntax string
4186 *
4187 * @param {string} str - source string
4188 * @param {number} i - start position
4189 * @param {{adv: boolean, comment: boolean, dir: boolean, i18n: boolean}} params - parameters
4190 * @return {{command: string, lastEl: string, length: number, name: string, sComment: boolean}}
4191 */
4192function getLineDesc(str, i, params) {
4193 var dir = params.dir,
4194 i18n = params.i18n;
4195
4196 var comment = params.comment,
4197 command = '',
4198 name = '';
4199
4200
4201 var lastEl = '',
4202 lastElI = 0,
4203 length = -1,
4204 skip = 0;
4205
4206 var escape = false,
4207 sComment = false,
4208 inline = false;
4209
4210 var bOpen = false,
4211 bEnd$$1 = true;
4212
4213 var begin = 0,
4214 filterStart$$1 = false,
4215 bStart = void 0;
4216
4217 var part = '',
4218 rPart = '';
4219
4220 var concatLine = false,
4221 nmBrk = null;
4222
4223 for (var _j2 = i; _j2 < str.length; _j2++) {
4224 var _el = str[_j2],
4225 cEscape = escape;
4226
4227 if (_el === '\\' || escape) {
4228 escape = !escape;
4229 }
4230
4231 length++;
4232 if (eol.test(_el)) {
4233 if (!comment && !bOpen) {
4234 rPart = sComment ? '' : part;
4235 part = '';
4236 }
4237
4238 var prevEl = lastEl;
4239
4240 var brk = false;
4241
4242 lastEl = '';
4243 if (comment || sComment && concatLine) {
4244 command += _el;
4245 } else if (!sComment) {
4246 if (dir) {
4247 var dirStart = ws$1.test(str[_j2 - 2]);
4248
4249 var literal = void 0;
4250 brk = dirStart && prevEl === CONCAT_END;
4251
4252 if (dirStart && (prevEl === CONCAT && command !== CONCAT || brk)) {
4253 literal = prevEl;
4254 command = command.slice(0, lastElI - 1) + command.slice(lastElI + 1);
4255 } else if (concatLine && !bOpen) {
4256 command += _el;
4257 }
4258
4259 if (concatLine && !brk) {
4260 continue;
4261 }
4262
4263 if (literal === CONCAT || bOpen) {
4264 concatLine = literal !== CONCAT ? 1 : true;
4265
4266 if (!bOpen) {
4267 command += _el;
4268 }
4269
4270 continue;
4271 }
4272 } else if (begin || bOpen === I18N) {
4273 command += _el;
4274 continue;
4275 }
4276 }
4277
4278 if (comment || concatLine && !brk) {
4279 sComment = false;
4280 continue;
4281 }
4282
4283 return {
4284 command: command,
4285 lastEl: lastEl,
4286 length: length,
4287 name: name,
4288 sComment: !inline && sComment
4289 };
4290 }
4291
4292 if (!bOpen && !cEscape) {
4293 var commentType = getCommentType(str, _j2);
4294
4295 if (comment) {
4296 comment = commentType !== MULT_COMMENT_END;
4297
4298 if (!comment) {
4299 skip += MULT_COMMENT_END.length;
4300 }
4301 } else if (!sComment) {
4302 comment = commentType === MULT_COMMENT_START;
4303
4304 if (!comment) {
4305 sComment = commentType === SINGLE_COMMENT;
4306 }
4307 }
4308 }
4309
4310 if (!comment && !sComment && !skip) {
4311 if (!bOpen) {
4312 if (ESCAPES_END[_el] || ESCAPES_END_WORD[rPart]) {
4313 bEnd$$1 = true;
4314 } else if (bEnd.test(_el)) {
4315 bEnd$$1 = false;
4316 }
4317
4318 if (sysWord.test(_el)) {
4319 part += _el;
4320 } else {
4321 rPart = part;
4322 part = '';
4323 }
4324
4325 var _skip = false;
4326 if (_el === FILTER && filterStart.test(str[_j2 + 1])) {
4327 filterStart$$1 = true;
4328 bEnd$$1 = false;
4329 _skip = true;
4330 } else if (filterStart$$1 && ws$1.test(_el)) {
4331 filterStart$$1 = false;
4332 bEnd$$1 = true;
4333 _skip = true;
4334 }
4335
4336 if (!_skip) {
4337 if (ESCAPES_END[_el]) {
4338 bEnd$$1 = true;
4339 } else if (bEnd.test(_el)) {
4340 bEnd$$1 = false;
4341 }
4342 }
4343
4344 if (dir) {
4345 if (!inline) {
4346 inline = str.substr(_j2, INLINE.length) === INLINE;
4347 }
4348 } else if (!cEscape) {
4349 if (begin) {
4350 if (_el === LEFT_BOUND && (params.dir || str[_j2 - 1] !== ADV_LEFT_BOUND || _j2 - 1 !== bStart)) {
4351 begin++;
4352 } else if (_el === RIGHT_BOUND) {
4353 begin--;
4354 }
4355 } else if (!params.dir && params.adv ? _el === ADV_LEFT_BOUND && str[_j2 + 1] === LEFT_BOUND : _el === LEFT_BOUND) {
4356 bStart = _j2;
4357 bEnd$$1 = false;
4358 begin++;
4359 }
4360 }
4361 }
4362
4363 if (!cEscape) {
4364 if ((ESCAPES[_el] || _el === I18N && i18n) && !bOpen && (_el !== '/' || bEnd$$1)) {
4365 bOpen = _el;
4366 } else if ((ESCAPES[_el] || _el === I18N && i18n) && bOpen === _el) {
4367 bOpen = false;
4368
4369 if (concatLine === 1) {
4370 concatLine = false;
4371 }
4372
4373 bEnd$$1 = false;
4374 }
4375 }
4376 }
4377
4378 if (skip) {
4379 skip--;
4380 }
4381
4382 var _needSpace = lineWs.test(_el);
4383
4384 if (_needSpace) {
4385 if (nmBrk === false) {
4386 nmBrk = true;
4387 }
4388 } else {
4389 lastEl = _el;
4390 lastElI = command.length;
4391 }
4392
4393 if (!nmBrk && !_needSpace) {
4394 if (nmBrk === null) {
4395 nmBrk = false;
4396 }
4397
4398 name += _el;
4399 }
4400
4401 if (nmBrk !== null) {
4402 command += _el;
4403 }
4404 }
4405
4406 if (dir && lastEl === CONCAT_END && ws$1.test(command[lastElI - 1])) {
4407 command = command.slice(0, lastElI) + command.slice(lastElI + 1);
4408 }
4409
4410 return {
4411 command: command,
4412 lastEl: lastEl,
4413 length: length,
4414 name: name,
4415 sComment: !inline && sComment
4416 };
4417}
4418
4419/**
4420 * Escapes backslashes in a string
4421 *
4422 * @param {?} str - source string
4423 * @return {string}
4424 */
4425function escapeBackslashes(str) {
4426 return String(str).replace(backSlashes, '\\\\');
4427}
4428
4429/**
4430 * Escapes single quotes in a string
4431 *
4432 * @param {?} str - source string
4433 * @return {string}
4434 */
4435function escapeSingleQuotes(str) {
4436 return String(str).replace(singleQuotes, '\\\'');
4437}
4438
4439/**
4440 * Escapes double quotes in a string
4441 *
4442 * @param {?} str - source string
4443 * @return {string}
4444 */
4445function escapeDoubleQuotes(str) {
4446 return String(str).replace(doubleQuotes, '\\"');
4447}
4448
4449var nRgxp = /\n/g;
4450var rRgxp$1 = /\r/g;
4451
4452/**
4453 * Escapes EOLs in a string
4454 *
4455 * @param {?} str - source string
4456 * @return {string}
4457 */
4458function escapeEOLs(str) {
4459 return String(str).replace(nRgxp, '\\n').replace(rRgxp$1, '\\r');
4460}
4461
4462/**
4463 * Applies default SS escaping to a string
4464 *
4465 * @param {?} str - source string
4466 * @return {string}
4467 */
4468function applyDefEscape(str) {
4469 return escapeEOLs(String(str).replace(backSlashes, '\\\\').replace(singleQuotes, '\\\''));
4470}
4471
4472var tplVarsRgxp = /__SNAKESKIN__(\d+)_/g;
4473
4474/**
4475 * Replaces all found blocks __SNAKESKIN__\d+_ to real content in a string
4476 * and returns a new string
4477 *
4478 * @param {string} str - source string
4479 * @param {(?function(string): string)=} [opt_fn] - function wrapper
4480 * @return {string}
4481 */
4482Parser.prototype.pasteTplVarBlocks = function (str, opt_fn) {
4483 var _this = this;
4484
4485 return str.replace(tplVarsRgxp, function (str, pos) {
4486 var val = _this.dirContent[pos];
4487 return '\' + (' + (opt_fn ? opt_fn(val) : val) + ') + \'';
4488 });
4489};
4490
4491/**
4492 * Replaces found matches ${ ... } from a string to SS calls
4493 *
4494 * @param {string} str - source string
4495 * @param {?$$SnakeskinParserReplaceTplVarsParams=} [opt_params] - additional parameters:
4496 *
4497 * *) [unsafe=false] - if is true, then default filters won't be applied to the resulting string
4498 * *) [replace=false] - if is true, then matches will be replaced to __SNAKESKIN__\d+_
4499 *
4500 * @param {(?function(string): string)=} [opt_wrap] - function wrapper
4501 * @return {string}
4502 */
4503Parser.prototype.replaceTplVars = function (str, opt_params, opt_wrap) {
4504 var _any = any(opt_params || {}),
4505 unsafe = _any.unsafe,
4506 replace = _any.replace;
4507
4508 str = this.pasteDangerBlocks(str);
4509
4510 var begin = 0;
4511
4512 var dir = '',
4513 res = '';
4514
4515 var i18nStr = '',
4516 i18nChunk = '',
4517 i18nStart = false;
4518
4519 var escape = false,
4520 comment = false,
4521 filterStart$$1 = false;
4522
4523 var bOpen = false,
4524 bEnd$$1 = true,
4525 bEscape = false;
4526
4527 var part = '',
4528 rPart = '';
4529
4530 var eolMap = {
4531 'n': '\n',
4532 'r': '\r'
4533 };
4534
4535 for (var i = 0; i < str.length; i++) {
4536 var cEscape = escape,
4537 pos = i,
4538 next = str[i + 1];
4539
4540 var el = str[i];
4541
4542 if (str.substr(i, 2) === '\r\n') {
4543 continue;
4544 }
4545
4546 if (begin) {
4547 if (!bOpen) {
4548 if (el === '\\' && STRONG_SYS_ESCAPES[next] || escape) {
4549 escape = !escape;
4550 }
4551
4552 if (escape) {
4553 continue;
4554 }
4555
4556 if (el === '\\' && eolMap[next]) {
4557 el = eolMap[next];
4558 i++;
4559 }
4560
4561 if (!cEscape && !i18nStart) {
4562 var commentType = getCommentType(str, pos);
4563
4564 if (commentType) {
4565 if (!comment || commentType === MULT_COMMENT_END && comment === MULT_COMMENT_START) {
4566 i += commentType.length - 1;
4567
4568 if (comment) {
4569 comment = false;
4570 continue;
4571 } else {
4572 comment = commentType;
4573 }
4574 }
4575 } else if (eol.test(el) && comment === SINGLE_COMMENT) {
4576 comment = false;
4577 }
4578 }
4579
4580 if (comment) {
4581 continue;
4582 }
4583
4584 if (i18nStart) {
4585 if (!cEscape && el === '"' && !this.language) {
4586 el = '\\"';
4587 }
4588
4589 if (cEscape || el !== I18N) {
4590 i18nStr += el;
4591 if (this.language) {
4592 continue;
4593 }
4594 }
4595 }
4596
4597 if (el === I18N && this.localization && !cEscape) {
4598 if (i18nStart && i18nStr && this.words && !this.words[i18nStr]) {
4599 this.words[i18nStr] = i18nStr;
4600 }
4601
4602 if (this.language) {
4603 if (i18nStart) {
4604 var word = this.language[i18nStr] || '';
4605 el = '\'' + applyDefEscape(isFunction(word) ? word() : word) + '\'';
4606 i18nStart = false;
4607 i18nStr = '';
4608 } else {
4609 el = '';
4610 i18nStart = true;
4611 }
4612 } else {
4613 if (i18nStart) {
4614 el = '"';
4615 i18nStr = '';
4616 i18nStart = false;
4617
4618 if (next === '(') {
4619 el += ',';
4620 i++;
4621 } else {
4622 if (this.i18nFnOptions) {
4623 el += ', ' + this.i18nFnOptions;
4624 }
4625
4626 el += ')';
4627 }
4628 } else {
4629 i18nStart = true;
4630 el = this.i18nFn + '("';
4631 }
4632 }
4633 }
4634
4635 if (!i18nStart) {
4636 if (ESCAPES_END[el] || ESCAPES_END_WORD[rPart]) {
4637 bEnd$$1 = true;
4638 } else if (bEnd.test(el)) {
4639 bEnd$$1 = false;
4640 }
4641
4642 if (sysWord.test(el)) {
4643 part += el;
4644 } else {
4645 rPart = part;
4646 part = '';
4647 }
4648
4649 var skip = false;
4650 if (el === FILTER && filterStart.test(next)) {
4651 filterStart$$1 = true;
4652 bEnd$$1 = false;
4653 skip = true;
4654 } else if (filterStart$$1 && ws$1.test(el)) {
4655 filterStart$$1 = false;
4656 bEnd$$1 = true;
4657 skip = true;
4658 }
4659
4660 if (!skip) {
4661 if (ESCAPES_END[el]) {
4662 bEnd$$1 = true;
4663 } else if (bEnd.test(el)) {
4664 bEnd$$1 = false;
4665 }
4666 }
4667
4668 if (!cEscape) {
4669 if (el === LEFT_BOUND) {
4670 begin++;
4671 } else if (el === RIGHT_BOUND) {
4672 begin--;
4673 }
4674 }
4675 }
4676 }
4677
4678 if (ESCAPES[el] && !bOpen && !cEscape && (el !== '/' || bEnd$$1)) {
4679 bOpen = el;
4680 } else if (bOpen && (el === '\\' || bEscape)) {
4681 bEscape = !bEscape;
4682 } else if (ESCAPES[el] && bOpen === el && !bEscape) {
4683 bOpen = false;
4684 bEnd$$1 = false;
4685 }
4686
4687 if (begin) {
4688 dir += el;
4689 } else {
4690 escape = false;
4691
4692 if (opt_wrap) {
4693 dir = opt_wrap(dir);
4694 }
4695
4696 var tmp = this.out(this.replaceDangerBlocks(dir).trim() || '\'\'', { unsafe: unsafe });
4697
4698 if (replace) {
4699 res += '__SNAKESKIN__' + this.dirContent.length + '_';
4700 this.dirContent.push(tmp);
4701 } else {
4702 res += '\' + (' + tmp + ') + \'';
4703 }
4704 }
4705 } else {
4706 if (el === '\\' && (MICRO_TEMPLATE_ESCAPES[next] || next === I18N && this.localization) || escape) {
4707 escape = !escape;
4708 }
4709
4710 if (escape) {
4711 continue;
4712 }
4713
4714 if (i18nStart) {
4715 if (!cEscape && el === '"' && !this.language) {
4716 el = '\\"';
4717 }
4718
4719 if (cEscape || el !== I18N) {
4720 i18nStr += el;
4721 if (this.language) {
4722 continue;
4723 }
4724 }
4725 }
4726
4727 if (el === I18N && this.localization && !cEscape) {
4728 if (i18nStart && i18nStr && this.words && !this.words[i18nStr]) {
4729 this.words[i18nStr] = i18nStr;
4730 }
4731
4732 if (this.language) {
4733 if (i18nStart) {
4734 var _word = this.language[i18nStr] || '';
4735 el = isFunction(_word) ? _word() : _word;
4736 i18nStart = false;
4737 i18nStr = '';
4738 } else {
4739 el = '';
4740 i18nStart = true;
4741 }
4742 } else {
4743 if (i18nStart) {
4744 i18nStr = '';
4745 i18nChunk += '"';
4746 i18nStart = false;
4747
4748 if (this.i18nFnOptions) {
4749 i18nChunk += ', ' + this.i18nFnOptions;
4750 }
4751
4752 var _tmp = this.out(this.replaceDangerBlocks(i18nChunk + ')').trim() || '\'\'', { unsafe: unsafe });
4753
4754 if (replace) {
4755 res += '__SNAKESKIN__' + this.dirContent.length + '_';
4756 this.dirContent.push(_tmp);
4757 } else {
4758 res += '\' + (' + _tmp + ') + \'';
4759 }
4760
4761 i18nChunk = '';
4762 continue;
4763 } else {
4764 i18nStart = true;
4765 el = this.i18nFn + '("';
4766 }
4767 }
4768 }
4769
4770 if (i18nStart) {
4771 i18nChunk += el;
4772 } else {
4773 if (!cEscape && str.substr(pos, MICRO_TEMPLATE.length) === MICRO_TEMPLATE) {
4774 begin++;
4775 dir = '';
4776 i += MICRO_TEMPLATE.length - 1;
4777 escape = false;
4778 continue;
4779 }
4780
4781 res += el !== '\\' || cEscape ? applyDefEscape(el) : escapeSingleQuotes(el);
4782 }
4783 }
4784 }
4785
4786 return res;
4787};
4788
4789var babylon = GLOBAL.babylon || GLOBAL.esprima || require('babylon');
4790
4791var _templateObject$1 = taggedTemplateLiteral(['[\'', '\']'], ['[\'', '\']']);
4792
4793/**
4794 * Returns a real directive name
4795 *
4796 * @param {string} name - source name
4797 * @return {string}
4798 */
4799Parser.prototype.getDirName = function (name) {
4800 return $dirNameAliases[name] || name;
4801};
4802
4803/**
4804 * Returns a function name from a string
4805 *
4806 * @param {string} str - source string
4807 * @param {?boolean=} opt_empty - if is true, then function name can be empty
4808 * @return {string}
4809 */
4810Parser.prototype.getFnName = function (str, opt_empty) {
4811 var tmp = /^[^(]+/.exec(str),
4812 val = tmp ? tmp[0].trim() : '';
4813
4814 if (!opt_empty && !val) {
4815 this.error('invalid "' + this.name + '" declaration');
4816 }
4817
4818 return val;
4819};
4820
4821/**
4822 * Replaces all find blocks %fileName% to the active file name
4823 * and returns a new string
4824 *
4825 * @param {string} str - source string
4826 * @return {string}
4827 */
4828Parser.prototype.replaceFileNamePatterns = function (str) {
4829 var _this = this;
4830
4831 var file = this.info.file;
4832
4833
4834 var basename = void 0,
4835 dirname = void 0;
4836
4837 str = this.replaceDangerBlocks(str.replace(/(.?)%(fileName|dirName)%/g, function (str, $1, placeholder) {
4838 if (!file) {
4839 _this.error('the placeholder %' + placeholder + '% can\'t be used without the "file" option');
4840 return '';
4841 }
4842
4843 if (!IS_NODE) {
4844 _this.error('the placeholder %' + placeholder + '% can\'t be used with live compilation in a browser');
4845 return '';
4846 }
4847
4848 var path = require('path');
4849
4850 var res = void 0;
4851 switch (placeholder) {
4852 case 'fileName':
4853 if (!basename) {
4854 basename = path.basename(file, path.extname(file));
4855 }
4856
4857 res = basename;
4858 break;
4859
4860 case 'dirName':
4861 if (!dirname) {
4862 dirname = path.basename(path.dirname(file));
4863 }
4864
4865 res = dirname;
4866 break;
4867 }
4868
4869 if ($1) {
4870 if ($1 !== '.') {
4871 res = $1 + '\'' + res + '\'';
4872 } else {
4873 res = $1 + res;
4874 }
4875 }
4876
4877 return res;
4878 }));
4879
4880 return str;
4881};
4882
4883var nmssRgxp = new RegExp('^(' + r(G_MOD) + '?)\\[');
4884var nmsRgxp = /\[/g;
4885var nmeRgxp = /]/g;
4886
4887/**
4888 * Returns a block name from a string
4889 *
4890 * @param {string} name - source string
4891 * @param {?boolean=} opt_parseLiteralScope - if true, then wil be parse literal scope declaration
4892 * @return {string}
4893 */
4894Parser.prototype.getBlockName = function (name, opt_parseLiteralScope) {
4895 var _this2 = this;
4896
4897 try {
4898 var parts = this.replaceFileNamePatterns(name).replace(nmssRgxp, function (str, $0) {
4899 return ($0 ? _this2.scope[_this2.scope.length - 1] + '.' : '') + '%';
4900 }).replace(nmsRgxp, '.%').replace(nmeRgxp, '').split('.');
4901
4902 var res = '';
4903 for (var i = 0; i < parts.length; i++) {
4904 var el = parts[i];
4905
4906 var custom = el[0] === '%';
4907
4908 el = opt_parseLiteralScope && i === 0 || custom ? this.out(custom ? el.slice(1) : el, { unsafe: true }) : el;
4909
4910 if (custom) {
4911 res += ws(_templateObject$1, applyDefEscape(this.returnEvalVal(el)));
4912 continue;
4913 }
4914
4915 res += res ? '.' + el : el;
4916 }
4917
4918 name = res.trim();
4919 babylon.parse(name);
4920 } catch (err) {
4921 this.error(err.message);
4922 return '';
4923 }
4924
4925 return name;
4926};
4927
4928/**
4929 * Normalizes the specified block name
4930 *
4931 * @param {string} name
4932 * @return {string}
4933 */
4934Parser.prototype.normalizeBlockName = function (name) {
4935 name = this.replaceDangerBlocks(name).replace(nmsRgxp, '.').replace(nmeRgxp, '');
4936
4937 return this.pasteDangerBlocks(name).replace(/\.['"]|['"]\./g, '.').replace(/^\.|['"]$/, '');
4938};
4939
4940/**
4941 * Returns an array of template names
4942 * that are involved in an inheritance chain
4943 *
4944 * @param {string} name - template name
4945 * @return {!Array}
4946 */
4947Parser.prototype.getExtList = function (name) {
4948 if ($extList[name]) {
4949 return $extList[name].slice();
4950 }
4951
4952 var res = [];
4953 while (name = $extMap[name]) {
4954 res.unshift(name);
4955 }
4956
4957 $extList[name] = res;
4958 return res.slice();
4959};
4960
4961/**
4962 * Clears the SS cache scope of the specified template
4963 *
4964 * @param {string} name - template name
4965 * @return {!Parser}
4966 */
4967Parser.prototype.clearScopeCache = function (name) {
4968 for (var key in $scope) {
4969 if (!$scope.hasOwnProperty(key)) {
4970 break;
4971 }
4972
4973 var cluster = $scope[key],
4974 el = cluster[name];
4975
4976 if (key === 'template') {
4977 if (el && el.parent) {
4978 delete el.parent.children[name];
4979 }
4980 } else {
4981 for (var _key in el) {
4982 if (!el.hasOwnProperty(el)) {
4983 break;
4984 }
4985
4986 if (el[_key].parent) {
4987 delete el[_key].parent.children[name];
4988 }
4989 }
4990 }
4991
4992 delete cluster[name];
4993 }
4994
4995 return this;
4996};
4997
4998/**
4999 * Returns diff of a directive command and directive declaration
5000 *
5001 * @param {number} length - command length
5002 * @return {number}
5003 */
5004Parser.prototype.getDiff = function (length) {
5005 return length + Number(this.needPrfx) + 1;
5006};
5007
5008/**
5009 * Resets a layer of compilation parameters
5010 * @return {!Parser}
5011 */
5012Parser.prototype.popParams = function () {
5013 this.params.pop();
5014
5015 var last = this.params[this.params.length - 1];
5016
5017 for (var key in last) {
5018 if (!last.hasOwnProperty(key)) {
5019 break;
5020 }
5021
5022 this[key] = last[key];
5023 }
5024
5025 return this;
5026};
5027
5028/**
5029 * Returns data from the SS cache by the specified key
5030 *
5031 * @param {?string} key - cache key
5032 * @param {string} code - source SS code
5033 * @param {!Object} params - compile parameters
5034 * @param {!Object} ctx - context
5035 * @return {(string|undefined)}
5036 */
5037function getFromCache(key, code, params, ctx) {
5038 if (IS_NODE && ctx !== NULL && $globalFnCache[key]) {
5039 Snakeskin$1.forEach($globalFnCache[key][code], function (el, key) {
5040 ctx[key] = el;
5041 });
5042 }
5043
5044 var cache = $globalCache[key] && $globalCache[key][code];
5045
5046 if (!cache) {
5047 return;
5048 }
5049
5050 if (params.words) {
5051 if (!cache.words) {
5052 return;
5053 }
5054
5055 Snakeskin$1.forEach(cache.words, function (el, key) {
5056 params.words[key] = el;
5057 });
5058 }
5059
5060 if (params.debug) {
5061 if (!cache.debug) {
5062 return;
5063 }
5064
5065 Snakeskin$1.forEach(cache.debug, function (el, key) {
5066 params.debug[key] = el;
5067 });
5068 }
5069
5070 return cache.text;
5071}
5072
5073/**
5074 * Returns a cache key for the current SS process
5075 *
5076 * @param {!Object} params - compile parameters
5077 * @param {!Object} ctx - context
5078 * @return {?string}
5079 */
5080function getCacheKey(params, ctx) {
5081 return params.language ? null : JSON.stringify([params.pack, params.module, params.moduleId, params.moduleName, ctx !== NULL, escapeEOLs(params.eol), params.tolerateWhitespaces, params.renderAs, params.renderMode, params.prettyPrint, params.ignore, params.localization, params.i18nFn, params.i18nFnOptions, params.literalBounds, params.attrLiteralBounds, params.tagFilter, params.tagNameFilter, params.attrKeyFilter, params.attrValueFilter, params.bemFilter, params.filters, params.useStrict]);
5082}
5083
5084/**
5085 * Saves compiled template functions in the SS cache by the specified key
5086 *
5087 * @param {?string} key - cache key
5088 * @param {string} code - source SS code
5089 * @param {!Object} params - compile parameters
5090 * @param {!Object} ctx - context
5091 */
5092function saveIntoFnCache(key, code, params, ctx) {
5093 if (ctx === NULL) {
5094 return;
5095 }
5096
5097 if (!key || !(params.cache || $globalCache[key])) {
5098 return;
5099 }
5100
5101 $globalFnCache[key] = Object.assign($globalFnCache[key] || {}, defineProperty({}, code, ctx));
5102}
5103
5104/**
5105 * Saves templates in the SS cache by the specified key
5106 *
5107 * @param {?string} key - cache key
5108 * @param {string} code - source SS code
5109 * @param {!Object} params - compile parameters
5110 * @param {!Parser} parser - instance of a Parser class
5111 */
5112function saveIntoCache(key, code, params, parser) {
5113 if (!key || !(params.cache || $globalCache[key])) {
5114 return;
5115 }
5116
5117 $globalCache[key] = Object.assign($globalCache[key] || {}, defineProperty({}, code, {
5118 debug: params.debug,
5119 text: parser.result,
5120 words: params.words
5121 }));
5122}
5123
5124/**
5125 * Returns RegExp by the specified text
5126 *
5127 * @param {string} source - source RegExp text
5128 * @param {?string=} [opt_flags] - RegExp flags
5129 * @return {!RegExp}
5130 */
5131function getRgxp(source, opt_flags) {
5132 opt_flags = opt_flags || '';
5133 $rgxp[opt_flags] = $rgxp[opt_flags] || {};
5134 return $rgxp[opt_flags][source] = $rgxp[opt_flags][source] || new RegExp(source, opt_flags);
5135}
5136
5137var propRgxp = new RegExp('[' + w + ']');
5138
5139/**
5140 * Returns true if a part of a string from
5141 * the specified position is a property of an object literal
5142 *
5143 * @param {string} str - source string
5144 * @param {number} start - start search position
5145 * @param {number} end - end search position
5146 * @return {boolean}
5147 */
5148function isSyOL(str, start, end) {
5149 var res = void 0;
5150
5151 while (start--) {
5152 var el = str[start];
5153
5154 if (!eol.test(el)) {
5155 res = el === '?';
5156 break;
5157 }
5158
5159 if (!eol.test(el) && (!propRgxp.test(el) || el === '?')) {
5160 if (el === '{' || el === ',') {
5161 break;
5162 }
5163
5164 res = true;
5165 break;
5166 }
5167 }
5168
5169 if (!res) {
5170 for (var i = end; i < str.length; i++) {
5171 var _el = str[i];
5172
5173 if (!eol.test(_el)) {
5174 return _el === ':';
5175 }
5176 }
5177 }
5178
5179 return false;
5180}
5181
5182/**
5183 * Returns true if the next non-whitespace character in a string
5184 * from the specified position is "=" (assignment)
5185 *
5186 * @param {string} str - source string
5187 * @param {number} pos - start search position
5188 * @return {boolean}
5189 */
5190function isNextAssign(str, pos) {
5191 for (var i = pos; i < str.length; i++) {
5192 var el = str[i];
5193
5194 if (!eol.test(el)) {
5195 return el === '=' && str[i + 1] !== '=';
5196 }
5197 }
5198
5199 return false;
5200}
5201
5202/**
5203 * Returns an information object for a string expression
5204 * if the string contains assignment of a variable (or a property)
5205 * OR returns false
5206 *
5207 * @param {string} str - source string
5208 * @param {?boolean=} opt_global - if true, then will be checked string as a super-global variable
5209 * @return {({key: string, value: string}|boolean)}
5210 */
5211function isAssignExpression(str, opt_global) {
5212 var rgxp = getRgxp('^[' + r(G_MOD) + '$' + symbols + '_' + (opt_global ? '[' : '') + ']', 'i');
5213
5214 if (!rgxp.test(str)) {
5215 return false;
5216 }
5217
5218 var prop = '',
5219 count = 0,
5220 eq = false;
5221
5222 var advEqMap = {
5223 '&': true,
5224 '*': true,
5225 '+': true,
5226 '-': true,
5227 '/': true,
5228 '^': true,
5229 '|': true,
5230 '~': true
5231 };
5232
5233 var bAdvMap = {
5234 '<': true,
5235 '>': true
5236 };
5237
5238 for (var i = 0; i < str.length; i++) {
5239 var el = str[i];
5240 prop += el;
5241
5242 if (B_OPEN[el]) {
5243 count++;
5244 continue;
5245 } else if (B_CLOSE[el]) {
5246 count--;
5247 continue;
5248 }
5249
5250 var prev = str[i - 1],
5251 next = str[i + 1];
5252
5253 if (!eq && !count && (el === '=' && next !== '=' && prev !== '=' && !advEqMap[prev] && !bAdvMap[prev] || advEqMap[el] && next === '=' || bAdvMap[el] && bAdvMap[next] && str[i + 2] === '=')) {
5254
5255 var diff = 1;
5256
5257 if (advEqMap[el]) {
5258 diff = 2;
5259 } else if (bAdvMap[el]) {
5260 diff = 3;
5261 }
5262
5263 return {
5264 key: prop.slice(0, -1),
5265 value: str.slice(i + diff)
5266 };
5267 }
5268
5269 eq = el === '=';
5270 }
5271
5272 return false;
5273}
5274
5275/* eslint-disable prefer-template */
5276
5277var blackWords = {
5278 '+': true,
5279 '++': true,
5280 '-': true,
5281 '--': true,
5282 '~': true,
5283 '~~': true,
5284 '!': true,
5285 '!!': true,
5286 'break': true,
5287 'case': true,
5288 'catch': true,
5289 'continue': true,
5290 'delete': true,
5291 'do': true,
5292 'else': true,
5293 'false': true,
5294 'finally': true,
5295 'for': true,
5296 'function': true,
5297 'if': true,
5298 'in': true,
5299 'of': true,
5300 'instanceof': true,
5301 'new': true,
5302 'null': true,
5303 'return': true,
5304 'switch': true,
5305 'this': true,
5306 'throw': true,
5307 'true': true,
5308 'try': true,
5309 'typeof': true,
5310 'var': true,
5311 'const': true,
5312 'let': true,
5313 'void': true,
5314 'while': true,
5315 'with': true,
5316 'class': true,
5317 'interface': true
5318};
5319
5320var unDefUnaryBlackWords = {
5321 'new': true
5322};
5323
5324var declBlackWords = {
5325 'const': true,
5326 'let': true,
5327 'var': true
5328};
5329
5330var ssfRgxp = /__FILTERS__\./;
5331var nextCharRgxp = new RegExp('[' + r(G_MOD) + '+\\-~!' + w + ']');
5332var newWordRgxp = new RegExp('[^' + r(G_MOD) + w + '[\\]]');
5333
5334var localContRgxp = new RegExp(r(G_MOD) + '{1}');
5335var globalContRgxp = new RegExp(r(G_MOD) + '{2}');
5336var prfxContRgxp = new RegExp('(.*?)' + r(G_MOD) + '+(.*)');
5337
5338var multPropRgxp = /\[|\./;
5339var firstPropRgxp = /([^.[]+)(.*)/;
5340var propValRgxp = /[^-+!(]+/;
5341
5342var dangerRgxp = /\)\s*(?:{|=>)/;
5343var functionRgxp = /\bfunction\b/;
5344var defFilterRgxp = /#;/g;
5345
5346var esprimaHackFn = function esprimaHackFn(str) {
5347 return String(str).trim().replace(/^({.*)/, '($0)').replace(/^\[(?!\s*])/, '$[').replace(/\b(?:yield|await|return)\b/g, '');
5348};
5349
5350/**
5351 * Prepares the specified command to output:
5352 * binds to the scope and initialization filters
5353 *
5354 * @param {string} command - source command
5355 * @param {?$$SnakeskinParserOutParams=} [opt_params] - additional parameters:
5356 *
5357 * *) [cache=true] - if is false, then filter results won't be cached in variable
5358 * *) [unsafe=false] - if is true, then default filters won't be applied to the resulting string
5359 * *) [skipFirstWord=false] - if is true, then the first word in the string will be skipped
5360 * *) [skipValidation=true] - if is false, then the resulting string won't be validated
5361 *
5362 * @return {string}
5363 */
5364Parser.prototype.out = function (command, opt_params) {
5365 var _this = this;
5366
5367 command = this.replaceDangerBlocks(command);
5368
5369 var _any = any(Object.assign({ cache: true }, opt_params)),
5370 cache = _any.cache,
5371 unsafe = _any.unsafe,
5372 skipFirstWord = _any.skipFirstWord,
5373 skipValidation = _any.skipValidation;
5374
5375 var structure = this.structure,
5376 tplName = String(this.tplName);
5377
5378
5379 if (dangerRgxp.test(command)) {
5380 this.error('unsupported syntax');
5381 return '';
5382 }
5383
5384 // DEFINITIONS:
5385 // Parenthesis = (
5386
5387 var res = command;
5388
5389 var
5390 // The number of open parentheses in the string
5391 // (open parenthesis inside the filter aren't considered)
5392 pCount = 0,
5393
5394
5395 // The number of open parentheses inside a filter:
5396 // |foo (1 + 2) / 3
5397 pCountFilter = 0;
5398
5399 var
5400 // The array of positions for opening and closing parenthesis (pCount),
5401 // goes in ascending order of nested blocks, such as:
5402 // ((a + b)) => [[1, 7], [0, 8]]
5403 pContent = [];
5404
5405 var
5406 // true, if there is filter declaration
5407 filterStart$$1 = false,
5408
5409
5410 // true, if there is a filter-wrapper, ie
5411 // (2 / 3)|round
5412 filterWrapper = false;
5413
5414 // Arrays of final filters and real filters,
5415 // for example:
5416 // {with foo}
5417 // {bar |ucfirst bar()|json}
5418 // {end}
5419 //
5420 // rvFilter => ['ucfirst bar()', 'json']
5421 // filter => ['ucfirst foo.bar()', 'json']
5422 var filters = [],
5423 rFilters = [];
5424
5425 var defFilters = this.filters[this.filters.length - 1],
5426 cancelFilters = {};
5427
5428 var
5429 // true, if it is possible to calculate a word
5430 nWord = !skipFirstWord,
5431
5432
5433 // The number of words to skip
5434 posNWord = 0;
5435
5436 var vars = structure.children ? structure.vars : structure.parent.vars;
5437
5438 var add = 0,
5439 wordAddEnd = 0,
5440 filterAddEnd = 0;
5441
5442 var ref = this.hasBlock('block', true),
5443 type = void 0;
5444
5445 if (ref) {
5446 ref = ref.params.name;
5447 type = 'block';
5448 }
5449
5450 if (ref && !$scope[type][tplName]) {
5451 ref = false;
5452 }
5453
5454 /**
5455 * @param {!Object} obj
5456 * @param {string} val
5457 * @return {(string|boolean)}
5458 */
5459 var search = function search(obj, val) {
5460 if (!obj) {
5461 return false;
5462 }
5463
5464 return vars[val + '_' + obj.id] || search(obj.parent, val) || false;
5465 };
5466
5467 /**
5468 * @param {string} str
5469 * @return {string}
5470 */
5471 var replacePropVal = function replacePropVal(str) {
5472 var def = vars[str];
5473
5474 var refCache = ref && $scope[type][tplName][ref],
5475 tplCache = $scope['template'][tplName];
5476
5477 if (!def && tplName && ($consts[tplName] && $consts[tplName][str] || tplCache && tplCache.parent && $consts[tplCache.parent.name] && $consts[tplCache.parent.name][str])) {
5478 return str;
5479 }
5480
5481 if (!def && refCache) {
5482 def = vars[str + '_' + refCache.id];
5483 }
5484
5485 if (!def) {
5486 def = vars[str + '_' + _this.environment.id];
5487 }
5488
5489 if (!def && tplName) {
5490 if (refCache && refCache.parent) {
5491 def = search(refCache.parent, str);
5492 }
5493
5494 if (!def && tplCache && tplCache.parent) {
5495 def = search(tplCache.parent, str);
5496 }
5497 }
5498
5499 if (def) {
5500 return def.value;
5501 }
5502
5503 return str;
5504 };
5505
5506 /**
5507 * @param {string} str
5508 * @return {string}
5509 */
5510 var addScope = function addScope(str) {
5511 if (!multPropRgxp.test(str[0]) && multPropRgxp.test(str)) {
5512 var firstProp = firstPropRgxp.exec(str);
5513
5514 firstProp[1] = firstProp[1].replace(propValRgxp, replacePropVal);
5515
5516 return firstProp.slice(1).join('');
5517 }
5518
5519 return str.replace(propValRgxp, replacePropVal);
5520 };
5521
5522 /**
5523 * @param {!Array} params
5524 * @return {string}
5525 */
5526 var joinFilterParams = function joinFilterParams(params) {
5527 var arr = [];
5528
5529 for (var i = 0; i < params.length; i++) {
5530 var el = params[i];
5531 arr[i] = isFunction(el) ? String(el(_this)) : el;
5532 }
5533
5534 return arr.join();
5535 };
5536
5537 /**
5538 * @param {string} str
5539 * @param {!Object} map
5540 * @return {string}
5541 */
5542 var removeDefFilters = function removeDefFilters(str, map) {
5543 var arr = Object.keys(map);
5544
5545 for (var i = 0; i < arr.length; i++) {
5546 str = str.replace(getRgxp('\\|' + arr[i] + ' .*?(?=#;)', 'g'), '');
5547 }
5548
5549 return str;
5550 };
5551
5552 /**
5553 * @param {string} str
5554 * @param {!Array<!Object>} filters
5555 * @return {string}
5556 */
5557 var addDefFilters = function addDefFilters(str, filters) {
5558 var isLocalFilter = filters === defFilters.local,
5559 prfx = [isLocalFilter ? '(' : '', isLocalFilter ? ')' : ''];
5560
5561 for (var i = 0; i < filters.length; i++) {
5562 var filter = filters[i],
5563 arr = Object.keys(filter);
5564
5565 for (var _i = 0; _i < arr.length; _i++) {
5566 str = '' + prfx[0] + str + '|' + arr[_i] + ' ' + joinFilterParams(filter[arr[_i]]) + '#;' + prfx[1];
5567 }
5568 }
5569
5570 return str;
5571 };
5572
5573 if (!command) {
5574 this.error('invalid syntax');
5575 return '';
5576 }
5577
5578 var cacheLink = replacePropVal('$_');
5579
5580 var isFilter = void 0,
5581 breakNum = void 0,
5582 escape = false;
5583
5584 for (var i = 0; i < command.length; i++) {
5585 var el = command[i],
5586 next = command[i + 1],
5587 next2 = command[i + 2];
5588
5589 var end = command.length - 1,
5590 cEscape = escape,
5591 uAdd = wordAddEnd + add;
5592
5593 if (el === '\\' || escape) {
5594 escape = !escape;
5595 }
5596
5597 if (escape) {
5598 if (unsafe) {
5599 command = command.slice(0, i) + command.slice(i + 1);
5600 res = res.slice(0, i + uAdd) + res.slice(i + uAdd + 1);
5601 }
5602
5603 continue;
5604 }
5605
5606 if (!breakNum) {
5607 if (el === '(') {
5608 if (filterStart$$1) {
5609 pCountFilter++;
5610 } else {
5611 pContent.unshift([i + wordAddEnd]);
5612 pCount++;
5613 }
5614 } else if (el === '.') {
5615 posNWord = 2;
5616 }
5617
5618 // nWord indicates that started a new word;
5619 // posNWord indicates how many new words to skip
5620 if (nWord && !posNWord && nextCharRgxp.test(el)) {
5621 /* eslint-disable prefer-const */
5622
5623 var _getWordFromPos = this.getWordFromPos(command, i),
5624 word = _getWordFromPos.word,
5625 finalWord = _getWordFromPos.finalWord,
5626 unary = _getWordFromPos.unary,
5627 tmpFinalWord = void 0;
5628
5629 /* eslint-enable prefer-const */
5630
5631 if (unary) {
5632 tmpFinalWord = finalWord.split(' ');
5633 finalWord = tmpFinalWord.slice(1).join(' ');
5634 }
5635
5636 // If true, then a word is:
5637 // not from blacklist,
5638 // not a filter,
5639 // not a number,
5640 // not a Escaper literal,
5641 // not a property ({property: )
5642 var canParse = !blackWords[word] && !pCountFilter && !ssfRgxp.test(word) && !isFilter && isNaN(Number(word)) && !escaperPart.test(word) && !isSyOL(command, i, i + word.length);
5643
5644 if (canParse && functionRgxp.test(word)) {
5645 this.error('unsupported syntax');
5646 return '';
5647 }
5648
5649 var vRes = void 0;
5650 if (canParse) {
5651 if (localContRgxp.test(finalWord)) {
5652 var chunks = prfxContRgxp.exec(finalWord);
5653
5654 if (globalContRgxp.test(finalWord)) {
5655 vRes = chunks[1] + '__VARS__' + concatProp(chunks[2]);
5656 } else if (this.scope.length) {
5657 vRes = chunks[1] + addScope(this.scope[this.scope.length - 1]) + concatProp(chunks[2]);
5658 } else {
5659 if (this.isSimpleOutput()) {
5660 this.error('invalid usage of context modifier @');
5661 return '';
5662 }
5663
5664 vRes = chunks[1] + chunks[2];
5665 }
5666 } else {
5667 vRes = addScope(finalWord);
5668 }
5669 } else if (finalWord === 'this' && tplName && !this.selfThis[this.selfThis.length - 1]) {
5670 vRes = '__THIS__';
5671 } else {
5672 vRes = finalWord;
5673 }
5674
5675 if (canParse && tplName && $consts[tplName] && $consts[tplName][vRes] && isNextAssign(command, i + word.length)) {
5676
5677 this.error('constant "' + vRes + '" is already defined');
5678 return '';
5679 }
5680
5681 if (unary) {
5682 vRes = tmpFinalWord[0] + ' ' + vRes;
5683 }
5684
5685 if (declBlackWords[finalWord]) {
5686 posNWord = 2;
5687 } else if (canParse && !unsafe && !filterStart$$1 && (!unary || unDefUnaryBlackWords[unary])) {
5688 vRes = addDefFilters(vRes, defFilters.local);
5689 }
5690
5691 wordAddEnd += vRes.length - word.length;
5692 nWord = false;
5693
5694 if (filterStart$$1) {
5695 var l = filters.length - 1;
5696 filters[l] += vRes;
5697 rFilters[l] += word;
5698 filterAddEnd += vRes.length - word.length;
5699 } else {
5700 res = res.slice(0, i + uAdd) + vRes + res.slice(i + word.length + uAdd);
5701 }
5702
5703 i += word.length - 2;
5704 breakNum = 1;
5705 continue;
5706
5707 // Maybe soon will start a new word
5708 } else if (newWordRgxp.test(el)) {
5709 nWord = true;
5710 posNWord && posNWord--;
5711 }
5712
5713 if (!filterStart$$1) {
5714 if (el === ')') {
5715 // Closing parenthesis, and the next two characters aren't filter
5716 if (next !== FILTER || !filterStart.test(next2)) {
5717 pCount && pCount--;
5718 pContent.shift();
5719 continue;
5720 } else {
5721 filterWrapper = true;
5722 }
5723 }
5724
5725 // Filter body
5726 } else if (el !== ')' || pCountFilter) {
5727 var _l = filters.length - 1;
5728 filters[_l] += el;
5729 rFilters[_l] += el;
5730 }
5731 }
5732
5733 if (i === end && pCount && !filterWrapper && el !== ')') {
5734 this.error('missing closing or opening parenthesis in the template');
5735 return '';
5736 }
5737
5738 // Closing of a filter
5739 if (filterStart$$1 && !pCountFilter && (el === ')' && !breakNum || i === end)) {
5740 var pos = pContent[0],
5741 cancelLocalFilters = {};
5742
5743
5744 var fAdd = wordAddEnd - filterAddEnd + add,
5745 fBody = res.slice(pos[0] + (pCount ? add : 0), pos[1] + fAdd);
5746
5747 var isGlobalFilter = i === end && el !== ')';
5748
5749 for (var _i2 = 0; _i2 < filters.length; _i2++) {
5750 var _el = filters[_i2];
5751
5752 if (_el[0] !== '!') {
5753 continue;
5754 }
5755
5756 filters.splice(_i2, 1);
5757 _i2--;
5758
5759 var filter = _el.slice(1);
5760
5761 if (isGlobalFilter) {
5762 cancelFilters[filter] = true;
5763 } else {
5764 cancelLocalFilters[filter] = true;
5765 }
5766 }
5767
5768 var tmp = fBody.trim() || 'undefined';
5769 for (var _i3 = 0; _i3 < filters.length; _i3++) {
5770 var params = filters[_i3].split(' '),
5771 input = params.slice(1).join(' ').trim(),
5772 current = params.shift().split('.');
5773
5774 var bind = [],
5775 test = void 0;
5776
5777 var Filters = Snakeskin$1.Filters,
5778 _pos = 0;
5779
5780
5781 while (Filters) {
5782 Filters = Filters[current[_pos]];
5783 _pos++;
5784
5785 if (_pos === current.length) {
5786 break;
5787 }
5788 }
5789
5790 if (Filters && Filters['ssFilterParams']) {
5791 var p = Filters['ssFilterParams'],
5792 arr = Object.keys(p);
5793
5794 for (var _i4 = 0; _i4 < arr.length; _i4++) {
5795 var key = arr[_i4],
5796 _el2 = p[key];
5797
5798 switch (key) {
5799 case 'bind':
5800 bind = bind.concat(_el2);
5801 break;
5802
5803 case 'test':
5804 test = _el2;
5805 break;
5806
5807 default:
5808 if (key[0] === '!') {
5809 var _filter2 = key.slice(1);
5810
5811 if (isGlobalFilter) {
5812 cancelFilters[_filter2] = true;
5813 } else {
5814 cancelLocalFilters[_filter2] = true;
5815 }
5816 }
5817 }
5818 }
5819 }
5820
5821 if (test && !test(tmp)) {
5822 continue;
5823 }
5824
5825 var _filter = '';
5826 for (var _i5 = 0; _i5 < current.length; _i5++) {
5827 _filter += '[\'' + current[_i5] + '\']';
5828 }
5829
5830 tmp = (cache ? '(' + cacheLink + ' = ' : '') + '__FILTERS__' + _filter + (filterWrapper || !pCount ? '.call(this,' : '') + tmp + (bind.length ? ',' + joinFilterParams(bind) : '') + (input ? ',' + input : '') + (filterWrapper || !pCount ? ')' : '') + (cache ? ')' : '');
5831 }
5832
5833 if (!isGlobalFilter) {
5834 tmp = removeDefFilters(tmp, cancelLocalFilters);
5835 }
5836
5837 var fStr = rFilters.join().length + 1;
5838 res = pCount ? res.slice(0, pos[0] + add) + tmp + res.slice(pos[1] + fAdd + fStr) : tmp;
5839
5840 pContent.shift();
5841 filters = [];
5842 filterStart$$1 = false;
5843 rFilters = [];
5844
5845 if (pCount) {
5846 pCount--;
5847 filterWrapper = false;
5848 }
5849
5850 wordAddEnd += tmp.length - fBody.length - fStr;
5851
5852 if (!pCount) {
5853 add += wordAddEnd - filterAddEnd;
5854 wordAddEnd = 0;
5855 filterAddEnd = 0;
5856 }
5857 }
5858
5859 // Closing parenthesis inside a filter
5860 if (el === ')' && pCountFilter && !breakNum) {
5861 pCountFilter--;
5862
5863 if (!pCountFilter) {
5864 var _l2 = filters.length - 1,
5865 _cache = filters[_l2];
5866
5867 filters[_l2] = this.out(_cache, { skipFirstWord: true, skipValidation: true, unsafe: true });
5868 var length = filters[_l2].length - _cache.length;
5869
5870 wordAddEnd += length;
5871 filterAddEnd += length;
5872
5873 if (i === end) {
5874 i--;
5875 breakNum = 1;
5876 }
5877 }
5878 }
5879
5880 isFilter = !cEscape && el === FILTER;
5881 breakNum && breakNum--;
5882
5883 // After 2 iteration begins a filter
5884 if (next === FILTER && filterStart.test(next2)) {
5885 nWord = false;
5886
5887 if (!filterStart$$1) {
5888 if (pCount) {
5889 pContent[0].push(i + 1);
5890 } else {
5891 pContent.push([0, i + 1]);
5892 }
5893 }
5894
5895 filterStart$$1 = true;
5896 if (!pCountFilter) {
5897 filters.push(next2);
5898 rFilters.push(next2);
5899 i += 2;
5900 if (i === end) {
5901 command += ' ';
5902 }
5903 }
5904 } else if (i === 0 && isFilter && filterStart.test(next)) {
5905 nWord = false;
5906
5907 if (!filterStart$$1) {
5908 pContent.push([0, i]);
5909 }
5910
5911 filterStart$$1 = true;
5912 if (!pCountFilter) {
5913 filters.push(next);
5914 rFilters.push(next);
5915 i++;
5916 }
5917 }
5918 }
5919
5920 if (!unsafe) {
5921 res = this.out(removeDefFilters(addDefFilters('(' + res + ')', defFilters.global), cancelFilters).replace(defFilterRgxp, ''), { cache: false, unsafe: true, skipFirstWord: skipFirstWord, skipValidation: skipValidation });
5922
5923 if (isNotPrimitive(res)) {
5924 res = '__FILTERS__[\'htmlObject\'](' + res + ')';
5925 }
5926 }
5927
5928 if (skipValidation !== false) {
5929 var esprimaRes = parse(res);
5930
5931 if (esprimaRes !== true) {
5932 this.error(String(esprimaRes));
5933 return '';
5934 }
5935 }
5936
5937 return res;
5938};
5939
5940/**
5941 * @param {string} str
5942 * @return {(boolean|string)}
5943 */
5944function parse(str) {
5945 try {
5946 babylon.parse(esprimaHackFn(str), { plugins: ['flow', 'asyncFunctions', 'objectRestSpread', 'exponentiationOperator', 'asyncGenerators', 'functionBind', 'functionSent'] });
5947 } catch (err) {
5948 return err.message.replace(/.*?: (\w)/, function (str, $1) {
5949 return $1.toLowerCase();
5950 });
5951 }
5952
5953 return true;
5954}
5955
5956/**
5957 * Appends a function to the SS queue
5958 *
5959 * @param {function(this:Parser)} fn - source function
5960 * @return {!Parser}
5961 */
5962Parser.prototype.toQueue = function (fn) {
5963 this.structure.stack.push(fn);
5964 return this;
5965};
5966
5967/**
5968 * Executes all functions in the SS queue
5969 * @return {!Parser}
5970 */
5971Parser.prototype.applyQueue = function () {
5972 var stack = this.structure.stack;
5973
5974
5975 for (var i = 0; i < stack.length; i++) {
5976 stack[i].call(this);
5977 stack.shift();
5978 }
5979
5980 return this;
5981};
5982
5983/**
5984 * Returns a string for the beginning of concatenation with __RESULT__
5985 * @return {string}
5986 */
5987Parser.prototype.$ = function () {
5988 if (this.stringResult) {
5989 return '__STRING_RESULT__ += ';
5990 }
5991
5992 switch (this.renderMode) {
5993 case 'stringConcat':
5994 return '__RESULT__ += ';
5995
5996 case 'stringBuffer':
5997 return '__RESULT__.push(';
5998
5999 default:
6000 return 'Snakeskin.appendChild(__RESULT__[__RESULT__.length - 1], ';
6001 }
6002};
6003
6004/**
6005 * Returns a string for the ending of concatenation with __RESULT__
6006 * @return {string}
6007 */
6008Parser.prototype.$$ = function () {
6009 if (this.stringResult) {
6010 return '';
6011 }
6012
6013 switch (this.renderMode) {
6014 case 'stringConcat':
6015 return '';
6016
6017 case 'stringBuffer':
6018 return ')';
6019
6020 default:
6021 return ', \'' + this.renderMode + '\')';
6022 }
6023};
6024
6025/**
6026 * Appends a string to __RESULT__
6027 *
6028 * @param {?string=} [opt_str] - source string
6029 * @return {string}
6030 */
6031Parser.prototype.wrap = function (opt_str) {
6032 return '' + this.$() + (opt_str || '') + this.$$() + ';';
6033};
6034
6035/**
6036 * Returns a string of template declaration
6037 * @return {string}
6038 */
6039Parser.prototype.getResultDecl = function () {
6040 switch (this.renderMode) {
6041 case 'stringConcat':
6042 return '\'\'';
6043
6044 case 'stringBuffer':
6045 return 'new Snakeskin.StringBuffer()';
6046
6047 default:
6048 return '[new Snakeskin.DocumentFragment(\'' + this.renderMode + '\')]';
6049 }
6050};
6051
6052/**
6053 * Returns a string of template content
6054 * @return {string}
6055 */
6056Parser.prototype.getReturnResultDecl = function () {
6057 var r$$1 = '__RESULT__ instanceof Raw ? __RESULT__.value : ';
6058
6059 switch (this.renderMode) {
6060 case 'stringConcat':
6061 return r$$1 + '__RESULT__';
6062
6063 case 'stringBuffer':
6064 return r$$1 + '__JOIN__(__RESULT__)';
6065
6066 default:
6067 return r$$1 + '__RESULT__[0]';
6068 }
6069};
6070
6071/**
6072 * Replaces CDATA blocks in a string
6073 *
6074 * @param {string} str - source string
6075 * @return {string}
6076 */
6077Parser.prototype.replaceCData = function (str) {
6078 var _this = this;
6079
6080 var s = ADV_LEFT_BOUND + LEFT_BOUND,
6081 e = RIGHT_BOUND;
6082
6083 return str.replace(new RegExp(r(s) + 'cdata' + r(e) + '([\\s\\S]*?)' + r(s) + '(?:\\/cdata|end cdata)' + r(e), 'g'), function (str, data) {
6084 _this.cdataContent.push(data);
6085 return String(
6086 // The number of added lines
6087 s + '__appendLine__ ' + (data.match(new RegExp(eol.source, 'g')) || '').length + e + (
6088
6089 // Label to replace CDATA
6090 '__CDATA__' + (_this.cdataContent.length - 1) + '_'));
6091 });
6092};
6093
6094/**
6095 * Declares the end of Snakeskin declaration
6096 *
6097 * @param {?string} cacheKey - cache key
6098 * @param {(Date|string)} label - declaration label
6099 * @return {!Parser}
6100 */
6101Parser.prototype.end = function (cacheKey, label) {
6102 var _this2 = this;
6103
6104 label = label || '';
6105
6106 // Replace some trash :)
6107 switch (this.renderMode) {
6108 case 'stringConcat':
6109 this.result = this.result.replace(/\b__RESULT__ \+= '';/g, '');
6110 break;
6111
6112 case 'stringBuffer':
6113 this.result = this.result.replace(/\b__RESULT__\.push\(''\);/g, '');
6114 break;
6115
6116 default:
6117 this.result = this.result.replace(new RegExp('\\bSnakeskin\\.appendChild\\(__RESULT__\\[__RESULT__\\.length - 1], \'\', \'' + this.renderMode + '\'\\);', 'g'), '');
6118
6119 break;
6120 }
6121
6122 if ({ 'amd': true, 'umd': true }[this.module] && this.amdModules.length) {
6123 this.result = this.result.replace(/\/\*#__SNAKESKIN_MODULES_DECL__\*\//, ',' + JSON.stringify(this.amdModules).slice(1, -1)).replace(/\/\*#__SNAKESKIN_MODULES__\*\//, ',' + this.amdModules.join());
6124 }
6125
6126 if (this.cdataContent.length) {
6127 this.result = this.result.replace(/__CDATA__(\d+)_\b/g, function (str, pos) {
6128 return escapeEOLs((_this2.cdataContent[pos] || '').replace(backSlashes, '\\\\').replace(new RegExp(eol.source, 'g'), _this2.eol)).replace(singleQuotes, '\\\'');
6129 });
6130 }
6131
6132 var versionDecl = 'Snakeskin v' + Snakeskin$1.VERSION.join('.'),
6133 keyDecl = 'key <' + cacheKey + '>',
6134 labelDecl = 'label <' + label.valueOf() + '>',
6135 includesDecl = 'includes <' + (this.environment.key.length ? JSON.stringify(this.environment.key) : '') + '>',
6136 generatedAtDecl = 'generated at <' + new Date().valueOf() + '>',
6137 resDecl = this.eol + ' ' + this.result;
6138
6139 this.result = '/* ' + versionDecl + ', ' + keyDecl + ', ' + labelDecl + ', ' + includesDecl + ', ' + generatedAtDecl + '.' + resDecl;
6140
6141 if (this.module !== 'native') {
6142 this.result += '});';
6143 }
6144
6145 return this;
6146};
6147
6148/**
6149 * Returns true if is possible to write in the JS string
6150 * @return {boolean}
6151 */
6152Parser.prototype.isSimpleOutput = function () {
6153 return !this.parentTplName && !this.outerLink;
6154};
6155
6156/**
6157 * Returns true if !outerLink && (parentTplName && !hasParentBlock || !parentTplName)
6158 * @return {boolean}
6159 */
6160Parser.prototype.isAdvTest = function () {
6161 return Boolean(!this.outerLink && (this.parentTplName && !this.hasParentBlock(this.getGroup('block')) || !this.parentTplName));
6162};
6163
6164/**
6165 * Adds a string to the result JS string if is possible
6166 *
6167 * @param {string=} str - source string
6168 * @param {?$$SnakeskinParserSaveParams=} [opt_params] - addition parameters:
6169 *
6170 * *) [iface=false] - if is true, then the current operation is an interface
6171 * *) [raw=false] - if is true, then the appending text is considered as raw
6172 * *) [jsDoc] - last position of appending jsDoc or false
6173 *
6174 * @return {(boolean|string)}
6175 */
6176Parser.prototype.save = function (str, opt_params) {
6177 var _any = any(opt_params || {}),
6178 iface = _any.iface,
6179 jsDoc = _any.jsDoc,
6180 raw = _any.raw;
6181
6182 if (str === undefined) {
6183 return false;
6184 }
6185
6186 if (!this.tplName || $write[this.tplName] !== false || iface) {
6187 if (!raw) {
6188 str = this.pasteDangerBlocks(str);
6189 }
6190
6191 if (jsDoc) {
6192 var pos = Number(jsDoc);
6193 this.result = this.result.slice(0, pos) + str + this.result.slice(pos);
6194 } else {
6195 this.result += str;
6196 }
6197
6198 return str;
6199 }
6200
6201 return false;
6202};
6203
6204/**
6205 * Adds a string to the result JS string if is possible
6206 * (with this.isSimpleOutput())
6207 *
6208 * @param {string=} str - source string
6209 * @param {?$$SnakeskinParserSaveParams=} [opt_params] - addition parameters:
6210 *
6211 * *) [iface=false] - if is true, then the current operation is an interface
6212 * *) [raw=false] - if is true, then the appending text is considered as raw
6213 * *) [jsDoc] - last position of appending jsDoc or false
6214 *
6215 * @return {(boolean|string)}
6216 */
6217Parser.prototype.append = function (str, opt_params) {
6218 if (!this.isSimpleOutput()) {
6219 return false;
6220 }
6221
6222 return this.save(str, opt_params);
6223};
6224
6225/**
6226 * Returns an object of the closest non logic parent directive
6227 *
6228 * @private
6229 * @param {$$SnakeskinParserStructure} structure - structure object
6230 * @return {$$SnakeskinParserStructure}
6231 */
6232Parser.prototype._getNonLogicParent = function (structure) {
6233 while (true) {
6234 if ($logicDirs[structure.name] && (structure.name !== 'block' || !structure.params.isCallable)) {
6235 structure = structure.parent;
6236 continue;
6237 }
6238
6239 return structure;
6240 }
6241};
6242
6243/**
6244 * Returns an object of the closest non logic parent directive
6245 * @return {?$$SnakeskinParserStructure}
6246 */
6247Parser.prototype.getNonLogicParent = function () {
6248 return this.structure.parent ? this._getNonLogicParent(any(this.structure.parent)) : null;
6249};
6250
6251/**
6252 * Returns true if the current directive is logic
6253 * @return {boolean}
6254 */
6255Parser.prototype.isLogic = function () {
6256 var structure = this.structure;
6257
6258 return $logicDirs[structure.name] && (structure.name !== 'block' || !structure.params.isCallable);
6259};
6260
6261/**
6262 * Checks availability of a directive in a chain structure
6263 *
6264 * @private
6265 * @param {(string|!Object<string, boolean>|!Array<string>)} name - directive name, a map of names or an array of names
6266 * @param {$$SnakeskinParserStructure} structure - structure object
6267 * @param {?boolean=} opt_return - if is true, then returns a reference to the found object (if it exists)
6268 * @return {(boolean|string|!Object)}
6269 */
6270Parser.prototype._has = function (name, structure, opt_return) {
6271 if (isArray(name)) {
6272 var map = {};
6273
6274 for (var i = 0; i < name.length; i++) {
6275 var el = name[i];
6276
6277 if (isObject(el)) {
6278 Object.assign(map, el);
6279 } else {
6280 map[el] = true;
6281 }
6282 }
6283
6284 name = map;
6285 }
6286
6287 var nameIsStr = isString(name);
6288
6289 while (true) {
6290 var nm = structure.name;
6291
6292 if (nameIsStr) {
6293 if (nm === name) {
6294 return opt_return ? structure : true;
6295 }
6296 } else if (name[nm]) {
6297 return opt_return ? structure : nm;
6298 }
6299
6300 if (structure.parent && structure.parent.name !== 'root') {
6301 structure = structure.parent;
6302 } else {
6303 return false;
6304 }
6305 }
6306};
6307
6308/**
6309 * Checks availability of a directive in a chain structure,
6310 * including the active
6311 *
6312 * @param {(string|!Object<string, boolean>|!Array<string>)} name - directive name, a map of names or an array of names
6313 * @param {?boolean=} opt_return - if is true, then returns a reference to the found object (if it exists)
6314 * @return {(boolean|string|!Object)}
6315 */
6316Parser.prototype.has = function (name, opt_return) {
6317 return this._has(name, any(this.structure), opt_return);
6318};
6319
6320/**
6321 * Checks availability of a directive in the chain structure,
6322 * excluding the active
6323 *
6324 * @param {(string|!Object<string, boolean>|!Array<string>)} name - directive name, a map of names or an array of names
6325 * @param {?boolean=} opt_return - if is true, then returns a reference to the found object (if it exists)
6326 * @return {(boolean|string|!Object)}
6327 */
6328Parser.prototype.hasParent = function (name, opt_return) {
6329 if (this.structure.parent) {
6330 return this._has(name, any(this.structure.parent), opt_return);
6331 }
6332
6333 return false;
6334};
6335
6336/**
6337 * Checks availability of a directive in the block chain structure,
6338 * including the active
6339 *
6340 * @param {(string|!Object<string, boolean>|!Array<string>)} name - directive name, a map of names or an array of names
6341 * @param {?boolean=} opt_return - if is true, then returns a reference to the found object (if it exists)
6342 * @return {(boolean|string|!Object)}
6343 */
6344Parser.prototype.hasBlock = function (name, opt_return) {
6345 if (this.blockStructure) {
6346 return this._has(name, any(this.blockStructure), opt_return);
6347 }
6348
6349 return false;
6350};
6351
6352/**
6353 * Checks availability of a directive in the block chain structure,
6354 * excluding the active
6355 *
6356 * @param {(string|!Object<string, boolean>|!Array<string>)} name - directive name, a map of names or an array of names
6357 * @param {?boolean=} opt_return - if is true, then returns a reference to the found object (if it exists)
6358 * @return {(boolean|string|!Object)}
6359 */
6360Parser.prototype.hasParentBlock = function (name, opt_return) {
6361 if (this.blockStructure && this.blockStructure.parent) {
6362 return this._has(name, any(this.blockStructure.parent), opt_return);
6363 }
6364
6365 return false;
6366};
6367
6368/**
6369 * Returns an object of the closest parent micro-template directive or false
6370 * @return {($$SnakeskinParserStructure|boolean)}
6371 */
6372Parser.prototype.hasParentMicroTemplate = function () {
6373 var _this = this;
6374
6375 var groups = this.getGroup('microTemplate', 'func', 'async', 'block');
6376
6377 var test = function test(obj) {
6378 var parent = any(_this._has(groups, obj, true));
6379
6380 if (parent && (_this.getGroup('microTemplate')[parent.name] || parent.name === 'block' && !parent.params.isCallable && (parent = test(parent.parent)))) {
6381
6382 return parent;
6383 }
6384
6385 return false;
6386 };
6387
6388 return test(this.structure.parent);
6389};
6390
6391/**
6392 * Returns an object of the closest parent function directive or false
6393 * @return {({asyncParent: (boolean|string), block: boolean, target: $$SnakeskinParserStructure}|boolean)}
6394 */
6395Parser.prototype.hasParentFunction = function () {
6396 var _this2 = this;
6397
6398 var cb = this.getGroup('func'),
6399 groups = this.getGroup('async', 'function', 'block');
6400
6401 var test = function test(obj) {
6402 var closest = any(obj.parent && _this2._getNonLogicParent(obj.parent));
6403
6404 var target = any(_this2._has(groups, obj, true)),
6405 asyncParent = closest && _this2.getGroup('async')[closest.name] && cb[target.name] ? closest.name : false;
6406
6407 if (target) {
6408 if (target.name === 'block' && !target.params.isCallable) {
6409 var tmp = test(target.parent);
6410
6411 if (!tmp) {
6412 return false;
6413 }
6414
6415 asyncParent = tmp.asyncParent;
6416 target = tmp.target;
6417 }
6418
6419 if (target.name === 'block' || cb[target.name] && !asyncParent) {
6420 return {
6421 asyncParent: asyncParent,
6422 block: true,
6423 target: target
6424 };
6425 }
6426
6427 if (target) {
6428 return {
6429 asyncParent: asyncParent,
6430 block: false,
6431 target: target
6432 };
6433 }
6434 }
6435
6436 return false;
6437 };
6438
6439 return test(this.structure.parent);
6440};
6441
6442/**
6443 * Returns variable id by the specified name
6444 *
6445 * @param {string} name - variable name
6446 * @return {string}
6447 */
6448Parser.prototype.getVar = function (name) {
6449 var vars = this.structure.vars;
6450
6451 return vars && vars[name] ? vars[name].value : name;
6452};
6453
6454/**
6455 * Declares a variable and returns string declaration
6456 *
6457 * @param {string} name - variable name
6458 * @param {?$$SnakeskinParserDeclVarParams=} [opt_params] - addition parameters:
6459 *
6460 * *) [fn=false] - if is true, then the variable will be declared as a function parameter
6461 * *) [sys=false] - if is true, then the variable will be declared as system
6462 *
6463 * @return {string}
6464 */
6465Parser.prototype.declVar = function (name, opt_params) {
6466 name = name.trim();
6467
6468 var _any = any(opt_params || {}),
6469 fn = _any.fn,
6470 sys = _any.sys,
6471 tplName = this.tplName,
6472 id = this.environment.id;
6473
6474 var structure = this.structure;
6475
6476
6477 if (!fn && tplName && $consts[tplName] && $consts[tplName][name]) {
6478 this.error('the variable "' + name + '" is already defined as a constant');
6479 }
6480
6481 if (!sys && SYS_CONSTS[name] || escaperPart.test(name)) {
6482 return this.error('can\'t declare the variable "' + name + '", try another name');
6483 }
6484
6485 while (!structure.vars) {
6486 structure = structure.parent;
6487 }
6488
6489 var val = structure.vars[name];
6490
6491 if (val && !val.inherited && structure.parent) {
6492 return val.value;
6493 }
6494
6495 var link = void 0,
6496 global = false;
6497
6498 if (structure.name === 'root') {
6499 global = true;
6500 name += '_' + id;
6501 link = '__LOCAL__.' + name + '_' + id + '_' + Snakeskin$1.UID;
6502 } else {
6503 if (this.getGroup('head')[structure.name]) {
6504 structure = structure.parent;
6505 name += '_' + id;
6506 }
6507
6508 link = '__' + name + '_' + structure.name + '_' + this.i;
6509 }
6510
6511 structure.vars[name] = {
6512 global: global,
6513 id: id,
6514 scope: this.scope.length,
6515 value: link
6516 };
6517
6518 if (tplName && this.vars[tplName]) {
6519 this.vars[tplName][name] = true;
6520 }
6521
6522 return link;
6523};
6524
6525/**
6526 * Parses string declaration of variables, initializes it
6527 * and returns new string declaration
6528 *
6529 * @param {string} str - source string
6530 * @param {?$$SnakeskinParserDeclVarsParams=} [opt_params] - addition parameters:
6531 *
6532 * *) [end=true] - if is true, then will be appended ; to the string
6533 * *) [def='undefined'] - default value for variables
6534 * *) [sys=false] - if is true, then the variable will be declared as system
6535 *
6536 * @return {string}
6537 */
6538Parser.prototype.declVars = function (str, opt_params) {
6539 var _any2 = any(opt_params || {}),
6540 _any2$def = _any2.def,
6541 def = _any2$def === undefined ? 'undefined' : _any2$def,
6542 _any2$end = _any2.end,
6543 end = _any2$end === undefined ? true : _any2$end,
6544 sys = _any2.sys;
6545
6546 var bOpen = 0,
6547 cache = '';
6548
6549 var structure = this.structure,
6550 fin = 'var ';
6551
6552
6553 while (!structure.vars) {
6554 structure = structure.parent;
6555 }
6556
6557 if (structure.name === 'root') {
6558 fin = '';
6559 }
6560
6561 for (var i = 0; i < str.length; i++) {
6562 var el = str[i];
6563
6564 if (B_OPEN[el]) {
6565 bOpen++;
6566 } else if (B_CLOSE[el]) {
6567 bOpen--;
6568 }
6569
6570 var lastIteration = i === str.length - 1;
6571
6572 if ((el === ',' || lastIteration) && !bOpen) {
6573 if (lastIteration) {
6574 cache += el;
6575 }
6576
6577 var parts = cache.split('='),
6578 realVar = this.declVar(parts[0], { sys: sys });
6579
6580 parts[0] = realVar + (def || parts[1] ? '=' : '');
6581 parts[1] = parts[1] || def;
6582
6583 var val = parts.slice(1).join('=');
6584
6585 fin += '' + parts[0] + (val ? this.out(val, { unsafe: true }) : '') + ',';
6586 cache = '';
6587
6588 continue;
6589 }
6590
6591 cache += el;
6592 }
6593
6594 if (bOpen) {
6595 this.error('invalid "' + this.name + '" declaration');
6596 }
6597
6598 return fin.slice(0, -1) + (end ? ';' : '');
6599};
6600
6601var _templateObject$2 = taggedTemplateLiteral(['\n\t\t', '\n\t\t__RESULT__ = __GET_XML_ATTRS_DECL_END__(\n\t\t\t__RESULT__,\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', '\n\t\t);\n\t'], ['\n\t\t', '\n\t\t__RESULT__ = __GET_XML_ATTRS_DECL_END__(\n\t\t\t__RESULT__,\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', '\n\t\t);\n\t']);
6602var _templateObject2$1 = taggedTemplateLiteral(['\n\t\t\t__ATTR_STR__ = \'\';\n\t\t\t$attrType = \'attrValue\';\n\t\t'], ['\n\t\t\t__ATTR_STR__ = \'\';\n\t\t\t$attrType = \'attrValue\';\n\t\t']);
6603var _templateObject3$1 = taggedTemplateLiteral(['\' +\n\t\t\t\t($attrType = \'attrKeyGroup\', \'\') +\n\t\t\t\t\'', '', '\' +\n\t\t\t\t($attrType = \'attrKey\', \'\') +\n\t\t\t\t\'', ''], ['\' +\n\t\t\t\t($attrType = \'attrKeyGroup\', \'\') +\n\t\t\t\t\'', '', '\' +\n\t\t\t\t($attrType = \'attrKey\', \'\') +\n\t\t\t\t\'', '']);
6604var _templateObject4$1 = taggedTemplateLiteral(['\n\t\t\t__GET_XML_ATTR_KEY_DECL__(\n\t\t\t\t($attrType = \'attrKey\', $attrKey = ', '),\n\t\t\t\t', ',\n\t\t\t\t', '\n\t\t\t);\n\t\t'], ['\n\t\t\t__GET_XML_ATTR_KEY_DECL__(\n\t\t\t\t($attrType = \'attrKey\', $attrKey = ', '),\n\t\t\t\t', ',\n\t\t\t\t', '\n\t\t\t);\n\t\t']);
6605
6606/**
6607 * Returns string declaration of the specified XML attributes
6608 *
6609 * @param {string} str - source string
6610 * @return {string}
6611 */
6612Parser.prototype.getXMLAttrsDecl = function (str) {
6613 return this.getXMLAttrsDeclStart() + this.getXMLAttrsDeclBody(str) + this.getXMLAttrsDeclEnd();
6614};
6615
6616/**
6617 * Returns start declaration of XML attributes
6618 * @return {string}
6619 */
6620Parser.prototype.getXMLAttrsDeclStart = function () {
6621 return this.declVars('$attrs = {}', { sys: true });
6622};
6623
6624/**
6625 * Returns declaration body of the specified XML attributes
6626 *
6627 * @param {string} str - source string
6628 * @return {string}
6629 */
6630Parser.prototype.getXMLAttrsDeclBody = function (str) {
6631 var groups = this.splitXMLAttrGroup(str);
6632
6633 var res = '';
6634 for (var i = 0; i < groups.length; i++) {
6635 res += this.getXMLAttrDecl(groups[i]);
6636 }
6637
6638 return res;
6639};
6640
6641/**
6642 * Returns end declaration of XML attributes
6643 * @return {string}
6644 */
6645Parser.prototype.getXMLAttrsDeclEnd = function () {
6646 var tagName = this.getVar('$tagName'),
6647 attrs = this.getVar('$attrs');
6648
6649 var res = '';
6650 if (this.tagFilter) {
6651 res += this.out('({name: ' + tagName + ', attrs: ' + attrs + '}' + FILTER + this.tagFilter + ')', { unsafe: true }) + ';';
6652 }
6653
6654 return ws(_templateObject$2, res, tagName, attrs, !this.stringResult && !stringRender[this.renderMode], this.stringResult, this.doctype === 'xml', this.attrLiteralBounds ? JSON.stringify(this.attrLiteralBounds) : false);
6655};
6656
6657/**
6658 * Returns string declaration of the specified XML attribute
6659 *
6660 * @param {$$SnakeskinParserGetXMLAttrDeclParams} params - parameters:
6661 *
6662 * *) attr - source attribute
6663 * *) [group] - group name
6664 * *) [separator='-'] - group separator
6665
6666 * @return {string}
6667 */
6668Parser.prototype.getXMLAttrDecl = function (params) {
6669 var _params$group = params.group,
6670 group = _params$group === undefined ? '' : _params$group,
6671 _params$separator = params.separator,
6672 separator = _params$separator === undefined ? '-' : _params$separator;
6673
6674
6675 var parts = params.attr.split(' | '),
6676 eqRgxp = / =(?: |$)/;
6677
6678 var res = '';
6679 for (var i = 0; i < parts.length; i++) {
6680 var el = parts[i],
6681 args = el.split(eqRgxp);
6682
6683 var empty = args.length !== 2;
6684 if (empty) {
6685 if (this.doctype === 'xml') {
6686 args[1] = args[0];
6687 empty = false;
6688 } else {
6689 args[1] = '';
6690 }
6691 }
6692
6693 for (var _i = 0; _i < args.length; _i++) {
6694 args[_i] = args[_i].trim();
6695 }
6696
6697 res += ws(_templateObject2$1);
6698
6699 if (group) {
6700 args[0] = ws(_templateObject3$1, group, separator, args[0]);
6701 } else {
6702 args[0] = args[0][0] === '-' ? 'data-' + args[0].slice(1) : args[0];
6703 }
6704
6705 var tokens = this.getTokens(args[1]);
6706
6707 for (var _i2 = 0; _i2 < tokens.length; _i2++) {
6708 var attrVal = '\'' + this.pasteTplVarBlocks(tokens[_i2]) + '\'';
6709
6710 if (this.attrValueFilter) {
6711 attrVal += FILTER + this.attrValueFilter;
6712 attrVal = this.out(attrVal, { unsafe: true });
6713 }
6714
6715 res += '__APPEND_XML_ATTR_VAL__(' + attrVal + ');';
6716 }
6717
6718 var _attrKey = '\'' + this.pasteTplVarBlocks(args[0]) + '\'';
6719
6720 if (this.attrKeyFilter) {
6721 _attrKey += FILTER + this.attrKeyFilter;
6722 _attrKey = this.out(_attrKey, { unsafe: true });
6723 }
6724
6725 res += ws(_templateObject4$1, _attrKey, this.getVar('$attrs'), empty);
6726 }
6727
6728 return res;
6729};
6730
6731/**
6732 * Splits a string of XML attribute declaration into groups
6733 *
6734 * @param {string} str - source string
6735 * @return {!Array<$$SnakeskinParserGetXMLAttrDeclParams>}
6736 */
6737Parser.prototype.splitXMLAttrGroup = function (str) {
6738 str = this.replaceTplVars(str, { replace: true });
6739
6740 var groups = [],
6741 groupBounds = ['(( ', ' ))'],
6742 groupLength = groupBounds[0].length,
6743 pOpenLength = groupBounds[0].trim().length;
6744
6745 var group = '',
6746 attr = '',
6747 separator = '',
6748 pOpen = 0,
6749 escape = false;
6750
6751 for (var i = 0; i < str.length; i++) {
6752 var el = str[i],
6753 cEscape = escape,
6754 chunk = !cEscape && str.substr(i, groupLength);
6755
6756 if (el === '\\' || escape) {
6757 escape = !escape;
6758 }
6759
6760 if (!pOpen) {
6761 if (attrSeparators[el] && !cEscape && str.substr(i + 1, groupLength) === groupBounds[0]) {
6762 pOpen = pOpenLength;
6763 i += groupLength;
6764 separator = el;
6765 continue;
6766 }
6767
6768 if (chunk === groupBounds[0]) {
6769 pOpen = pOpenLength;
6770 i += groupLength - 1;
6771 separator = '';
6772 continue;
6773 }
6774 }
6775
6776 if (pOpen) {
6777 if (chunk === groupBounds[1] && pOpen === pOpenLength) {
6778 groups.push({
6779 attr: attr.trim(),
6780 group: (attrKey.exec(group) || [])[1],
6781 separator: separator
6782 });
6783
6784 pOpen = 0;
6785 group = '';
6786 attr = '';
6787 separator = '';
6788
6789 i += groupLength - 1;
6790 continue;
6791 } else if (el === '(') {
6792 pOpen++;
6793 } else if (el === ')') {
6794 pOpen--;
6795 }
6796 }
6797
6798 if (!pOpen) {
6799 group += el;
6800 } else {
6801 attr += el;
6802 }
6803 }
6804
6805 if (group && !attr) {
6806 groups.push({
6807 attr: group.trim(),
6808 group: undefined,
6809 separator: undefined
6810 });
6811 }
6812
6813 return groups;
6814};
6815
6816var _templateObject$3 = taggedTemplateLiteral(['\n\t\t', '\n\t\t__RESULT__ = __GET_XML_ATTRS_DECL_START__(\n\t\t\t__RESULT__,\n\t\t\t', ',\n\t\t\t\'', '\',\n\t\t\t', ',\n\t\t\t', '\n\t\t);\n\t'], ['\n\t\t', '\n\t\t__RESULT__ = __GET_XML_ATTRS_DECL_START__(\n\t\t\t__RESULT__,\n\t\t\t', ',\n\t\t\t\'', '\',\n\t\t\t', ',\n\t\t\t', '\n\t\t);\n\t']);
6817var _templateObject2$2 = taggedTemplateLiteral(['\n\t\t', '\n\t\t', '\n\t\t__RESULT__ = __GET_XML_TAG_DECL_END__(\n\t\t\t__RESULT__,\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', '\n\t\t);\n\t'], ['\n\t\t', '\n\t\t', '\n\t\t__RESULT__ = __GET_XML_TAG_DECL_END__(\n\t\t\t__RESULT__,\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', '\n\t\t);\n\t']);
6818var _templateObject3$2 = taggedTemplateLiteral(['\n\t\t', '\n\t\t__RESULT__ = __GET_END_XML_TAG_DECL__(\n\t\t\t__RESULT__,\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', '.trim(),\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', '\n\t\t\t', '\n\t\t);\n\t'], ['\n\t\t', '\n\t\t__RESULT__ = __GET_END_XML_TAG_DECL__(\n\t\t\t__RESULT__,\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', '.trim(),\n\t\t\t', ',\n\t\t\t', ',\n\t\t\t', '\n\t\t\t', '\n\t\t);\n\t']);
6819
6820var defaultTag = 'div';
6821
6822/**
6823 * Returns string declaration of an opening tag for the specified XML tag
6824 *
6825 * @param {string} tag - tag name
6826 * @param {?string=} [opt_attrs] - tag attributes
6827 * @param {?boolean=} opt_inline - if true, then the tag is inline
6828 * @return {string}
6829 */
6830Parser.prototype.getXMLTagDecl = function (tag, opt_attrs, opt_inline) {
6831 return this.getXMLTagDeclStart(tag) + this.getXMLAttrsDeclStart() + (opt_attrs ? this.getXMLAttrsDeclBody(opt_attrs) : '') + this.getXMLAttrsDeclEnd() + this.getXMLTagDeclEnd(opt_inline);
6832};
6833
6834/**
6835 * Returns start declaration of the specified XML tag
6836 *
6837 * @param {string} tag - tag name
6838 * @return {string}
6839 */
6840Parser.prototype.getXMLTagDeclStart = function (tag) {
6841 tag = '\'' + tag + '\'';
6842
6843 if (this.tagNameFilter) {
6844 tag += FILTER + this.tagNameFilter;
6845 }
6846
6847 return ws(_templateObject$3, this.declVars('$tagName = (' + tag + ').trim() || \'' + defaultTag + '\'', { sys: true }), this.getVar('$tagName'), this.renderMode, !stringRender[this.renderMode], this.stringResult);
6848};
6849
6850/**
6851 * Returns end declaration of the specified XML tag
6852 *
6853 * @param {?boolean=} opt_inline - if true, then the tag is inline
6854 * @return {string}
6855 */
6856Parser.prototype.getXMLTagDeclEnd = function (opt_inline) {
6857 var isDOMRenderMode = !this.stringResult && !stringRender[this.renderMode];
6858
6859 return ws(_templateObject2$2, this.declVars('__CALL_CACHE__ = __RESULT__', { sys: true }), isDOMRenderMode ? this.declVars('__NODE__ = $0', { sys: true }) : '', this.getVar('$tagName'), Boolean(opt_inline), this.out('__INLINE_TAGS__[$tagName]', { unsafe: true }), isDOMRenderMode, this.stringResult, this.doctype === 'xml');
6860};
6861
6862/**
6863 * Returns string declaration of a closing tag for the specified XML tag
6864 *
6865 * @param {?boolean=} opt_inline - if true, then the tag is inline
6866 * @return {string}
6867 */
6868Parser.prototype.getEndXMLTagDecl = function (opt_inline) {
6869 var isDOMRenderMode = !this.stringResult && !stringRender[this.renderMode];
6870
6871 return ws(_templateObject3$2, this.declVars('__CALL_TMP__ = ' + this.getReturnResultDecl(), { sys: true }), this.getVar('$tagName'), Boolean(opt_inline), this.out('__INLINE_TAGS__[$tagName]', { unsafe: true }), this.getVar('$attrs'), this.getVar('__CALL_CACHE__'), this.getVar('__CALL_TMP__'), isDOMRenderMode, this.stringResult, this.doctype === 'xml', isDOMRenderMode ? ', ' + this.getVar('__NODE__') : '');
6872};
6873
6874/**
6875 * Analyzes a string of XML tag declaration
6876 * and returns a reporting object
6877 *
6878 * @param {string} str - source string
6879 * @return {$$SnakeskinParserGetXMLTagDescResult}
6880 */
6881Parser.prototype.getXMLTagDesc = function (str) {
6882 str = this.replaceTplVars(str, { replace: true });
6883
6884 var points = [],
6885 types = [];
6886
6887 var action = '',
6888 tag = '',
6889 id = '';
6890
6891 var inline = false,
6892 inlineMap = false,
6893 hasId = false;
6894
6895 var pseudo = [],
6896 classes = [];
6897
6898 var s = MICRO_TEMPLATE,
6899 e = RIGHT_BOUND;
6900
6901 var bOpen = 0,
6902 bStart = false;
6903
6904 var classRef = /^&/;
6905
6906 var bMap = {
6907 '[': true,
6908 ']': true
6909 };
6910
6911 var sys = {
6912 '!': true,
6913 '#': true,
6914 '.': true
6915 };
6916
6917 var error = {
6918 classes: [],
6919 id: '',
6920 inline: false,
6921 inlineMap: false,
6922 pseudo: [],
6923 tag: ''
6924 };
6925
6926 function pseudoHelper() {
6927 var val = pseudo[pseudo.length - 1];
6928
6929 if (val === 'inline') {
6930 inline = true;
6931 } else if (/inline=/.test(val)) {
6932 inlineMap = val.split('=')[1].trim();
6933 }
6934 }
6935
6936 for (var i = 0; i < str.length; i++) {
6937 var el = str[i];
6938
6939 if (bMap[el]) {
6940 if (el === '[') {
6941 bOpen++;
6942 bStart = true;
6943 } else {
6944 bOpen--;
6945 }
6946
6947 continue;
6948 }
6949
6950 if (bStart && el !== '.') {
6951 this.error('invalid syntax');
6952 return error;
6953 }
6954
6955 bStart = false;
6956 if (sys[el] && (el !== '#' || !bOpen)) {
6957 if (el === '#') {
6958 if (hasId) {
6959 this.error('invalid syntax');
6960 return error;
6961 }
6962
6963 hasId = true;
6964 }
6965
6966 tag = tag || 'div';
6967 action = el;
6968
6969 if (el === '.') {
6970 if (bOpen) {
6971 if (points.length) {
6972 for (var _i = points.length; _i--;) {
6973 var point = points[_i];
6974
6975 if (point) {
6976 if (point.stage >= bOpen) {
6977 continue;
6978 }
6979
6980 var tmp = classes[_i],
6981 pos = point.from;
6982
6983 if (point.val != null) {
6984 tmp = tmp.replace(classRef, point.val);
6985 }
6986
6987 while (points[pos] != null) {
6988 var _points$pos = points[pos],
6989 val = _points$pos.val,
6990 from = _points$pos.from;
6991
6992 tmp = tmp.replace(classRef, val);
6993 pos = from;
6994 }
6995
6996 points.push({
6997 from: _i,
6998 stage: bOpen,
6999 val: tmp
7000 });
7001
7002 break;
7003 }
7004
7005 points.push({
7006 from: _i,
7007 stage: bOpen,
7008 val: classes[_i]
7009 });
7010
7011 break;
7012 }
7013 } else {
7014 points.push({
7015 from: null,
7016 stage: bOpen,
7017 val: null
7018 });
7019 }
7020 } else {
7021 points.push(null);
7022 }
7023
7024 types.push(!bOpen);
7025 classes.push('');
7026 } else if (el === '!') {
7027 pseudoHelper();
7028 pseudo.push('');
7029 }
7030
7031 continue;
7032 }
7033
7034 switch (action) {
7035 case '#':
7036 id += el;
7037 break;
7038
7039 case '.':
7040 classes[classes.length - 1] += el;
7041 break;
7042
7043 case '!':
7044 pseudo[pseudo.length - 1] += el;
7045 break;
7046
7047 default:
7048 tag += el;
7049 }
7050 }
7051
7052 if (bOpen) {
7053 this.error('invalid syntax');
7054 return error;
7055 }
7056
7057 var ref = this.bemRef;
7058
7059 for (var _i2 = 0; _i2 < classes.length; _i2++) {
7060 var _el = classes[_i2];
7061
7062 var _point = points[_i2];
7063
7064 if (_point && _point.val != null) {
7065 _el = _el.replace(classRef, _point.val);
7066 }
7067
7068 if (classRef.test(_el) && ref) {
7069 if (this.bemFilter) {
7070 _el = s + '\'' + ref + '\'' + FILTER + this.bemFilter + ' \'' + _el.slice(1) + '\'' + e;
7071 } else {
7072 _el = s + '\'' + ref + '\' + \'' + _el.slice(1) + '\'' + e;
7073 }
7074
7075 _el = this.pasteDangerBlocks(this.replaceTplVars(_el));
7076 } else if (_el && types[_i2]) {
7077 ref = this.pasteTplVarBlocks(_el);
7078 this.append('$class = \'' + ref + '\';');
7079 }
7080
7081 classes[_i2] = this.pasteTplVarBlocks(_el);
7082 }
7083
7084 this.bemRef = ref;
7085 pseudoHelper();
7086
7087 return {
7088 classes: classes,
7089 id: this.pasteTplVarBlocks(id),
7090 inline: inline,
7091 inlineMap: inlineMap,
7092 pseudo: pseudo,
7093 tag: this.pasteTplVarBlocks(tag)
7094 };
7095};
7096
7097/**
7098 * Appends default filters to output
7099 *
7100 * @param {!Object} filters - source filters
7101 * @return {!Array}
7102 */
7103Parser.prototype.appendDefaultFilters = function (filters) {
7104 var obj = Object.assign({ global: [], local: [] }, filters),
7105 arr = Object.keys(obj);
7106
7107 var f = this.filters = this.filters || [],
7108 prev = f[f.length - 1],
7109 prevMap = {};
7110
7111 Snakeskin$1.forEach(prev, function (el, key) {
7112 prevMap[key] = {};
7113 Snakeskin$1.forEach(el, function (el) {
7114 prevMap[key][Object.keys(el)[0]] = true;
7115 });
7116 });
7117
7118 for (var i = 0; i < arr.length; i++) {
7119 var key = arr[i],
7120 _filters = obj[key];
7121
7122 for (var _i = 0; _i < _filters.length; _i++) {
7123 var el = _filters[_i];
7124
7125 if (isArray(el)) {
7126 el = el[0];
7127
7128 var isStr = isString(el);
7129
7130 if (prevMap[key] && prevMap[key][isStr ? el : Object.keys(el)[0]]) {
7131 _filters[_i] = isStr ? defineProperty({}, el, []) : el;
7132 } else {
7133 _filters.splice(_i, 1);
7134 _i--;
7135 }
7136 } else if (isString(el)) {
7137 _filters[_i] = defineProperty({}, el, []);
7138 }
7139 }
7140 }
7141
7142 f.push(obj);
7143 return f;
7144};
7145
7146var unaryBlackWords = {
7147 'in': true,
7148 'instanceof': true,
7149 'new': true,
7150 'of': true,
7151 'typeof': true
7152};
7153
7154var nextWordCharRgxp = new RegExp('[' + r(G_MOD) + '+\\-~!' + w + '[\\]().]');
7155
7156/**
7157 * Returns a full word from a string from the specified position
7158 *
7159 * @param {string} str - source string
7160 * @param {number} pos - start search position
7161 * @return {{word: string, finalWord: string, unary: string}}
7162 */
7163Parser.prototype.getWordFromPos = function (str, pos) {
7164 var pCount = 0,
7165 diff = 0;
7166
7167 var start = 0,
7168 pContent = null;
7169
7170 var unary = void 0,
7171 unaryStr = '',
7172 word = '';
7173
7174 var res = '',
7175 nRes = '';
7176
7177 for (var i = pos, j = 0; i < str.length; i++, j++) {
7178 var el = str[i];
7179
7180 if (!pCount && !nextWordCharRgxp.test(el) && (el !== ' ' || !(unary = unaryBlackWords[word]))) {
7181 break;
7182 }
7183
7184 if (el === ' ') {
7185 word = '';
7186 } else {
7187 word += el;
7188 }
7189
7190 if (unary) {
7191 unaryStr = unaryStr || res;
7192 unary = false;
7193 }
7194
7195 if (pContent !== null && (pCount > 1 || pCount === 1 && !P_CLOSE[el])) {
7196 pContent += el;
7197 }
7198
7199 if (P_OPEN[el]) {
7200 if (pContent === null) {
7201 start = j + 1;
7202 pContent = '';
7203 }
7204
7205 pCount++;
7206 } else if (P_CLOSE[el]) {
7207 if (!pCount) {
7208 break;
7209 }
7210
7211 pCount--;
7212 if (!pCount) {
7213 nRes = nRes.slice(0, start + diff) + (pContent && this.out(pContent, { unsafe: true }));
7214 diff = nRes.length - res.length;
7215 pContent = null;
7216 }
7217 }
7218
7219 res += el;
7220 nRes += el;
7221 }
7222
7223 return {
7224 finalWord: nRes,
7225 unary: unaryStr,
7226 word: res
7227 };
7228};
7229
7230/**
7231 * Splits a string by a separator and returns an array of tokens
7232 *
7233 * @param {string} str - source string
7234 * @return {!Array<string>}
7235 */
7236Parser.prototype.getTokens = function (str) {
7237 var arr = [''];
7238
7239 var escape = false,
7240 bStart = false,
7241 bOpen = 0;
7242
7243 for (var i = 0; i < str.length; i++) {
7244 var el = str[i],
7245 part = str.substr(i, MICRO_TEMPLATE.length),
7246 cEscape = escape;
7247
7248 if (el === '\\' || escape) {
7249 escape = !escape;
7250 }
7251
7252 var l = arr.length - 1;
7253 if (!cEscape && part === MICRO_TEMPLATE) {
7254 i += MICRO_TEMPLATE.length - 1;
7255 arr[l] += part;
7256 bStart = true;
7257 bOpen++;
7258 continue;
7259 }
7260
7261 if (bStart) {
7262 switch (el) {
7263 case LEFT_BOUND:
7264 bOpen++;
7265 break;
7266
7267 case RIGHT_BOUND:
7268 bOpen--;
7269 break;
7270 }
7271 }
7272
7273 if (el === ' ' && !bOpen) {
7274 l = arr.push('') - 1;
7275 }
7276
7277 if (el !== ' ' || bOpen) {
7278 arr[l] += el;
7279 }
7280 }
7281
7282 return arr;
7283};
7284
7285var _templateObject$4 = taggedTemplateLiteral(['\n\t\tvar __RESULT__ = ', ';\n\n\t\tfunction getTplResult(opt_clear) {\n\t\t\tvar res = ', ';\n\n\t\t\tif (opt_clear) {\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t}\n\n\t\t\treturn res;\n\t\t}\n\n\t\tfunction clearTplResult() {\n\t\t\t__RESULT__ = ', ';\n\t\t}\n\t'], ['\n\t\tvar __RESULT__ = ', ';\n\n\t\tfunction getTplResult(opt_clear) {\n\t\t\tvar res = ', ';\n\n\t\t\tif (opt_clear) {\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t}\n\n\t\t\treturn res;\n\t\t}\n\n\t\tfunction clearTplResult() {\n\t\t\t__RESULT__ = ', ';\n\t\t}\n\t']);
7286
7287/**
7288 * Returns declaration of template runtime
7289 * @return {string}
7290 */
7291Parser.prototype.getTplRuntime = function () {
7292 return ws(_templateObject$4, this.getResultDecl(), this.getReturnResultDecl(), this.getResultDecl(), this.getResultDecl());
7293};
7294
7295/**
7296 * Compiles Snakeskin templates
7297 *
7298 * @param {(Element|string)} src - reference to a DOM node, where the templates were declared
7299 * or a text of the templates
7300 *
7301 * @param {?$$SnakeskinParams=} [opt_params] - additional runtime parameters:
7302 * *) [cache = true] - if is false, then caching will be disabled
7303 * *) [vars] - map of super global variables, which will be added to Snakeskin.Vars
7304 * *) [context] - storage object for compiled templates
7305 * *) [babel] - array of applied babel plugins
7306 *
7307 * *) [onError] - callback for an error handling
7308 * *) [throws = false] - if is true, then in case of an error or a missing error handler will be thrown an exception
7309 * *) [debug] - object, which will be contained some debug information
7310 *
7311 * *) [resolveModuleSource] - function for resolve a module source
7312 * *) [pack = false] - if true, then templates will be compiled to WebPack format
7313 * *) [module = 'umd'] - module type for compiled templates (native, umd, amd, cjs, global)
7314 * *) [moduleId = 'tpls'] - module id for AMD/UMD declaration
7315 * *) [moduleName] - module name for global/UMD declaration
7316 *
7317 * *) [useStrict = true] - if is false, then all templates will be compiled without the 'use strict'; mode
7318 * *) [prettyPrint = false] - if is true, then output code will be formatted (js-beautify)
7319 *
7320 * *) [literalBounds = ['{', '}']] - bounds for the literal directive
7321 * *) [attrLiteralBounds] - bounds for the attribute literal directive
7322 * *) [tagNameFilter] - name of the tag name filter
7323 * *) [tagFilter] - name of the tag filter
7324 * *) [attrKeyFilter] - name of the attribute key filter
7325 * *) [attrValueFilter] - name of the attribute value filter
7326 * *) [bemFilter] - name of the bem filter
7327 * *) [filters = ['undef', 'html']] - list of default filters for output
7328 *
7329 * *) [localization = true] - if is false, then localization literals ` ... ` won't be wrapped with a i18n function
7330 * *) [i18nFn = 'i18n'] - name of the i18n function
7331 * *) [i18nFnOptions] - additional option for the i18n function or array of options
7332 * *) [language] - map of words for the localization (for example, {'Hello world': 'Привет мир'})
7333 * *) [words] - object, which will be contained all found localization words
7334 *
7335 * *) [ignore] - RegExp object, which specifies whitespace symbols for ignoring
7336 * *) [tolerateWhitespaces = false] - if is true, then whitespaces will be processed "as is"
7337 * *) [eol = '\n'] - EOL symbol
7338 *
7339 * *) [doctype = 'html'] - document type
7340 * *) [renderAs] - rendering type of templates:
7341 * 1) placeholder - all templates will be rendered as "placeholder";
7342 * 2) interface - all templates will be rendered as "interface";
7343 * 3) template - all templates will be rendered as "template".
7344 *
7345 * *) [renderMode = 'stringConcat'] - rendering mode of templates:
7346 * 1) stringConcat - renders template to a string, for concatenation of strings will be used operator;
7347 * 2) stringBuffer - renders template to a string, for concatenation of strings will be used Snakeskin.StringBuffer;
7348 * 3) dom - renders template to a DocumentFragment object.
7349 *
7350 * @param {?$$SnakeskinInfoParams=} [opt_info] - additional parameters for debug:
7351 * *) [file] - path to a template file
7352 *
7353 * @return {(string|boolean|null)}
7354 */
7355Snakeskin$1.compile = function (src, opt_params, opt_info) {
7356 src = src || '';
7357
7358 /** @type {$$SnakeskinParams} */
7359 var p = any(Object.assign({
7360 cache: true,
7361 doctype: 'html',
7362 renderMode: 'stringConcat',
7363 vars: {},
7364 throws: true,
7365 pack: false,
7366 module: 'umd',
7367 moduleId: 'tpls',
7368 useStrict: true,
7369 prettyPrint: false,
7370 literalBounds: ['{{', '}}'],
7371 filters: { global: ['html', 'undef'], local: ['undef'] },
7372 tolerateWhitespaces: false,
7373 eol: '\n',
7374 localization: true,
7375 i18nFn: 'i18n',
7376 i18nOptions: []
7377 }, opt_params));
7378
7379 if (p.pack) {
7380 p.module = 'cjs';
7381 }
7382
7383 Snakeskin$1.forEach(p.vars, function (el, key) {
7384 Snakeskin$1.Vars[key] = el;
7385 });
7386
7387 // <<<
7388 // Debug information
7389 // >>>
7390
7391 var info = any(Object.assign({ line: 1 }, opt_info));
7392
7393 var text = void 0;
7394 if ((typeof src === 'undefined' ? 'undefined' : _typeof(src)) === 'object' && 'innerHTML' in src) {
7395 info.node = src;
7396 text = src.innerHTML.replace(wsStart, '');
7397 } else {
7398 text = String(src);
7399 }
7400
7401 // <<<
7402 // Caching
7403 // >>>
7404
7405 var ctx = p.context || NULL,
7406 cacheKey = getCacheKey(p, ctx);
7407
7408 if (p.getCacheKey) {
7409 return cacheKey;
7410 }
7411
7412 if (p.cache) {
7413 var tmp = getFromCache(cacheKey, text, p, ctx);
7414
7415 if (tmp) {
7416 return tmp;
7417 }
7418 }
7419
7420 // <<<
7421 // File initialization
7422 // >>>
7423
7424 var label = '';
7425 Snakeskin$1.LocalVars.include = {};
7426 Snakeskin$1.UID = Math.random().toString(16).replace('0.', '').slice(0, 5);
7427
7428 if (IS_NODE && info.file) {
7429 var path = require('path');
7430 info.file = path.normalize(path.resolve(info.file));
7431 Snakeskin$1.LocalVars.include[info.file] = templateRank['template'];
7432 label = mtime(info.file);
7433 }
7434
7435 // <<<
7436 // Transpiler
7437 // >>>
7438
7439 var parser = new Parser(text, any(Object.assign({ info: info }, p)));
7440
7441 var begin = 0,
7442 beginStr = false;
7443
7444 var command = '',
7445 rawCommand = '',
7446 commandLength = 0,
7447 commandNameDecl = false,
7448 filterStart$$1 = false,
7449 pseudoI = false;
7450
7451 var commandTypeRgxp = /[^\s]+/,
7452 commandRgxp = /[^\s]+\s*/,
7453 ignoreRgxp = new RegExp(r(ADV_LEFT_BOUND) + '?' + r(LEFT_BOUND) + '__.*?__.*?' + r(RIGHT_BOUND), 'g');
7454
7455 var escape = false,
7456 comment = false,
7457 commentStart = 0;
7458
7459 var jsDoc = false,
7460 jsDocStart = false;
7461
7462 var freezeI = 0,
7463 freezeTmp = 0,
7464 prfxI = 0;
7465
7466 var prevCommentSpace = false,
7467 clrL = true;
7468
7469 var bOpen = false,
7470 bEnd$$1 = void 0,
7471 bEscape = false,
7472 part = '',
7473 rPart = '';
7474
7475 var i18nStr = '',
7476 i18nStart = false,
7477 i18nDirStart = false,
7478 i18nInterpolation = false,
7479 i18nTpl = 0,
7480 i18nPOpen = 0;
7481
7482 /**
7483 * @param {string} val
7484 * @return {(function(string): string|undefined)}
7485 */
7486 function getReplacer(val) {
7487 return $dirNameShorthands[val.substr(0, 2)] || $dirNameShorthands[val[0]];
7488 }
7489
7490 while (++parser.i < parser.source.length) {
7491 var str = parser.source,
7492 structure = parser.structure;
7493
7494
7495 var el = str[parser.i];
7496
7497 if (begin) {
7498 rawCommand += el;
7499 }
7500
7501 var rEl = el,
7502 next = str[parser.i + 1],
7503 substr2 = str.substr(parser.i, 2);
7504
7505 var line = info.line,
7506 lastLine = line - 1;
7507
7508
7509 var modLine = !parser.freezeLine && parser.lines.length === line;
7510
7511 if (freezeI) {
7512 freezeI--;
7513 modLine = false;
7514 }
7515
7516 var eol$$1 = eol.test(el),
7517 cClrL = clrL,
7518 space = parser.strongSpace[parser.strongSpace.length - 1];
7519
7520 if (eol$$1) {
7521 if (substr2 === '\r\n') {
7522 if (begin) {
7523 commandLength++;
7524 }
7525
7526 continue;
7527 }
7528
7529 el = p.eol;
7530 clrL = true;
7531 }
7532
7533 if (!parser.freezeLine) {
7534 if (eol$$1) {
7535 if (modLine) {
7536 parser.lines[line] = '';
7537 }
7538
7539 info.line++;
7540 } else if (modLine) {
7541 parser.lines[lastLine] += el;
7542 }
7543 }
7544
7545 var cEscape = escape,
7546 isPrefStart = !cEscape && !begin && substr2 === ADV_LEFT_BOUND + LEFT_BOUND;
7547
7548 if (ws$1.test(el)) {
7549 // Inside a directive
7550 if (begin) {
7551 if (bOpen) {
7552 el = escapeEOLs(el);
7553 } else {
7554 if (!parser.space) {
7555 el = ' ';
7556 parser.space = true;
7557 } else if (!comment) {
7558 commandLength++;
7559 continue;
7560 } else {
7561 commandLength++;
7562 }
7563 }
7564
7565 // Outside a template
7566 } else if (!parser.tplName) {
7567 // For JSDoc all of symbols don't change,
7568 // but in other case they will be ignored
7569 if (!comment && !jsDoc) {
7570 continue;
7571 }
7572
7573 // Inside a template
7574 } else {
7575 if (!space && (parser.tolerateWhitespaces || !parser.space) && !parser.sysSpace) {
7576 el = parser.ignore && parser.ignore.test(el) ? '' : el;
7577
7578 if (el) {
7579 el = parser.tolerateWhitespaces ? el : ' ';
7580 parser.space = true;
7581 }
7582 } else if (!comment && !jsDoc) {
7583 continue;
7584 }
7585 }
7586 } else {
7587 clrL = false;
7588
7589 if (!begin && !space && !parser.sysSpace) {
7590 if (isPrefStart ? el === ADV_LEFT_BOUND : el === LEFT_BOUND) {
7591 parser.prevSpace = parser.space;
7592 } else {
7593 parser.prevSpace = false;
7594 }
7595 }
7596
7597 if (!comment) {
7598 prevCommentSpace = parser.space;
7599 }
7600
7601 parser.space = false;
7602 }
7603
7604 if (!bOpen) {
7605 if (el === '\\' && (begin ? BASE_SYS_ESCAPES : SYS_ESCAPES)[next] || escape) {
7606 escape = !escape;
7607 }
7608
7609 if (escape) {
7610 continue;
7611 }
7612
7613 if (!cEscape && !i18nStart) {
7614 var _map;
7615
7616 var commentType = getCommentType(str, parser.i),
7617 endComment = (comment === MULT_COMMENT_START || jsDoc) && getCommentType(str, parser.i - MULT_COMMENT_END.length + 1) === MULT_COMMENT_END;
7618
7619 var map = (_map = {}, defineProperty(_map, MULT_COMMENT_START, true), defineProperty(_map, SINGLE_COMMENT, true), _map);
7620
7621 if (map[commentType] || endComment) {
7622 if (!comment && !jsDoc) {
7623 if (commentType === SINGLE_COMMENT) {
7624 comment = commentType;
7625
7626 if (modLine) {
7627 parser.lines[lastLine] += commentType.slice(1);
7628 }
7629
7630 parser.i += commentType.length - 1;
7631 } else if (commentType === MULT_COMMENT_START) {
7632 commentStart = parser.i;
7633
7634 if (!begin && str.substr(parser.i, JS_DOC.length) === JS_DOC) {
7635 if (beginStr && parser.isSimpleOutput()) {
7636 parser.save('\'' + parser.$$() + ';');
7637 }
7638
7639 jsDoc = true;
7640 jsDocStart = parser.result.length;
7641 beginStr = true;
7642 } else {
7643 comment = commentType;
7644
7645 if (modLine) {
7646 parser.lines[lastLine] += commentType.slice(1);
7647 }
7648
7649 parser.i += commentType.length - 1;
7650 }
7651 }
7652 } else if (endComment && parser.i - commentStart > MULT_COMMENT_START.length) {
7653 if (comment === MULT_COMMENT_START) {
7654 comment = false;
7655 parser.space = prevCommentSpace;
7656 prevCommentSpace = false;
7657 continue;
7658 } else if (beginStr) {
7659 beginStr = false;
7660 }
7661 }
7662 } else if (eol.test(rEl) && comment === SINGLE_COMMENT) {
7663 comment = false;
7664 parser.space = prevCommentSpace;
7665 prevCommentSpace = false;
7666 continue;
7667 }
7668 }
7669
7670 if (comment) {
7671 continue;
7672 }
7673
7674 if (!jsDoc) {
7675 if (begin) {
7676 if (i18nPOpen) {
7677 if (el === '(') {
7678 i18nPOpen++;
7679 } else if (el === ')' && i18nPOpen && ! --i18nPOpen) {
7680 el = el + (!i18nInterpolation || i18nTpl ? '' : RIGHT_BOUND);
7681 }
7682 }
7683
7684 if (!cEscape) {
7685 if (substr2 === MICRO_TEMPLATE) {
7686 i18nTpl = 1;
7687 } else if (el === RIGHT_BOUND && i18nTpl) {
7688 i18nTpl--;
7689 }
7690 }
7691 }
7692
7693 if (i18nStart) {
7694 if (!parser.language) {
7695 if (cEscape) {
7696 if (el === '\\') {
7697 el = '\\\\';
7698 }
7699 } else if (el === '"') {
7700 el = '\\"';
7701 }
7702 }
7703
7704 if (cEscape || el !== I18N) {
7705 if (pseudoI !== false) {
7706 continue;
7707 }
7708
7709 i18nStr += el;
7710 if (parser.language) {
7711 continue;
7712 }
7713 }
7714 }
7715
7716 if (el === I18N && parser.localization && !cEscape) {
7717 if (i18nStart && i18nStr && p.words && !p.words[i18nStr]) {
7718 p.words[i18nStr] = i18nStr;
7719 }
7720
7721 if (!i18nStart && begin) {
7722 var _ref = commandRgxp.exec(command) || [''],
7723 _ref2 = slicedToArray(_ref, 1),
7724 cmd = _ref2[0];
7725
7726 var replacer = getReplacer(cmd);
7727
7728 if (replacer) {
7729 cmd = replacer(cmd);
7730 }
7731
7732 i18nInterpolation = (cmd = cmd.trim()) && $dirInterpolation[cmd];
7733 }
7734
7735 if (parser.language) {
7736 if (i18nStart) {
7737 var word = parser.language[i18nStr] || '';
7738 word = isFunction(word) ? word() : word;
7739
7740 el = begin && (!i18nInterpolation || i18nTpl) ? '\'' + applyDefEscape(word) + '\'' : word;
7741
7742 i18nStart = false;
7743 i18nInterpolation = false;
7744 i18nStr = '';
7745 } else {
7746 i18nStart = true;
7747 el = '';
7748 }
7749 } else {
7750 if (i18nStart) {
7751 i18nStart = false;
7752 i18nStr = '';
7753
7754 if (begin) {
7755 el = '"';
7756 if (next === '(') {
7757 el += ',';
7758 i18nPOpen++;
7759 parser.lines[lastLine] += next;
7760 parser.i++;
7761 } else {
7762 if (parser.i18nFnOptions) {
7763 el += ', ' + parser.i18nFnOptions;
7764 }
7765
7766 el += ')' + (!i18nInterpolation || i18nTpl ? '' : RIGHT_BOUND);
7767 }
7768
7769 if (i18nDirStart) {
7770 i18nDirStart = false;
7771 parser.freezeLine--;
7772 freezeI += freezeTmp;
7773 freezeTmp = 0;
7774 }
7775
7776 i18nInterpolation = false;
7777 } else {
7778 var advStr = FILTER + '!html' + RIGHT_BOUND;
7779
7780 freezeTmp = advStr.length;
7781 parser.source = str.slice(0, parser.i + 1) + advStr + str.slice(parser.i + 1);
7782
7783 parser.i = Number(pseudoI);
7784 parser.freezeLine++;
7785 pseudoI = false;
7786 continue;
7787 }
7788 } else {
7789 i18nStart = true;
7790
7791 if (begin) {
7792 el = '' + (!i18nInterpolation || i18nTpl ? '' : MICRO_TEMPLATE) + parser.i18nFn + '("';
7793 } else {
7794 var diff = Number(parser.needPrfx) + 1;
7795
7796 parser.source = str.slice(0, parser.i) + (parser.needPrfx ? ADV_LEFT_BOUND : '') + LEFT_BOUND + str.slice(parser.i);
7797
7798 pseudoI = parser.i - diff;
7799 parser.i += diff;
7800 i18nDirStart = true;
7801 continue;
7802 }
7803 }
7804 }
7805 }
7806
7807 if (!i18nStart && !cEscape) {
7808 // Directive is started
7809 if (isPrefStart || el === LEFT_BOUND) {
7810 if (begin && !cEscape) {
7811 begin++;
7812 } else if (!parser.needPrfx || isPrefStart) {
7813 if (isPrefStart) {
7814 parser.i++;
7815 parser.needPrfx = true;
7816
7817 if (modLine) {
7818 parser.lines[lastLine] += LEFT_BOUND;
7819 }
7820 }
7821
7822 bEnd$$1 = true;
7823 commandNameDecl = true;
7824 begin = 1;
7825
7826 continue;
7827 }
7828
7829 // Directive is ended
7830 } else if (el === RIGHT_BOUND && begin && ! --begin) {
7831 commandNameDecl = false;
7832
7833 var commandExpr = command,
7834 _replacer = getReplacer(command);
7835
7836 command = command.trim();
7837 if (!command) {
7838 continue;
7839 }
7840
7841 if (_replacer) {
7842 command = _replacer(command);
7843 }
7844
7845 var _commandTypeRgxp$exec = commandTypeRgxp.exec(command),
7846 _commandTypeRgxp$exec2 = slicedToArray(_commandTypeRgxp$exec, 1),
7847 commandType = _commandTypeRgxp$exec2[0];
7848
7849 var defDir = !Snakeskin$1.Directives[commandType];
7850
7851 if (defDir) {
7852 if (isAssignExpression(command, !parser.tplName)) {
7853 commandType = parser.tplName ? 'const' : 'global';
7854 } else {
7855 commandType = parser.tplName ? 'output' : 'decorator';
7856 }
7857 }
7858
7859 commandType = Snakeskin$1.Directives[commandType] ? commandType : 'output';
7860
7861 // All directives, which matches to the template __.*?__
7862 // will be cutted from the code listing
7863 if (ignoreRgxp.test(commandType)) {
7864 parser.lines[lastLine] = parser.lines[lastLine].replace(ignoreRgxp, '');
7865 }
7866
7867 command = parser.replaceDangerBlocks(defDir ? command : command.replace(commandRgxp, ''));
7868
7869 parser.space = parser.prevSpace;
7870
7871 var inlineLength = parser.inline.length;
7872
7873 var fnRes = Snakeskin$1.Directives[commandType].call(parser, command, {
7874 length: commandLength,
7875 type: commandType,
7876 expr: commandExpr,
7877 raw: rawCommand.slice(0, -1),
7878 jsDoc: jsDocStart
7879 });
7880
7881 if (parser.break) {
7882 return false;
7883 }
7884
7885 if (parser.needPrfx && parser.needPrfx !== 1) {
7886 if (parser.getDirName(commandType) === 'end') {
7887 if (prfxI) {
7888 prfxI--;
7889
7890 if (!prfxI) {
7891 parser.needPrfx = false;
7892 }
7893 } else {
7894 parser.needPrfx = false;
7895 }
7896 } else if (inlineLength === parser.inline.length && !prfxI) {
7897 parser.needPrfx = false;
7898 } else if (parser.inline.length > inlineLength) {
7899 prfxI++;
7900 }
7901 }
7902
7903 if (parser.text && !parser.strongSpace[parser.strongSpace.length - 1]) {
7904 parser.sysSpace = false;
7905 parser.space = parser.prevSpace = false;
7906 }
7907
7908 jsDocStart = false;
7909 parser.text = false;
7910
7911 if (fnRes === false) {
7912 begin = 0;
7913 beginStr = false;
7914 }
7915
7916 command = '';
7917 rawCommand = '';
7918 commandLength = 0;
7919 continue;
7920 }
7921 }
7922 }
7923 }
7924
7925 // Working with a directive
7926 if (begin) {
7927 if (beginStr && parser.isSimpleOutput()) {
7928 parser.save('\'' + parser.$$() + ';');
7929 beginStr = false;
7930 }
7931
7932 if (!i18nStart) {
7933 if (!bOpen) {
7934 var skip = false;
7935 if (el === FILTER && filterStart.test(next)) {
7936 filterStart$$1 = true;
7937 bEnd$$1 = false;
7938 skip = true;
7939 } else if (filterStart$$1 && ws$1.test(el)) {
7940 filterStart$$1 = false;
7941 bEnd$$1 = true;
7942 skip = true;
7943 }
7944
7945 if (!skip) {
7946 if (ESCAPES_END[el] || ESCAPES_END_WORD[rPart] || commandNameDecl && ws$1.test(el) && Snakeskin$1.Directives[command.trim()]) {
7947 commandNameDecl = false;
7948 bEnd$$1 = true;
7949 rPart = '';
7950 } else if (bEnd.test(el)) {
7951 bEnd$$1 = false;
7952 }
7953
7954 if (sysWord.test(el)) {
7955 part += el;
7956 } else {
7957 rPart = part;
7958 part = '';
7959 }
7960 }
7961 }
7962
7963 if (ESCAPES[el] && !bOpen && !cEscape && (el !== '/' || bEnd$$1 && command)) {
7964 bOpen = el;
7965 } else if (bOpen && (el === '\\' || bEscape)) {
7966 bEscape = !bEscape;
7967 } else if (ESCAPES[el] && bOpen === el && !bEscape) {
7968 bOpen = false;
7969 bEnd$$1 = false;
7970 }
7971 }
7972
7973 command += el;
7974 commandLength++;
7975
7976 // Plain text
7977 } else {
7978 if (jsDoc) {
7979 parser.save(el, { raw: true });
7980 } else if (!parser.tplName) {
7981 if (el === ' ') {
7982 continue;
7983 }
7984
7985 // Convert Jade-Like to classic
7986 if (cClrL && (SHORTS[el] || SHORTS[substr2])) {
7987 var adv = parser.lines[lastLine].length - 1,
7988 source = parser.toBaseSyntax(parser.source, parser.i - adv);
7989
7990 if (source.error) {
7991 return false;
7992 }
7993
7994 parser.source = parser.source.slice(0, parser.i - adv) + source.code + parser.source.slice(parser.i + source.length - adv);
7995
7996 parser.lines[lastLine] = parser.lines[lastLine].slice(0, -1);
7997 parser.i--;
7998 continue;
7999 }
8000
8001 parser.error('text can\'t be used in the global space');
8002 return false;
8003 } else {
8004 if (structure.chain && !$dirParents[structure.name]['text']) {
8005 if (el === ' ') {
8006 parser.space = false;
8007 continue;
8008 }
8009
8010 parser.error('text can\'t be used within the "' + structure.name + '"');
8011 return false;
8012 }
8013
8014 parser.startInlineDir('text');
8015 if (parser.isSimpleOutput()) {
8016 if (!beginStr) {
8017 parser.save(parser.$() + '\'');
8018 beginStr = true;
8019 }
8020
8021 parser.save(applyDefEscape(el), { raw: true });
8022 }
8023
8024 parser.inline.pop();
8025 parser.structure = parser.structure.parent;
8026 }
8027
8028 if (jsDoc && !beginStr) {
8029 jsDoc = false;
8030 parser.space = true;
8031 }
8032 }
8033 }
8034
8035 // If we have some unclosed directives,
8036 // then will be thrown an exception
8037 if (begin || parser.structure.parent) {
8038 parser.error('missing closing or opening directives in the template');
8039 return false;
8040 }
8041
8042 // If we have some outer declarations,
8043 // which weren't attached to template,
8044 // then will be thrown an exception
8045 for (var key in parser.preDefs) {
8046 if (!parser.preDefs.hasOwnProperty(key)) {
8047 break;
8048 }
8049
8050 parser.error('the template "' + key + '" is not defined');
8051 return false;
8052 }
8053
8054 // Attach a compilation label
8055 parser.end(cacheKey, label);
8056
8057 // Beautify
8058 if (p.prettyPrint) {
8059 parser.result = beautify(parser.result);
8060 parser.result = parser.result.replace(new RegExp(eol.source, 'g'), any(p.eol));
8061 }
8062
8063 // Line feed
8064 parser.result += p.eol;
8065
8066 if (p.babel) {
8067 var babel = require('babel-core');
8068 parser.result = babel.transform(parser.result, p.babel).code;
8069 }
8070
8071 // Save some debug information
8072 if (p.debug) {
8073 p.debug.code = parser.result;
8074 p.debug.files = parser.files;
8075 }
8076
8077 if (compile(text, p, info, cacheKey, ctx, parser)) {
8078 return false;
8079 }
8080
8081 saveIntoCache(cacheKey, text, p, parser);
8082 return parser.result;
8083};
8084
8085function mtime(file) {
8086 var fs = require('fs');
8087
8088 try {
8089 return fs.statSync(file).mtime.valueOf();
8090 } catch (ignore) {
8091 return '';
8092 }
8093}
8094
8095function compile(text, p, info, cacheKey, ctx, parser) {
8096 try {
8097 if (parser.module !== 'native') {
8098 // Server compilation
8099 if (IS_NODE) {
8100 var env = parser.environment;
8101
8102 if (ctx !== NULL) {
8103 Function('Snakeskin', 'module', 'exports', 'require', '__dirname', '__filename', parser.result)(Snakeskin$1, {
8104 children: [],
8105 exports: ctx,
8106 filename: env.filename,
8107 id: env.filename,
8108 loaded: true,
8109 parent: env.module,
8110 require: env.require
8111 }, ctx, env.require, env.dirname, env.filename);
8112 }
8113
8114 // CommonJS compiling in a browser
8115 } else if (ctx !== NULL) {
8116 Function('Snakeskin', 'module', 'exports', 'global', parser.result)(Snakeskin$1, { exports: ctx }, ctx, GLOBAL);
8117
8118 // Compiling in a browser
8119 } else {
8120 Function('Snakeskin', parser.result).call(ROOT, Snakeskin$1);
8121 }
8122 }
8123
8124 saveIntoFnCache(cacheKey, text, p, ctx);
8125 } catch (err) {
8126 delete info.line;
8127 delete info.template;
8128 parser.error(err.message);
8129 return true;
8130 }
8131}
8132
8133Snakeskin$1.addDirective('__setError__', {
8134 group: 'ignore'
8135}, function (command) {
8136 this.error(this.pasteDangerBlocks(command));
8137});
8138
8139Snakeskin$1.addDirective('__appendLine__', {
8140 deferInit: true,
8141 group: 'ignore',
8142 placement: 'template'
8143}, function (command) {
8144 this.startInlineDir('cdata').isSimpleOutput();
8145
8146 var val = parseInt(command, 10);
8147 this.info.line += val;
8148
8149 for (var i = 0; i < val; i++) {
8150 this.lines[this.info.line + i] = '';
8151 }
8152});
8153
8154Snakeskin$1.addDirective('__setLine__', {
8155 group: 'ignore'
8156}, function (command) {
8157 if (this.freezeLine) {
8158 return;
8159 }
8160
8161 this.info.line = parseInt(command, 10);
8162});
8163
8164Snakeskin$1.addDirective('__cutLine__', {
8165 group: 'ignore'
8166}, function () {
8167 if (this.freezeLine) {
8168 return;
8169 }
8170
8171 this.lines.pop();
8172 this.info.line--;
8173});
8174
8175Snakeskin$1.addDirective('__switchLine__', {
8176 deferInit: true,
8177 group: 'ignore'
8178}, function (command) {
8179 this.startDir(null, {
8180 line: this.info.line
8181 });
8182
8183 if (this.freezeLine) {
8184 return;
8185 }
8186
8187 this.info.line = parseInt(command, 10);
8188}, function () {
8189 if (this.freezeLine) {
8190 return;
8191 }
8192
8193 var length = this.info.line = this.structure.params.line;
8194
8195 for (var i = this.lines.length; i < length; i++) {
8196 this.lines.push('');
8197 }
8198});
8199
8200Snakeskin$1.addDirective('set', {
8201 group: 'set',
8202 notEmpty: true,
8203 placement: 'global',
8204 shorthands: {
8205 '@=': 'set '
8206 }
8207}, set$1);
8208
8209Snakeskin$1.addDirective('__set__', {
8210 group: 'ignore',
8211 notEmpty: true
8212}, set$1);
8213
8214function set$1(command) {
8215 var _this = this;
8216
8217 var tplName = this.tplName,
8218 file = this.info.file,
8219 _params = slicedToArray(this.params, 1),
8220 root = _params[0],
8221 last = this.params[this.params.length - 1];
8222
8223 /**
8224 * @param {!Object} a
8225 * @param {!Object} b
8226 * @return {!Object}
8227 */
8228
8229
8230 function extend(a, b) {
8231 for (var key in b) {
8232 if (!b.hasOwnProperty(key)) {
8233 break;
8234 }
8235
8236 var aVal = a[key],
8237 bVal = b[key];
8238
8239 if (aVal && bVal && aVal.constructor === Object && bVal.constructor === Object) {
8240 extend(aVal, bVal);
8241 } else {
8242 a[key] = bVal;
8243 }
8244 }
8245
8246 return a;
8247 }
8248
8249 function mix(base, opt_adv, opt_initial) {
8250 return extend(Object.assign(opt_initial || {}, opt_adv), base);
8251 }
8252
8253 var init = false,
8254 params = last,
8255 parentCache = void 0,
8256 cache = void 0;
8257
8258 if (tplName) {
8259 cache = $output[tplName].flags = $output[tplName].flags || {};
8260 if (this.parentTplName) {
8261 parentCache = $output[this.parentTplName] && $output[this.parentTplName].flags;
8262 }
8263 }
8264
8265 if (last['@root'] || file && last['@file'] !== file || tplName && last['@tplName'] !== tplName) {
8266 init = true;
8267 params = {
8268 '@file': file,
8269 '@tplName': tplName
8270 };
8271
8272 var inherit = function inherit(obj) {
8273 for (var key in obj) {
8274 if (!obj.hasOwnProperty(key)) {
8275 break;
8276 }
8277
8278 if (key[0] !== '@' && key in root) {
8279 params[key] = _this[key] = obj[key];
8280
8281 if (cache) {
8282 cache[key] = obj[key];
8283 }
8284 }
8285 }
8286 };
8287
8288 inherit(last);
8289 if (parentCache) {
8290 inherit(parentCache);
8291 }
8292
8293 this.params.push(params);
8294 }
8295
8296 var flag = void 0,
8297 value = void 0;
8298
8299 if (isArray(command)) {
8300 var _command = slicedToArray(command, 2);
8301
8302 flag = _command[0];
8303 value = _command[1];
8304 } else {
8305 var parts = command.split(' ');
8306
8307 var _parts = slicedToArray(parts, 1);
8308
8309 flag = _parts[0];
8310
8311
8312 try {
8313 value = this.returnEvalVal(this.out(parts.slice(1).join(' '), { unsafe: true }));
8314 } catch (err) {
8315 return this.error(err.message);
8316 }
8317 }
8318
8319 if (flag in root) {
8320 if (flag === 'language') {
8321 value = mix(toObj(value, file, function (src) {
8322 var root = _this.environment.root || _this.environment;
8323 root.key.push([src, require('fs').statSync(src).mtime.valueOf()]);
8324 _this.files[src] = true;
8325 }), init ? params[flag] : null, init ? null : params[flag]);
8326 }
8327
8328 switch (flag) {
8329 case 'filters':
8330 value = this.appendDefaultFilters(value);
8331 break;
8332
8333 case 'language':
8334 value = mix(toObj(value, file, function (src) {
8335 var root = _this.environment.root || _this.environment;
8336 root.key.push([src, require('fs').statSync(src).mtime.valueOf()]);
8337 _this.files[src] = true;
8338 }), init ? params[flag] : null, init ? null : params[flag]);
8339
8340 break;
8341 }
8342
8343 params[flag] = this[flag] = value;
8344
8345 if (cache) {
8346 cache[flag] = value;
8347 }
8348 } else if (flag[0] !== '@') {
8349 return this.error('unknown compiler flag "' + flag + '"');
8350 }
8351}
8352
8353var _templateObject$5 = taggedTemplateLiteral(['\n\t\t\t\t\tif (__RETURN__) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t'], ['\n\t\t\t\t\tif (__RETURN__) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t']);
8354var _templateObject2$3 = taggedTemplateLiteral(['\n\t\t\t\t\t\t\tif (__RETURN__) {\n\t\t\t\t\t\t\t\treturn arguments[arguments.length - 1](__RETURN_VAL__);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t'], ['\n\t\t\t\t\t\t\tif (__RETURN__) {\n\t\t\t\t\t\t\t\treturn arguments[arguments.length - 1](__RETURN_VAL__);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t']);
8355var _templateObject3$3 = taggedTemplateLiteral(['\n\t\t\t\t\t\t\tif (__RETURN__) {\n\t\t\t\t\t\t\t\tif (typeof arguments[0] === \'function\') {\n\t\t\t\t\t\t\t\t\treturn arguments[0](__RETURN_VAL__);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t'], ['\n\t\t\t\t\t\t\tif (__RETURN__) {\n\t\t\t\t\t\t\t\tif (typeof arguments[0] === \'function\') {\n\t\t\t\t\t\t\t\t\treturn arguments[0](__RETURN_VAL__);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t']);
8356var _templateObject4$2 = taggedTemplateLiteral(['\n\t\t\t\t\tif (__RETURN__) {\n\t\t\t\t\t\treturn __RETURN_VAL__;\n\t\t\t\t\t}\n\t\t\t\t'], ['\n\t\t\t\t\tif (__RETURN__) {\n\t\t\t\t\t\treturn __RETURN_VAL__;\n\t\t\t\t\t}\n\t\t\t\t']);
8357
8358Snakeskin$1.addDirective('end', {
8359 deferInit: true,
8360 group: 'end',
8361 shorthands: { '/': 'end ' }
8362}, function (command) {
8363 var _Snakeskin$Directives,
8364 _this = this;
8365
8366 var structure = this.structure,
8367 name = this.structure.name;
8368
8369
8370 if (!structure.parent) {
8371 return this.error('invalid call "end"');
8372 }
8373
8374 if (command && command !== name) {
8375 var group = this.getGroup('rootTemplate');
8376 if (!this.renderAs || !group[name] || !group[command]) {
8377 return this.error('invalid closing directive, expected: "' + name + '", declared: "' + command + '"');
8378 }
8379 }
8380
8381 if (this.deferReturn) {
8382 var _name = this.structure.name;
8383
8384
8385 var async = this.getGroup('async'),
8386 isCallback = this.getGroup('func')[_name];
8387
8388 var closest = void 0,
8389 asyncParent = void 0;
8390
8391 if (isCallback) {
8392 closest = any(this.getNonLogicParent()).name, asyncParent = async[closest];
8393 }
8394
8395 if (this.getGroup('function', 'async')[_name] && (isCallback && asyncParent || !isCallback)) {
8396 var def = ws(_templateObject$5);
8397
8398 if (isCallback || async[_name]) {
8399 this.deferReturn = 0;
8400 }
8401
8402 if (isCallback) {
8403 if (this.getGroup('waterfall')[closest]) {
8404 this.append(ws(_templateObject2$3));
8405 } else if (this.getGroup('Async')[closest]) {
8406 this.append(ws(_templateObject3$3));
8407 } else {
8408 this.append(def);
8409 }
8410 } else if (async[_name]) {
8411 this.append(def);
8412 } else if (this.deferReturn) {
8413 if (this.deferReturn > 1) {
8414 this.append(def);
8415 }
8416
8417 this.deferReturn++;
8418 }
8419 } else {
8420 this.append(ws(_templateObject4$2));
8421
8422 this.deferReturn = 0;
8423 }
8424 }
8425
8426 var destruct = Snakeskin$1.Directives[name + 'End'];
8427
8428 if (destruct) {
8429 destruct.call.apply(destruct, [this].concat(Array.prototype.slice.call(arguments)));
8430 } else if (!structure.logic) {
8431 this.append('};');
8432 }
8433
8434 (_Snakeskin$Directives = Snakeskin$1.Directives[name + 'BaseEnd']).call.apply(_Snakeskin$Directives, [this].concat(Array.prototype.slice.call(arguments)));
8435
8436 this.endDir().toQueue(function () {
8437 return _this.startInlineDir();
8438 });
8439});
8440
8441Snakeskin$1.addDirective('__end__', {
8442 alias: true,
8443 deferInit: true,
8444 group: 'ignore'
8445}, function () {
8446 var _Snakeskin$Directives2;
8447
8448 (_Snakeskin$Directives2 = Snakeskin$1.Directives['end']).call.apply(_Snakeskin$Directives2, [this].concat(Array.prototype.slice.call(arguments)));
8449});
8450
8451Snakeskin$1.addDirective('void', {
8452 group: 'void',
8453 notEmpty: true,
8454 shorthands: { '?': 'void ' }
8455}, function (command) {
8456 this.append(this.out(command, { unsafe: true }) + ';');
8457});
8458
8459Snakeskin$1.addDirective('if', {
8460 block: true,
8461 group: ['if', 'logic'],
8462 notEmpty: true
8463}, function (command) {
8464 this.append('if (' + this.out(command, { unsafe: true }) + ') {');
8465}, function () {
8466 this.append('}');
8467});
8468
8469Snakeskin$1.addDirective('unless', {
8470 block: true,
8471 group: ['unless', 'if', 'logic'],
8472 notEmpty: true
8473}, function (command) {
8474 this.append('if (!(' + this.out(command, { unsafe: true }) + ')) {');
8475}, function () {
8476 this.append('}');
8477});
8478
8479Snakeskin$1.addDirective('else', {
8480 group: ['else', 'logic'],
8481 with: Snakeskin$1.group('if')
8482}, function (command) {
8483 // else if OR else unless
8484 if (command) {
8485 var parts = command.split(' '),
8486 prfx = parts[0] === 'unless' ? '!' : '';
8487
8488 if (this.getGroup('if')[parts[0]]) {
8489 parts.shift();
8490 }
8491
8492 this.append('} else if (' + prfx + '(' + this.out(parts.join(' '), { unsafe: true }) + ')) {');
8493 } else {
8494 this.append('} else {');
8495 }
8496});
8497
8498Snakeskin$1.addDirective('switch', {
8499 block: true,
8500 children: Snakeskin$1.group('case'),
8501 group: ['switch', 'logic'],
8502 notEmpty: true
8503}, function (command) {
8504 this.append('switch (' + this.out(command, { unsafe: true }) + ') {');
8505}, function () {
8506 this.append('}');
8507});
8508
8509Snakeskin$1.addDirective('case', {
8510 block: true,
8511 group: ['case', 'logic'],
8512 notEmpty: true,
8513 shorthands: { '/>': 'end case', '>': 'case ' }
8514}, function (command) {
8515 this.append('case ' + this.out(command, { unsafe: true }) + ': {');
8516}, function () {
8517 this.append('} break;');
8518});
8519
8520Snakeskin$1.addDirective('default', {
8521 block: true,
8522 group: ['case', 'logic']
8523}, function () {
8524 this.append('default: {');
8525}, function () {
8526 this.append('}');
8527});
8528
8529var _templateObject$6 = taggedTemplateLiteral(['\n\t\t\t\t', '\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t'], ['\n\t\t\t\t', '\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t']);
8530var _templateObject2$4 = taggedTemplateLiteral(['\n\t\t\t\tyield', ' ', ';\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t'], ['\n\t\t\t\tyield', ' ', ';\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t']);
8531var _templateObject3$4 = taggedTemplateLiteral(['\n\t\t\t\tif (__LENGTH__(__RESULT__)) {\n\t\t\t\t\tyield', ' ', ';\n\t\t\t\t\t__RESULT__ = ', ';\n\n\t\t\t\t} else {\n\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t\tyield', ' ', ';\n\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t}\n\t\t\t'], ['\n\t\t\t\tif (__LENGTH__(__RESULT__)) {\n\t\t\t\t\tyield', ' ', ';\n\t\t\t\t\t__RESULT__ = ', ';\n\n\t\t\t\t} else {\n\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t\tyield', ' ', ';\n\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t}\n\t\t\t']);
8532
8533Snakeskin$1.addDirective('yield', {
8534 ancestorsBlacklist: Snakeskin$1.group('function'),
8535 block: true,
8536 deferInit: true,
8537 generator: true,
8538 group: 'yield',
8539 placement: 'template'
8540}, function (command) {
8541 var prfx = '';
8542 if (command[0] === '*') {
8543 prfx = '*';
8544 command = command.slice(1);
8545 }
8546
8547 if (command.slice(-1) === '/') {
8548 this.startInlineDir(null, { command: command.slice(0, -1), prfx: prfx, short: true });
8549 return;
8550 }
8551
8552 this.startDir(null, { command: command, prfx: prfx });
8553
8554 if (!command) {
8555 this.append(ws(_templateObject$6, this.declVars('__CALL_CACHE__ = __RESULT__', { sys: true }), this.getResultDecl()));
8556 }
8557}, function () {
8558 var p = this.structure.params;
8559
8560 if (p.command) {
8561 this.append('yield' + p.prfx + ' ' + this.out(p.command, { unsafe: true }) + ';');
8562 } else if (p.short) {
8563 this.append(ws(_templateObject2$4, p.prfx, this.getReturnResultDecl(), this.getResultDecl()));
8564 } else {
8565 var tmp = this.getVar('__CALL_CACHE__');
8566
8567 this.append(ws(_templateObject3$4, p.prfx, this.getReturnResultDecl(), tmp, tmp, p.prfx, this.getReturnResultDecl(), this.getResultDecl()));
8568 }
8569});
8570
8571var _templateObject$7 = taggedTemplateLiteral(['\n\t\t\t\t', '\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t'], ['\n\t\t\t\t', '\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t']);
8572var _templateObject2$5 = taggedTemplateLiteral(['\n\t\t\t\tawait ', ';\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t'], ['\n\t\t\t\tawait ', ';\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t']);
8573var _templateObject3$5 = taggedTemplateLiteral(['\n\t\t\t\tif (__LENGTH__(__RESULT__)) {\n\t\t\t\t\tawait ', ';\n\t\t\t\t\t__RESULT__ = ', ';\n\n\t\t\t\t} else {\n\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t\tawait ', ';\n\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t}\n\t\t\t'], ['\n\t\t\t\tif (__LENGTH__(__RESULT__)) {\n\t\t\t\t\tawait ', ';\n\t\t\t\t\t__RESULT__ = ', ';\n\n\t\t\t\t} else {\n\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t\tawait ', ';\n\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t}\n\t\t\t']);
8574
8575Snakeskin$1.addDirective('await', {
8576 ancestorsBlacklist: Snakeskin$1.group('function'),
8577 async: true,
8578 block: true,
8579 deferInit: true,
8580 group: 'await',
8581 placement: 'template'
8582}, function (command) {
8583 if (command.slice(-1) === '/') {
8584 this.startInlineDir(null, { command: command.slice(0, -1), short: true });
8585 return;
8586 }
8587
8588 this.startDir(null, { command: command });
8589
8590 if (!command) {
8591 this.append(ws(_templateObject$7, this.declVars('__CALL_CACHE__ = __RESULT__', { sys: true }), this.getResultDecl()));
8592 }
8593}, function () {
8594 var p = this.structure.params;
8595
8596 if (p.command) {
8597 this.append('await ' + this.out(p.command, { unsafe: true }) + ';');
8598 } else if (p.short) {
8599 this.append(ws(_templateObject2$5, this.getReturnResultDecl(), this.getResultDecl()));
8600 } else {
8601 var tmp = this.getVar('__CALL_CACHE__');
8602
8603 this.append(ws(_templateObject3$5, this.getReturnResultDecl(), tmp, tmp, this.getReturnResultDecl(), this.getResultDecl()));
8604 }
8605});
8606
8607Snakeskin$1.addDirective('throw', {
8608 group: ['throw', 'exception'],
8609 notEmpty: true
8610}, function (command) {
8611 this.append('throw ' + this.out(command, { unsafe: true }) + ';');
8612});
8613
8614Snakeskin$1.addDirective('try', {
8615 block: true,
8616 group: ['try', 'exception', 'dynamic']
8617}, function () {
8618 this.append('try {');
8619}, function () {
8620 if (this.structure.params.chain) {
8621 this.append('}');
8622 } else {
8623 this.append('} catch (ignore) {}');
8624 }
8625});
8626
8627Snakeskin$1.addDirective('catch', {
8628 group: ['catch', 'exception', 'dynamic'],
8629 notEmpty: true,
8630 with: Snakeskin$1.group('try')
8631}, function (command) {
8632 this.structure.params.chain = true;
8633 this.append('} catch (' + this.declVar(command) + ') {');
8634});
8635
8636Snakeskin$1.addDirective('finally', {
8637 group: ['finally', 'exception'],
8638 with: Snakeskin$1.group('try')
8639}, function () {
8640 this.structure.params.chain = true;
8641 this.append('} finally {');
8642});
8643
8644Snakeskin$1.addDirective('var', {
8645 block: true,
8646 deferInit: true,
8647 group: 'var',
8648 notEmpty: true,
8649 shorthands: { ':': 'var ' }
8650}, function (command) {
8651 var putIn = /^putIn\s+([^\s=,]+)$/.exec(command);
8652
8653 if (putIn) {
8654 this.append(this.declVars(putIn[1]));
8655 Snakeskin$1.Directives['putIn'].call(this, putIn[1]);
8656 } else {
8657 var short = command.slice(-1) === '/';
8658
8659 if (short) {
8660 command = command.slice(0, -1);
8661 }
8662
8663 this.append(this.declVars(command));
8664
8665 if (short) {
8666 this.startInlineDir();
8667 } else {
8668 this.startDir();
8669 }
8670 }
8671}, function () {});
8672
8673Snakeskin$1.addDirective('with', {
8674 block: true,
8675 group: 'with',
8676 logic: true,
8677 notEmpty: true
8678}, function (command) {
8679 this.scope.push(this.out(command, { unsafe: true }));
8680}, function () {
8681 this.scope.pop();
8682});
8683
8684Snakeskin$1.addDirective('head', {
8685 block: true,
8686 group: ['head', 'define'],
8687 logic: true,
8688 placement: 'global'
8689});
8690
8691Snakeskin$1.addDirective('eval', {
8692 block: true,
8693 deferInit: true,
8694 group: 'eval',
8695 logic: true,
8696 placement: 'global'
8697}, function () {
8698 this.startDir(null, {
8699 from: this.result.length
8700 });
8701}, function () {
8702 var p = this.structure.params;
8703 p['@result'] = this.result;
8704 this.result = this.result.slice(0, p.from);
8705});
8706
8707Snakeskin$1.addDirective('ignoreWhitespaces', {
8708 group: ['ignoreWhitespaces', 'space'],
8709 placement: 'template',
8710 shorthands: { '&': 'ignoreWhitespaces ' }
8711}, function () {
8712 this.space = true;
8713 this.prevSpace = true;
8714});
8715
8716Snakeskin$1.addDirective('ignoreAllWhitespaces', {
8717 block: true,
8718 group: ['ignoreAllWhitespaces', 'space'],
8719 placement: 'template',
8720 shorthands: { '&+': 'ignoreAllWhitespaces ' }
8721}, function () {
8722 this.strongSpace.push(true);
8723}, function () {
8724 this.strongSpace.pop();
8725 this.sysSpace = Number(this.sysSpace);
8726});
8727
8728Snakeskin$1.addDirective('unIgnoreAllWhitespaces', {
8729 block: true,
8730 group: ['unIgnoreAllWhitespaces', 'space'],
8731 placement: 'template',
8732 shorthands: { '&-': 'unIgnoreAllWhitespaces ' }
8733}, function () {
8734 this.strongSpace.push(false);
8735}, function () {
8736 this.strongSpace.pop();
8737 this.sysSpace = Number(this.sysSpace);
8738});
8739
8740Snakeskin$1.addDirective('sp', {
8741 group: ['sp', 'space'],
8742 shorthands: { '\\': 'sp ' },
8743 text: true
8744});
8745
8746Snakeskin$1.addDirective('__sp__', {
8747 group: 'ignore',
8748 text: true
8749});
8750
8751Snakeskin$1.addDirective('__&+__', {
8752 group: 'ignore'
8753}, function () {
8754 if (this.tolerateWhitespaces) {
8755 return;
8756 }
8757
8758 this.sysSpace = true;
8759});
8760
8761Snakeskin$1.addDirective('__&-__', {
8762 group: 'ignore'
8763}, function () {
8764 if (this.tolerateWhitespaces) {
8765 return;
8766 }
8767
8768 if (this.sysSpace === 1) {
8769 this.space = false;
8770 }
8771
8772 this.sysSpace = false;
8773});
8774
8775Snakeskin$1.addDirective('const', {
8776 deferInit: true,
8777 group: ['const', 'inherit', 'inlineInherit']
8778}, function (command, _ref) {
8779 var length = _ref.length;
8780 var tplName = this.tplName;
8781
8782
8783 if (!tplName) {
8784 var _Snakeskin$Directives;
8785
8786 (_Snakeskin$Directives = Snakeskin$1.Directives['global']).call.apply(_Snakeskin$Directives, [this].concat(Array.prototype.slice.call(arguments)));
8787 return;
8788 }
8789
8790 var output = command.slice(-1) === '?';
8791
8792 if (output) {
8793 command = command.slice(0, -1);
8794 }
8795
8796 var parts = command.split('=');
8797
8798 if (!parts[1] || !parts[1].trim()) {
8799 return this.error('invalid "' + this.name + '" declaration');
8800 }
8801
8802 var prop = parts[0].trim();
8803
8804 if (scopeMod.test(prop)) {
8805 prop = this.out(prop, { unsafe: true });
8806 }
8807
8808 var name = this.pasteDangerBlocks(prop).replace(/\[(['"`])(.*?)\1]/g, '.$2');
8809
8810 this.startInlineDir(null, { name: name });
8811
8812 if (!this.outerLink && !/[.\[]/.test(prop)) {
8813 this.consts.push('var ' + prop + ';');
8814 }
8815
8816 var str = prop + ' = ' + this.out(parts.slice(1).join('='), { unsafe: !output });
8817
8818 this.text = output;
8819 this.append(output ? this.wrap(str) : str + ';');
8820
8821 if (this.isAdvTest()) {
8822 if ($consts[tplName][name]) {
8823 return this.error('the constant "' + name + '" is already defined');
8824 }
8825
8826 if (this.vars[tplName][name]) {
8827 return this.error('the constant "' + name + '" is already defined as variable');
8828 }
8829
8830 if (SYS_CONSTS[name] || escaperPart.test(name)) {
8831 return this.error('can\'t declare the constant "' + name + '", try another name');
8832 }
8833
8834 var parentTpl = this.parentTplName,
8835 start = this.i - this.startTemplateI,
8836 block = this.hasParent(this.getGroup('dynamic'));
8837
8838 var parent = void 0;
8839 if (parentTpl) {
8840 parent = $consts[parentTpl][name];
8841 }
8842
8843 $consts[tplName][name] = {
8844 block: Boolean(block || parentTpl && parent && parent.block),
8845 from: start - length,
8846 needPrfx: this.needPrfx,
8847 output: output ? '?' : null,
8848 to: start
8849 };
8850
8851 if (!block) {
8852 $constPositions[tplName] = start + 1;
8853 }
8854 }
8855});
8856
8857Snakeskin$1.addDirective('global', {
8858 group: ['global', 'var', 'output'],
8859 notEmpty: true
8860}, function (command) {
8861 var output = command.slice(-1) === '?';
8862
8863 if (output) {
8864 command = command.slice(0, -1);
8865 }
8866
8867 var desc = isAssignExpression(command, true);
8868
8869 if ((!desc || output) && !this.tplName) {
8870 return this.error('invalid "' + this.name + '" declaration');
8871 }
8872
8873 if (output) {
8874 this.text = true;
8875 this.append(this.wrap(this.out(desc.key, { unsafe: true }) + ' = ' + this.out(desc.value)));
8876 } else {
8877 var mod = G_MOD + G_MOD;
8878
8879 if (command[0] !== G_MOD) {
8880 command = mod + command;
8881 } else {
8882 command = command.replace(scopeMod, mod);
8883 }
8884
8885 this.save(this.out(command, { unsafe: true }) + ';');
8886 }
8887});
8888
8889Snakeskin$1.addDirective('output', {
8890 group: 'output',
8891 placement: 'template',
8892 text: true
8893}, function (command) {
8894 this.append(this.wrap(this.out(command)));
8895});
8896
8897var _templateObject$8 = taggedTemplateLiteral(['\n\t\t\t\t', '\n\t\t\t\t__STRING_RESULT__ = \'\';\n\t\t\t'], ['\n\t\t\t\t', '\n\t\t\t\t__STRING_RESULT__ = \'\';\n\t\t\t']);
8898
8899Snakeskin$1.addDirective('comment', {
8900 block: true,
8901 deferInit: true,
8902 group: ['comment', 'tag', 'output'],
8903 interpolation: true,
8904 placement: 'template',
8905 selfInclude: false,
8906 shorthands: { '/!': 'end comment', '<!': 'comment ' }
8907}, function (condition) {
8908 this.startDir(null, { condition: condition });
8909
8910 var str = void 0;
8911 if (!stringRender[this.renderMode]) {
8912 if (!this.stringResult) {
8913 this.stringResult = this.structure.params.stringResult = true;
8914 }
8915
8916 str = '__STRING_RESULT__ = \'\';';
8917 } else {
8918 str = this.wrap('\'<!--\'');
8919 }
8920
8921 if (condition) {
8922 str += this.wrap('\'[if ' + this.replaceTplVars(condition) + ']>\'');
8923 }
8924
8925 this.append(str);
8926}, function () {
8927 var p = this.structure.params,
8928 end = p.condition ? ' <![endif]' : '';
8929
8930 var str = void 0;
8931 if (!stringRender[this.renderMode]) {
8932 str = this.wrap('\'' + end + '\'');
8933
8934 if (p.stringResult) {
8935 this.stringResult = false;
8936 }
8937
8938 str += ws(_templateObject$8, this.wrap('new Snakeskin.Comment(__STRING_RESULT__, \'' + this.renderMode + '\')'));
8939 } else {
8940 str = this.wrap('\'' + end + '-->\'');
8941 }
8942
8943 this.append(str);
8944});
8945
8946var types = {
8947 '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" ' + '"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
8948
8949 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" ' + '"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
8950
8951 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" ' + '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
8952
8953 'html': '<!DOCTYPE html>',
8954 'mathml 1.0': '<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">',
8955 'mathml 2.0': '<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">',
8956
8957 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" ' + '"http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">',
8958
8959 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' + '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
8960
8961 'svg 1.0': '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" ' + '"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">',
8962
8963 'svg 1.1 basic': '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" ' + '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">',
8964
8965 'svg 1.1 full': '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ' + '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
8966
8967 'svg 1.1 tiny': '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" ' + '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">',
8968
8969 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ' + '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
8970
8971 'xml': '<?xml version="1.0" encoding="utf-8" ?>'
8972};
8973
8974Snakeskin$1.addDirective('doctype', {
8975 group: ['doctype', 'output'],
8976 placement: 'template',
8977 renderModesWhitelist: ['stringConcat', 'stringBuffer']
8978}, function (command) {
8979 command = (command || 'html').toLowerCase();
8980
8981 var type = types[command] || '';
8982
8983 if (!type) {
8984 return this.error('invalid doctype');
8985 }
8986
8987 this.doctype = command !== 'html' ? 'xml' : type;
8988 this.append(this.out('__INLINE_TAGS__ = Snakeskin.inlineTags[\'' + command + '\'] || Snakeskin.inlineTags[\'html\'];', { unsafe: true }) + this.wrap('\'' + type + '\''));
8989});
8990
8991Snakeskin$1.addDirective('namespace', {
8992 deferInit: true,
8993 group: 'namespace',
8994 notEmpty: true,
8995 placement: 'global'
8996}, function (nms) {
8997 if (this.namespace) {
8998 return this.error('namespace can be set only once for a file');
8999 }
9000
9001 this.environment.namespace = nms = this.getBlockName(nms);
9002
9003 if (this.namespaces[nms]) {
9004 this.namespaces[nms].files.push(this.info.file);
9005 } else {
9006 this.namespaces[nms] = { files: [this.info.file] };
9007 }
9008
9009 this.scope.push('exports' + concatProp(nms));
9010});
9011
9012Snakeskin$1.addDirective('decorator', {
9013 group: 'decorator',
9014 notEmpty: true,
9015 placement: 'global'
9016}, function (command) {
9017 this.decorators.push(this.out(command, { unsafe: true }));
9018});
9019
9020var _templateObject$9 = taggedTemplateLiteral(['[\'', '\']'], ['[\'', '\']']);
9021var _templateObject2$6 = taggedTemplateLiteral(['\n\t\t\t\t\t\tif (', ' instanceof Object === false) {\n\t\t\t\t\t\t\t', ' = {};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t', '\n\t\t\t\t\t'], ['\n\t\t\t\t\t\tif (', ' instanceof Object === false) {\n\t\t\t\t\t\t\t', ' = {};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t', '\n\t\t\t\t\t']);
9022var _templateObject3$6 = taggedTemplateLiteral(['\n\t\t\t\t\texports', ' =\n\t\t\t\t\t\tSnakeskin.decorate([\n\t\t\t\t\t\t\t', '],\n\t\t\t\t\t\t\t', ' function ', '', '('], ['\n\t\t\t\t\texports', ' =\n\t\t\t\t\t\tSnakeskin.decorate([\n\t\t\t\t\t\t\t', '],\n\t\t\t\t\t\t\t', ' function ', '', '(']);
9023var _templateObject4$3 = taggedTemplateLiteral(['\n\t\t\t\tvar\n\t\t\t\t\t__THIS__ = this;\n\n\t\t\t\tvar\n\t\t\t\t\tcallee = exports', ',\n\t\t\t\t\tself = callee.Blocks = {};\n\n\t\t\t\tvar\n\t\t\t\t\t__INLINE_TAGS__ = Snakeskin.inlineTags[\'', '\'] || Snakeskin.inlineTags[\'html\'],\n\t\t\t\t\t__INLINE_TAG__;\n\n\t\t\t\tvar\n\t\t\t\t\t__STRING_RESULT__;\n\n\t\t\t\t', '\n\n\t\t\t\tvar\n\t\t\t\t\t$0 = ', ',\n\t\t\t\t\t$class,\n\t\t\t\t\t$tagName,\n\t\t\t\t\t$attrKey,\n\t\t\t\t\t$attrType,\n\t\t\t\t\t$attrs;\n\n\t\t\t\tvar\n\t\t\t\t\t__ATTR_STR__,\n\t\t\t\t\t__ATTR_CONCAT_MAP__ = {\'class\': true};\n\n\t\t\t\tfunction __GET_XML_ATTR_KEY_DECL__(val, cache, empty) {\n\t\t\t\t\tif (val != null && val !== \'\') {\n\t\t\t\t\t\tif (!__ATTR_CONCAT_MAP__[val] || !cache[val] || cache[val][0] === TRUE) {\n\t\t\t\t\t\t\tcache[val] = [];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcache[val].push(empty ? TRUE : __ATTR_STR__);\n\t\t\t\t\t}\n\n\t\t\t\t\t__ATTR_STR__ = $attrType = undefined;\n\t\t\t\t}\n\n\t\t\t\tfunction __APPEND_XML_ATTR_VAL__(val) {\n\t\t\t\t\t__ATTR_STR__ = __ATTR_STR__ + (__ATTR_STR__ ? \' \' : \'\') + (val != null ? val : \'\');\n\t\t\t\t}\n\n\t\t\t\tfunction __GET_XML_ATTRS_DECL_START__(res, link, renderMode, isDOMRenderMode, stringResult) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (!stringResult && isDOMRenderMode) {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\t$0 = new Snakeskin.Element(link, renderMode);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t__STRING_RESULT__ += \'<\' + link;\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __GET_XML_ATTRS_DECL_END__(res, link, cache, isDOMRenderMode, stringResult, isXMLDoctype, literalBounds) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (typeof link === \'undefined\' || link !== \'?\') {\n\t\t\t\t\t\tvar base = true;\n\t\t\t\t\t\tvar set = function (el, key) {\n\t\t\t\t\t\t\tif (!base && {\'class\': true, \'id\': true}[key]) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t\tattr = el[0] === TRUE ? isDOMRenderMode || isXMLDoctype ? key : TRUE : el.join(\' \'),\n\t\t\t\t\t\t\t\twrapper = literalBounds && attr !== TRUE && attr.slice(0, 2) === \'{{\' && attr.slice(-2) === \'}}\';\n\n\t\t\t\t\t\t\tif (!isDOMRenderMode) {\n\t\t\t\t\t\t\t\tif (attr === TRUE) {\n\t\t\t\t\t\t\t\t\tattr = \'\';\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tif (wrapper) {\n\t\t\t\t\t\t\t\t\t\tattr = \'=\' + literalBounds[0] + attr.slice(2, -2) + literalBounds[1];\n\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tattr = \'="\' + __ESCAPE_D_Q__(attr) + \'"\';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t__STRING_RESULT__ += \' \' + key + attr;\n\n\t\t\t\t\t\t\t} else if (isDOMRenderMode) {\n\t\t\t\t\t\t\t\tSnakeskin.setAttribute($0, key, attr);\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (cache[\'id\']) {\n\t\t\t\t\t\t\tset(cache[\'id\'], \'id\');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (cache[\'class\']) {\n\t\t\t\t\t\t\tset(cache[\'class\'], \'class\');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbase = false;\n\t\t\t\t\t\tSnakeskin.forEach(cache, set);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __GET_XML_TAG_DECL_END__(res, link, inline, inlineTag, isDOMRenderMode, stringResult, isXMLDoctype) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (isDOMRenderMode) {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\tif (inline && !inlineTag || inlineTag === true) {\n\t\t\t\t\t\t\t\t$0 = __RESULT__[__RESULT__.length - 1];\n\n\t\t\t\t\t\t\t} else if (inlineTag && inlineTag!== true) {\n\t\t\t\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t\t\t\t\t$0 = __RESULT__[__RESULT__.length - 1];\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t__RESULT__.push($0);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\tif (inline && !inlineTag || inlineTag === true) {\n\t\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t\t__STRING_RESULT__ += (isXMLDoctype ? \'/\' : \'\') + \'>\';\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else if (inlineTag && inlineTag !== true) {\n\t\t\t\t\t\t\t\t__RESULT__ = ', ';\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t\t__STRING_RESULT__ += \'>\';\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __GET_END_XML_TAG_DECL__(\n\t\t\t\t\tres,\n\t\t\t\t\tlink,\n\t\t\t\t\tinline,\n\t\t\t\t\tinlineTag,\n\t\t\t\t\tattrCache,\n\t\t\t\t\tcallCache,\n\t\t\t\t\tcallTmp,\n\t\t\t\t\tisDOMRenderMode,\n\t\t\t\t\tstringResult,\n\t\t\t\t\tisXMLDoctype,\n\t\t\t\t\tnode\n\n\t\t\t\t) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (isDOMRenderMode) {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\tif (inlineTag) {\n\t\t\t\t\t\t\t\tif (inlineTag !== true) {\n\t\t\t\t\t\t\t\t\t__RESULT__ = callCache;\n\t\t\t\t\t\t\t\t\tif (inlineTag in attrCache === false && callTmp) {\n\t\t\t\t\t\t\t\t\t\tSnakeskin.setAttribute(node, inlineTag, callTmp);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else if (!inline) {\n\t\t\t\t\t\t\t\t__RESULT__.pop();\n\t\t\t\t\t\t\t\t$0 = __RESULT__[__RESULT__.length - 1];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\tif (inlineTag) {\n\t\t\t\t\t\t\t\tif (inlineTag !== true) {\n\t\t\t\t\t\t\t\t\t__RESULT__ = callCache;\n\n\t\t\t\t\t\t\t\t\tif (inlineTag in attrCache === false && callTmp) {\n\t\t\t\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t\t\t\t__STRING_RESULT__ += \' \' + inlineTag + \'="\' + callTmp + \'"\';\n\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t\t\t__STRING_RESULT__ += (isXMLDoctype ? \'/\' : \'\') + \'>\';\n\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else if (!inline) {\n\t\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t\t__STRING_RESULT__ += \'</\' + link + \'>\';\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __TARGET_END__(res, stack, ref) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (__LENGTH__(__RESULT__)) {\n\t\t\t\t\t\tstack.push({\n\t\t\t\t\t\t\tkey: undefined,\n\t\t\t\t\t\t\tvalue: Unsafe(', ')\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tSnakeskin.forEach(stack, function (el) {\n\t\t\t\t\t\tref[el.key || ref.length] = el.value;\n\t\t\t\t\t});\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __PUTIN_CALL__(res, pos, stack) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (pos === true || !pos && __LENGTH__(__RESULT__)) {\n\t\t\t\t\t\tstack.push(Unsafe(', '));\n\t\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __PUTIN_TARGET__(res, pos, stack, key) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (pos === true || !pos && __LENGTH__(__RESULT__)) {\n\t\t\t\t\t\tstack.push({\n\t\t\t\t\t\t\tkey: key,\n\t\t\t\t\t\t\tvalue: Unsafe(', ')\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tvar\n\t\t\t\t\t__RETURN__ = false,\n\t\t\t\t\t__RETURN_VAL__;\n\n\t\t\t\tvar\n\t\t\t\t\tTPL_NAME = "', '",\n\t\t\t\t\tPARENT_TPL_NAME', ',\n\t\t\t\t\tEOL = "', '";\n\n\t\t\t\t', '\n\t\t\t'], ['\n\t\t\t\tvar\n\t\t\t\t\t__THIS__ = this;\n\n\t\t\t\tvar\n\t\t\t\t\tcallee = exports', ',\n\t\t\t\t\tself = callee.Blocks = {};\n\n\t\t\t\tvar\n\t\t\t\t\t__INLINE_TAGS__ = Snakeskin.inlineTags[\'', '\'] || Snakeskin.inlineTags[\'html\'],\n\t\t\t\t\t__INLINE_TAG__;\n\n\t\t\t\tvar\n\t\t\t\t\t__STRING_RESULT__;\n\n\t\t\t\t', '\n\n\t\t\t\tvar\n\t\t\t\t\t$0 = ', ',\n\t\t\t\t\t$class,\n\t\t\t\t\t$tagName,\n\t\t\t\t\t$attrKey,\n\t\t\t\t\t$attrType,\n\t\t\t\t\t$attrs;\n\n\t\t\t\tvar\n\t\t\t\t\t__ATTR_STR__,\n\t\t\t\t\t__ATTR_CONCAT_MAP__ = {\'class\': true};\n\n\t\t\t\tfunction __GET_XML_ATTR_KEY_DECL__(val, cache, empty) {\n\t\t\t\t\tif (val != null && val !== \'\') {\n\t\t\t\t\t\tif (!__ATTR_CONCAT_MAP__[val] || !cache[val] || cache[val][0] === TRUE) {\n\t\t\t\t\t\t\tcache[val] = [];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcache[val].push(empty ? TRUE : __ATTR_STR__);\n\t\t\t\t\t}\n\n\t\t\t\t\t__ATTR_STR__ = $attrType = undefined;\n\t\t\t\t}\n\n\t\t\t\tfunction __APPEND_XML_ATTR_VAL__(val) {\n\t\t\t\t\t__ATTR_STR__ = __ATTR_STR__ + (__ATTR_STR__ ? \' \' : \'\') + (val != null ? val : \'\');\n\t\t\t\t}\n\n\t\t\t\tfunction __GET_XML_ATTRS_DECL_START__(res, link, renderMode, isDOMRenderMode, stringResult) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (!stringResult && isDOMRenderMode) {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\t$0 = new Snakeskin.Element(link, renderMode);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t__STRING_RESULT__ += \'<\' + link;\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __GET_XML_ATTRS_DECL_END__(res, link, cache, isDOMRenderMode, stringResult, isXMLDoctype, literalBounds) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (typeof link === \'undefined\' || link !== \'?\') {\n\t\t\t\t\t\tvar base = true;\n\t\t\t\t\t\tvar set = function (el, key) {\n\t\t\t\t\t\t\tif (!base && {\'class\': true, \'id\': true}[key]) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t\tattr = el[0] === TRUE ? isDOMRenderMode || isXMLDoctype ? key : TRUE : el.join(\' \'),\n\t\t\t\t\t\t\t\twrapper = literalBounds && attr !== TRUE && attr.slice(0, 2) === \'{{\' && attr.slice(-2) === \'}}\';\n\n\t\t\t\t\t\t\tif (!isDOMRenderMode) {\n\t\t\t\t\t\t\t\tif (attr === TRUE) {\n\t\t\t\t\t\t\t\t\tattr = \'\';\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tif (wrapper) {\n\t\t\t\t\t\t\t\t\t\tattr = \'=\' + literalBounds[0] + attr.slice(2, -2) + literalBounds[1];\n\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tattr = \'="\' + __ESCAPE_D_Q__(attr) + \'"\';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t__STRING_RESULT__ += \' \' + key + attr;\n\n\t\t\t\t\t\t\t} else if (isDOMRenderMode) {\n\t\t\t\t\t\t\t\tSnakeskin.setAttribute($0, key, attr);\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (cache[\'id\']) {\n\t\t\t\t\t\t\tset(cache[\'id\'], \'id\');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (cache[\'class\']) {\n\t\t\t\t\t\t\tset(cache[\'class\'], \'class\');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbase = false;\n\t\t\t\t\t\tSnakeskin.forEach(cache, set);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __GET_XML_TAG_DECL_END__(res, link, inline, inlineTag, isDOMRenderMode, stringResult, isXMLDoctype) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (isDOMRenderMode) {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\tif (inline && !inlineTag || inlineTag === true) {\n\t\t\t\t\t\t\t\t$0 = __RESULT__[__RESULT__.length - 1];\n\n\t\t\t\t\t\t\t} else if (inlineTag && inlineTag!== true) {\n\t\t\t\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t\t\t\t\t$0 = __RESULT__[__RESULT__.length - 1];\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t__RESULT__.push($0);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\tif (inline && !inlineTag || inlineTag === true) {\n\t\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t\t__STRING_RESULT__ += (isXMLDoctype ? \'/\' : \'\') + \'>\';\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else if (inlineTag && inlineTag !== true) {\n\t\t\t\t\t\t\t\t__RESULT__ = ', ';\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t\t__STRING_RESULT__ += \'>\';\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __GET_END_XML_TAG_DECL__(\n\t\t\t\t\tres,\n\t\t\t\t\tlink,\n\t\t\t\t\tinline,\n\t\t\t\t\tinlineTag,\n\t\t\t\t\tattrCache,\n\t\t\t\t\tcallCache,\n\t\t\t\t\tcallTmp,\n\t\t\t\t\tisDOMRenderMode,\n\t\t\t\t\tstringResult,\n\t\t\t\t\tisXMLDoctype,\n\t\t\t\t\tnode\n\n\t\t\t\t) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (isDOMRenderMode) {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\tif (inlineTag) {\n\t\t\t\t\t\t\t\tif (inlineTag !== true) {\n\t\t\t\t\t\t\t\t\t__RESULT__ = callCache;\n\t\t\t\t\t\t\t\t\tif (inlineTag in attrCache === false && callTmp) {\n\t\t\t\t\t\t\t\t\t\tSnakeskin.setAttribute(node, inlineTag, callTmp);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else if (!inline) {\n\t\t\t\t\t\t\t\t__RESULT__.pop();\n\t\t\t\t\t\t\t\t$0 = __RESULT__[__RESULT__.length - 1];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (link !== \'?\') {\n\t\t\t\t\t\t\tif (inlineTag) {\n\t\t\t\t\t\t\t\tif (inlineTag !== true) {\n\t\t\t\t\t\t\t\t\t__RESULT__ = callCache;\n\n\t\t\t\t\t\t\t\t\tif (inlineTag in attrCache === false && callTmp) {\n\t\t\t\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t\t\t\t__STRING_RESULT__ += \' \' + inlineTag + \'="\' + callTmp + \'"\';\n\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t\t\t__STRING_RESULT__ += (isXMLDoctype ? \'/\' : \'\') + \'>\';\n\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else if (!inline) {\n\t\t\t\t\t\t\t\tif (stringResult) {\n\t\t\t\t\t\t\t\t\t__STRING_RESULT__ += \'</\' + link + \'>\';\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __TARGET_END__(res, stack, ref) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (__LENGTH__(__RESULT__)) {\n\t\t\t\t\t\tstack.push({\n\t\t\t\t\t\t\tkey: undefined,\n\t\t\t\t\t\t\tvalue: Unsafe(', ')\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tSnakeskin.forEach(stack, function (el) {\n\t\t\t\t\t\tref[el.key || ref.length] = el.value;\n\t\t\t\t\t});\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __PUTIN_CALL__(res, pos, stack) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (pos === true || !pos && __LENGTH__(__RESULT__)) {\n\t\t\t\t\t\tstack.push(Unsafe(', '));\n\t\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tfunction __PUTIN_TARGET__(res, pos, stack, key) {\n\t\t\t\t\tvar __RESULT__ = res;\n\n\t\t\t\t\tif (pos === true || !pos && __LENGTH__(__RESULT__)) {\n\t\t\t\t\t\tstack.push({\n\t\t\t\t\t\t\tkey: key,\n\t\t\t\t\t\t\tvalue: Unsafe(', ')\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t\t}\n\n\t\t\t\t\treturn __RESULT__;\n\t\t\t\t}\n\n\t\t\t\tvar\n\t\t\t\t\t__RETURN__ = false,\n\t\t\t\t\t__RETURN_VAL__;\n\n\t\t\t\tvar\n\t\t\t\t\tTPL_NAME = "', '",\n\t\t\t\t\tPARENT_TPL_NAME', ',\n\t\t\t\t\tEOL = "', '";\n\n\t\t\t\t', '\n\t\t\t']);
9024var _templateObject5$1 = taggedTemplateLiteral(['\n\t\t\t\t\t\t', '\n\t\t\t\t\t\treturn ', ';\n\t\t\t\t\t});\n\n\t\t\t\t\tSnakeskin.cache["', '"] = exports', ';\n\t\t\t\t'], ['\n\t\t\t\t\t\t', '\n\t\t\t\t\t\treturn ', ';\n\t\t\t\t\t});\n\n\t\t\t\t\tSnakeskin.cache["', '"] = exports', ';\n\t\t\t\t']);
9025
9026['async', 'template', 'interface', 'placeholder'].forEach(function (dir) {
9027 Snakeskin$1.addDirective(dir, {
9028 block: true,
9029 deferInit: true,
9030 group: [dir, 'template', 'rootTemplate', 'define'],
9031 notEmpty: true,
9032 placement: 'global'
9033 }, function (command, _ref) {
9034 var _this = this;
9035
9036 var length = _ref.length,
9037 type = _ref.type,
9038 expr = _ref.expr,
9039 jsDoc = _ref.jsDoc;
9040
9041 if (this.name === 'async') {
9042 this.async = true;
9043 var _dir = command.split(' ');
9044 return Snakeskin$1.Directives[_dir[0]].call(this, _dir.slice(1).join(' ').trim(), {
9045 type: _dir[0],
9046 length: length,
9047 expr: expr,
9048 jsDoc: jsDoc
9049 });
9050 }
9051
9052 var env = this.environment,
9053 nms = env.namespace,
9054 prfx = ['', ''];
9055
9056 if (!nms) {
9057 return this.error('the directive "' + this.name + '" can\'t be declared without namespace');
9058 }
9059
9060 this.startTemplateI = this.i + 1;
9061 this.startTemplateLine = this.info.line;
9062
9063 var tplName = this.replaceFileNamePatterns(this.getFnName(command)),
9064 pos = void 0;
9065
9066 if (/\*/.test(tplName)) {
9067 prfx[1] = '*';
9068 tplName = tplName.replace(prfx[1], '');
9069 this.generator = true;
9070 }
9071
9072 if (this.async) {
9073 prfx[0] = 'async';
9074 }
9075
9076 var oldTplName = tplName = this.replaceDangerBlocks(nms) + concatProp(tplName);
9077
9078 var setTplName = function setTplName() {
9079 _this.info.template = _this.tplName = tplName;
9080 delete $write[oldTplName];
9081 $write[tplName] = _this.name === 'template';
9082 };
9083
9084 var flags = command.split(/\s+@=\s+/).slice(1);
9085
9086 var renderAs = this.renderAs;
9087
9088 for (var i = 0; i < flags.length; i++) {
9089 var _flags$i$split = flags[i].split(/\s+/),
9090 _flags$i$split2 = slicedToArray(_flags$i$split, 2),
9091 flag = _flags$i$split2[0],
9092 value = _flags$i$split2[1];
9093
9094 if (flag === 'renderAs') {
9095 renderAs = this.pasteDangerBlocks(value);
9096 }
9097 }
9098
9099 this.startDir(templateRank[renderAs] < templateRank[type] ? renderAs : type);
9100 setTplName();
9101
9102 var iface = this.name === 'interface',
9103 fnArgs = this.getFnArgs(command),
9104 fnArgsKey = fnArgs.join().replace(/=(.*?)(?:,|$)/g, '');
9105
9106 var lastDecl = command.slice(fnArgs.lastI),
9107 lastDeclTest = /\s*([^\s]+)/.exec(lastDecl);
9108
9109 if (lastDeclTest && !{ '@=': true, 'extends': true }[lastDeclTest[1]]) {
9110 return this.error('invalid syntax');
9111 }
9112
9113 pos = this.save('/* Snakeskin template: ' + tplName + '; ' + fnArgsKey + ' */', { iface: iface, jsDoc: jsDoc });
9114 if (jsDoc && pos) {
9115 jsDoc += pos.length;
9116 }
9117
9118 var tplNameParts = tplName.replace(nmssRgxp, '%').replace(nmsRgxp, '.%').replace(nmeRgxp, '').split('.');
9119
9120 var tplNameLength = tplNameParts.length;
9121
9122 var shortcut = '';
9123
9124 var _tplNameParts = slicedToArray(tplNameParts, 1);
9125
9126 tplName = _tplNameParts[0];
9127
9128
9129 if (tplName[0] === '%') {
9130 try {
9131 tplName = ws(_templateObject$9, applyDefEscape(this.returnEvalVal(this.out(tplName.slice(1), { unsafe: true }))));
9132 } catch (err) {
9133 return this.error(err.message);
9134 }
9135 } else {
9136 shortcut = tplName;
9137 }
9138
9139 var lastName = '';
9140 for (var _i = 1; _i < tplNameLength; _i++) {
9141 var el = tplNameParts[_i];
9142
9143 var custom = el[0] === '%',
9144 def = 'exports' + concatProp(tplName);
9145
9146 if (custom) {
9147 el = el.slice(1);
9148 }
9149
9150 pos = this.save(ws(_templateObject2$6, def, def, _i === 1 && shortcut ? (this.module === 'native' ? 'export ' : '') + 'var ' + shortcut + ' = ' + def + ';' : ''), { iface: iface, jsDoc: jsDoc });
9151
9152 if (jsDoc && pos) {
9153 jsDoc += pos.length;
9154 }
9155
9156 if (custom) {
9157 try {
9158 tplName += ws(_templateObject$9, applyDefEscape(this.returnEvalVal(this.out(el, { unsafe: true }))));
9159 } catch (err) {
9160 return this.error(err.message);
9161 }
9162
9163 continue;
9164 } else if (_i === tplNameLength - 1) {
9165 lastName = el;
9166 }
9167
9168 tplName += '.' + el;
9169 }
9170
9171 try {
9172 babylon.parse(tplName);
9173 } catch (ignore) {
9174 return this.error('invalid "' + this.name + '" name');
9175 }
9176
9177 var normalizeTplName = this.normalizeBlockName(tplName);
9178
9179 if (this.templates[normalizeTplName]) {
9180 var _templates$normalizeT = this.templates[normalizeTplName],
9181 file = _templates$normalizeT.file,
9182 _renderAs = _templates$normalizeT.renderAs;
9183
9184
9185 if (this.file !== file || this.renderAs === _renderAs) {
9186 return this.error('the template "' + tplName + '" already defined');
9187 }
9188 }
9189
9190 var declTplName = tplName;
9191 this.templates[normalizeTplName] = {
9192 declTplName: declTplName,
9193 file: this.info.file,
9194 renderAs: this.renderAs
9195 };
9196
9197 tplName = normalizeTplName;
9198 setTplName();
9199
9200 this.info.template = declTplName;
9201 this.vars[tplName] = {};
9202 this.blockTable = {};
9203 this.blockStructure = {
9204 children: [],
9205 name: 'root',
9206 parent: null
9207 };
9208
9209 var parentTplName = void 0,
9210 declParentTplName = void 0;
9211
9212 if (/\)\s+extends\s+/.test(command)) {
9213 try {
9214 this.scope.push(this.scope[this.scope.length - 1].replace(/^exports\.?/, ''));
9215 parentTplName = declParentTplName = this.getBlockName(/\)\s+extends\s+(.*?)(?=@=|$)/.exec(command)[1], true);
9216 this.scope.pop();
9217 } catch (ignore) {
9218 return this.error('invalid template name "' + this.name + '" for inheritance');
9219 }
9220
9221 parentTplName = this.parentTplName = this.normalizeBlockName(parentTplName);
9222
9223 if ($cache[parentTplName] == null) {
9224 if (!this.renderAs || this.renderAs === 'template') {
9225 return this.error('the specified template "' + declParentTplName + '" for inheritance is not defined');
9226 }
9227
9228 parentTplName = this.parentTplName = undefined;
9229 }
9230 }
9231
9232 var parentObj = $output[parentTplName];
9233
9234 if (parentTplName) {
9235 if (parentObj.async) {
9236 prfx[0] = 'async';
9237 this.async = true;
9238 }
9239
9240 if (parentObj.generator) {
9241 prfx[1] = '*';
9242 this.generator = true;
9243 }
9244 }
9245
9246 var decorators = (parentTplName ? parentObj.decorators : []).concat(this.decorators);
9247
9248 if (iface) {
9249 this.save('exports' + concatProp(declTplName) + ' = ' + prfx[0] + ' function ' + prfx[1] + (tplNameLength > 1 ? lastName : shortcut) + '(', { iface: iface });
9250 } else {
9251 this.save(ws(_templateObject3$6, concatProp(declTplName), decorators.join(), prfx[0], prfx[1], tplNameLength > 1 ? lastName : shortcut));
9252 }
9253
9254 this.decorators = [];
9255 this.initTemplateCache(tplName);
9256
9257 if (tplName in $extMap) {
9258 this.clearScopeCache(tplName);
9259 }
9260
9261 var scope = $scope['template'],
9262 parent = scope[parentTplName];
9263
9264 scope[tplName] = {
9265 children: {},
9266 id: this.environment.id,
9267 name: tplName,
9268 parent: parent
9269 };
9270
9271 scope[tplName].root = parent ? parent.root : scope[tplName];
9272
9273 if (parent) {
9274 parent.children[tplName] = scope[tplName];
9275 }
9276
9277 $args[tplName] = {};
9278 $argsRes[tplName] = {};
9279 $output[tplName] = {
9280 async: this.async,
9281 decorators: decorators,
9282 generator: this.generator
9283 };
9284
9285 $extMap[tplName] = parentTplName;
9286 delete $extList[tplName];
9287
9288 var baseParams = {};
9289
9290 if (!parentTplName) {
9291 var obj = this.params[this.params.length - 1];
9292
9293 for (var key in obj) {
9294 if (!obj.hasOwnProperty(key)) {
9295 break;
9296 }
9297
9298 var _el = obj[key];
9299
9300 if (key !== 'renderAs' && key[0] !== '@' && _el !== undefined) {
9301 baseParams[key] = _el;
9302 }
9303 }
9304 }
9305
9306 if (parentTplName && !flags.length) {
9307 flags.push('@skip true');
9308 }
9309
9310 for (var _i2 = 0; _i2 < flags.length; _i2++) {
9311 delete baseParams[flags[_i2].split(' ')[0]];
9312 Snakeskin$1.Directives['__set__'].call(this, flags[_i2]);
9313 }
9314
9315 for (var _key in baseParams) {
9316 if (!baseParams.hasOwnProperty(_key)) {
9317 break;
9318 }
9319
9320 var _el2 = baseParams[_key];
9321 Snakeskin$1.Directives['__set__'].call(this, [_key, _key === 'filters' ? _el2[_el2.length - 1] : _el2]);
9322 }
9323
9324 var doctype = this.doctype;
9325
9326 this.doctype = doctype && doctype !== 'html' ? 'xml' : 'html';
9327
9328 var args = this.declFnArgs(command, { dir: 'template', parentTplName: parentTplName, tplName: tplName });
9329
9330 this.save(args.decl + ') {', { iface: iface });
9331 this.save(ws(_templateObject4$3, concatProp(declTplName), doctype, this.getTplRuntime(), stringRender[this.renderMode] ? 'undefined' : '__RESULT__[0]', this.wrap('\'<\' + link'), this.wrap('\' \' + key + attr'), this.wrap('$0'), this.getResultDecl(), this.wrap('(isXMLDoctype ? \'/\' : \'\') + \'>\''), this.getResultDecl(), this.wrap('\'>\''), this.wrap('\' \' + inlineTag + \'="\' + callTmp + \'"\''), this.wrap('(isXMLDoctype ? \'/\' : \'\') + \'>\''), this.wrap('\'</\' + link + \'>\''), this.getReturnResultDecl(), this.getReturnResultDecl(), this.getResultDecl(), this.getReturnResultDecl(), this.getResultDecl(), escapeDoubleQuotes(declTplName), declParentTplName ? ' = "' + escapeDoubleQuotes(declParentTplName) + '"' : '', escapeEOLs(this.eol), args.def));
9332
9333 var preDefs = this.preDefs[tplName];
9334 if ((!$extMap[tplName] || parentTplName) && preDefs) {
9335 this.source = this.source.slice(0, this.i + 1) + preDefs.text + this.source.slice(this.i + 1);
9336
9337 delete this.preDefs[tplName];
9338 }
9339 }, function (command, _ref2) {
9340 var length = _ref2.length;
9341
9342 var tplName = String(this.tplName),
9343 diff = this.getDiff(length);
9344
9345 $cache[tplName] = this.source.slice(this.startTemplateI, this.i - diff);
9346 $templates[tplName] = this.blockTable;
9347
9348 if (this.parentTplName) {
9349 this.info.line = this.startTemplateLine;
9350 this.lines.splice(this.startTemplateLine, this.lines.length);
9351
9352 this.source = this.source.slice(0, this.startTemplateI) + this.getTplFullBody(tplName) + this.source.slice(this.i - diff);
9353
9354 if (this.needPrfx) {
9355 this.needPrfx = 1;
9356 }
9357
9358 this.initTemplateCache(tplName);
9359 this.startDir(this.structure.name);
9360 this.i = this.startTemplateI - 1;
9361 this.parentTplName = undefined;
9362 this.blockTable = {};
9363 this.vars[tplName] = {};
9364 return;
9365 }
9366
9367 if (this.needPrfx === 1) {
9368 this.needPrfx = false;
9369 }
9370
9371 var iface = this.structure.name === 'interface';
9372
9373 if (iface) {
9374 this.save('};', { iface: iface });
9375 } else {
9376 var declTplName = this.templates[tplName].declTplName;
9377
9378
9379 this.save(ws(_templateObject5$1, this.consts.join(''), this.getReturnResultDecl(), escapeDoubleQuotes(declTplName), concatProp(declTplName)));
9380 }
9381
9382 this.save('/* Snakeskin template. */', { iface: iface });
9383
9384 this.popParams();
9385 this.canWrite = true;
9386 this.tplName = undefined;
9387 this.async = false;
9388 this.generator = false;
9389 delete this.info.template;
9390 });
9391});
9392
9393var _templateObject$10 = taggedTemplateLiteral(['\n\t\t\t\t\t\t\t\ttypeof require === \'function\' ?\n\t\t\t\t\t\t\t\t\trequire(', ') : typeof ', ' !== \'undefined\' ? ', ' : GLOBAL[', '];\n\t\t\t\t\t\t\t'], ['\n\t\t\t\t\t\t\t\ttypeof require === \'function\' ?\n\t\t\t\t\t\t\t\t\trequire(', ') : typeof ', ' !== \'undefined\' ? ', ' : GLOBAL[', '];\n\t\t\t\t\t\t\t']);
9394
9395Snakeskin$1.addDirective('import', {
9396 ancestorsBlacklist: [Snakeskin$1.group('template'), Snakeskin$1.group('dynamic'), Snakeskin$1.group('logic')],
9397 group: ['import', 'head'],
9398 notEmpty: true
9399}, function (command) {
9400 var _this = this;
9401
9402 var structure = this.structure,
9403 file = this.info.file;
9404
9405
9406 var isNativeExport = this.module === 'native',
9407 resolve = this.resolveModuleSource;
9408
9409 var res = '',
9410 from = '';
9411
9412 if (isNativeExport) {
9413 res += 'import ';
9414 structure.vars = {};
9415 structure.params['@result'] = '';
9416 }
9417
9418 command = command.replace(/(?:\s+from\s+([^\s]+)\s*|\s*([^\s]+)\s*)$/, function (str, path1, path2) {
9419 var f = function f() {
9420 var path = _this.pasteDangerBlocks(path1 || path2),
9421 pathId = _this.pasteDangerBlocks(path).slice(1, -1);
9422
9423 if (resolve) {
9424 pathId = resolve(pathId, file);
9425 path = '\'' + pathId + '\'';
9426 }
9427
9428 switch (_this.module) {
9429 case 'native':
9430 return '' + (path1 ? 'from ' : '') + path + ';';
9431
9432 case 'cjs':
9433 return 'require(' + path + ');';
9434
9435 case 'global':
9436 return 'GLOBAL[' + path + '];';
9437
9438 case 'amd':
9439 _this.amdModules.push(pathId);
9440 return pathId + ';';
9441
9442 default:
9443 if (getRgxp('^[$' + symbols + '_][' + w + ']*$').test(pathId)) {
9444 _this.amdModules.push(pathId);
9445 return ws(_templateObject$10, path, pathId, pathId, path);
9446 }
9447
9448 return 'typeof require === \'function\' ? require(' + path + ') : GLOBAL[' + path + '];';
9449 }
9450 };
9451
9452 if (isNativeExport) {
9453 from = f();
9454 } else {
9455 if (path1) {
9456 res += '__REQUIRE__ = ' + f();
9457 from = '__REQUIRE__';
9458 } else {
9459 res += f();
9460 from = true;
9461 }
9462 }
9463
9464 return '';
9465 });
9466
9467 if (!from) {
9468 return this.error('invalid "' + this.name + '" declaration');
9469 }
9470
9471 /**
9472 * @param {string} str
9473 * @param {?boolean=} [opt_global]
9474 * @return {string}
9475 */
9476 var f = function f(str, opt_global) {
9477 if (!str.length) {
9478 return '';
9479 }
9480
9481 var args = str.split(/\s*,\s*/),
9482 arr = [];
9483
9484 for (var i = 0; i < args.length; i++) {
9485 var parts = args[i].split(/\s+as\s+/);
9486
9487 if (isNativeExport) {
9488 if (opt_global) {
9489 if (parts[1]) {
9490 arr.push(parts[0] + ' as ' + _this.declVar(parts[1]));
9491 } else {
9492 arr.push(_this.declVar(parts[0]));
9493 }
9494 } else {
9495 arr.push(parts[0] + ' as ' + _this.declVar(parts[1] || parts[0]));
9496 }
9497 } else {
9498 arr.push(_this.declVars((parts[1] || parts[0]) + ' = ' + from + (opt_global || parts[0] === '*' ? '' : '.' + (parts[1] || parts[0]))));
9499 }
9500 }
9501
9502 return arr.join(isNativeExport ? ',' : '');
9503 };
9504
9505 var r$$1 = /^,|,$/;
9506 command = command.replace(/\s*,?\s*\{\s*(.*?)\s*}\s*,?\s*/g, function (str, decl) {
9507 if (isNativeExport) {
9508 res += '{ ' + f(decl) + ' },';
9509 } else {
9510 res += f(decl);
9511 }
9512
9513 return ',';
9514 }).replace(r$$1, '');
9515
9516 if (!command) {
9517 res = res.replace(r$$1, '');
9518 }
9519
9520 if (isNativeExport) {
9521 res = res + f(command, true) + from;
9522 } else {
9523 res = res + f(command, true);
9524 }
9525
9526 this.append(res);
9527});
9528
9529var _templateObject$11 = taggedTemplateLiteral(['\n\t\t\t\tSnakeskin.include(\n\t\t\t\t\t\'', '\',\n\t\t\t\t\t', ',\n\t\t\t\t\t\'', '\',\n\t\t\t\t\t', '\n\t\t\t\t);\n\t\t\t'], ['\n\t\t\t\tSnakeskin.include(\n\t\t\t\t\t\'', '\',\n\t\t\t\t\t', ',\n\t\t\t\t\t\'', '\',\n\t\t\t\t\t', '\n\t\t\t\t);\n\t\t\t']);
9530
9531Snakeskin$1.addDirective('include', {
9532 ancestorsBlacklist: [Snakeskin$1.group('head'), Snakeskin$1.group('template')],
9533 deferInit: true,
9534 group: 'include',
9535 notEmpty: true
9536}, function (command) {
9537 this.startInlineDir(null, {
9538 from: this.result.length
9539 });
9540
9541 var parts = command.split(/\s+as\s+/);
9542
9543 if (!parts[0]) {
9544 return this.error('invalid "' + this.name + '" declaration');
9545 }
9546
9547 var path = this.out(parts[0], { unsafe: true }),
9548 type = parts[1] ? '\'' + parts[1].trim() + '\'' : '\'\'';
9549
9550 if (path !== undefined && type !== undefined) {
9551 this.save(ws(_templateObject$11, escapeBackslashes(this.info.file || ''), this.pasteDangerBlocks(path), escapeEOLs(this.eol), type));
9552 }
9553}, function () {
9554 if (this.hasParent(this.getGroup('eval'))) {
9555 return;
9556 }
9557
9558 this.result = this.result.slice(0, this.structure.params.from);
9559});
9560
9561Snakeskin$1.addDirective('__setFile__', {
9562 group: 'ignore'
9563}, function (file) {
9564 file = this.pasteDangerBlocks(file);
9565 this.namespace = undefined;
9566
9567 var env = this.environment,
9568 r$$1 = getRequire(file);
9569
9570 var module = {
9571 children: [],
9572 exports: {},
9573 filename: file,
9574 dirname: r$$1.dirname,
9575 id: env.id + 1,
9576 key: null,
9577 loaded: true,
9578 namespace: null,
9579 parent: this.environment,
9580 require: r$$1.require,
9581 root: env.root || env
9582 };
9583
9584 module.root.key.push([file, require('fs').statSync(file).mtime.valueOf()]);
9585 env.children.push(module);
9586
9587 this.environment = module;
9588 this.info.file = file;
9589 this.files[file] = true;
9590 this.save(this.declVars('$_', { sys: true }));
9591});
9592
9593Snakeskin$1.addDirective('__endSetFile__', {
9594 group: 'ignore'
9595}, function () {
9596 var _environment = this.environment,
9597 filename = _environment.filename,
9598 namespace = _environment.namespace;
9599
9600
9601 this.environment = this.environment.parent;
9602 this.info.file = this.environment.filename;
9603
9604 if (namespace) {
9605 this.scope.pop();
9606 }
9607
9608 if (this.params[this.params.length - 1]['@file'] === filename) {
9609 this.popParams();
9610 }
9611});
9612
9613Snakeskin$1.addDirective('for', {
9614 block: true,
9615 group: ['for', 'cycle', 'dynamic'],
9616 notEmpty: true
9617}, function (command) {
9618 // for var i = 0; i < 3; i++
9619 if (/;/.test(command)) {
9620 var parts = command.split(';');
9621
9622 if (parts.length !== 3) {
9623 return this.error('invalid "' + this.name + '" declaration');
9624 }
9625
9626 var varDeclRgxp = /\bvar\b/;
9627
9628 var decl = varDeclRgxp.test(parts[0]) ? this.declVars(parts[0].replace(varDeclRgxp, '')) : this.out(parts[0], { unsafe: true });
9629
9630 parts[1] = parts[1] && '(' + parts[1] + ')';
9631 parts[2] = parts[2] && '(' + parts[2] + ')';
9632
9633 this.append('for (' + decl + this.out(parts.slice(1).join(';'), { unsafe: true }) + ') {');
9634
9635 // for var key in obj OR for var el of obj
9636 } else {
9637 var _parts = /\s*(var|)\s+(.*?)\s+(in|of)\s+(.*)/.exec(command);
9638
9639 if (!_parts) {
9640 return this.error('invalid "' + this.name + '" declaration');
9641 }
9642
9643 var _decl = _parts[1] ? this.declVars(_parts[2], { def: '', end: false }) : this.out(_parts[2], { unsafe: true });
9644 this.append('for (' + _decl + ' ' + _parts[3] + ' ' + this.out(_parts[4], { unsafe: true }) + ') {');
9645 }
9646}, function () {
9647 this.append('}');
9648});
9649
9650Snakeskin$1.addDirective('while', {
9651 block: true,
9652 deferInit: true,
9653 group: ['while', 'cycle', 'dynamic'],
9654 notEmpty: true
9655}, function (command) {
9656 // do { ... } while ( ... )
9657 if (this.structure.name === 'do') {
9658 this.append('} while (' + this.out(command, { unsafe: true }) + ');');
9659 this.structure.params.chain = true;
9660 Snakeskin$1.Directives['end'].call(this);
9661
9662 // while ( ... ) { ... }
9663 } else {
9664 this.startDir();
9665 this.append('while (' + this.out(command, { unsafe: true }) + ') {');
9666 }
9667}, function () {
9668 this.append('}');
9669});
9670
9671Snakeskin$1.addDirective('do', {
9672 block: true,
9673 endsWith: [Snakeskin$1.group('while'), 'end'],
9674 group: ['do', 'cycle', 'dynamic']
9675}, function () {
9676 this.append('do {');
9677}, function () {
9678 if (this.structure.params.chain) {
9679 return;
9680 }
9681
9682 this.append('} while (true);');
9683});
9684
9685var _templateObject$12 = taggedTemplateLiteral(['\n\t\t\t\t\t\tif (typeof arguments[0] === \'function\') {\n\t\t\t\t\t\t\treturn arguments[0](', ');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t'], ['\n\t\t\t\t\t\tif (typeof arguments[0] === \'function\') {\n\t\t\t\t\t\t\treturn arguments[0](', ');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t']);
9686var _templateObject2$7 = taggedTemplateLiteral(['\n\t\t\t\t\t\tif (typeof arguments[0] === \'function\') {\n\t\t\t\t\t\t\treturn arguments[0](', ');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t'], ['\n\t\t\t\t\t\tif (typeof arguments[0] === \'function\') {\n\t\t\t\t\t\t\treturn arguments[0](', ');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t']);
9687
9688Snakeskin$1.addDirective('break', {
9689 ancestorsWhitelist: [Snakeskin$1.group('cycle'), Snakeskin$1.group('iterator'), Snakeskin$1.group('async')],
9690 group: ['break', 'control']
9691}, function (command) {
9692 var parent = any(this.hasParentFunction());
9693
9694 if (parent) {
9695 if (parent.block) {
9696 return this.error('the directive "' + this.name + '" can\'t be used within the "' + parent.target.name + '"');
9697 }
9698
9699 if (parent.asyncParent) {
9700 var val = command ? this.out(command, { unsafe: true }) : 'false';
9701
9702 if (this.getGroup('waterfall')[parent.asyncParent]) {
9703 this.append('return arguments[arguments.length - 1](' + val + ');');
9704 } else {
9705 this.append(ws(_templateObject$12, val));
9706 }
9707 } else {
9708 this.append('return false;');
9709 }
9710 } else {
9711 this.append('break;');
9712 }
9713});
9714
9715Snakeskin$1.addDirective('continue', {
9716 ancestorsWhitelist: [Snakeskin$1.group('cycle'), Snakeskin$1.group('iterator'), Snakeskin$1.group('async')],
9717 group: ['continue', 'control']
9718}, function (command) {
9719 var parent = any(this.hasParentFunction());
9720
9721 if (parent) {
9722 if (parent.block) {
9723 return this.error('the directive "' + this.name + '" can\'t be used within the "' + parent.target.name + '"');
9724 }
9725
9726 if (parent.asyncParent) {
9727 var val = command ? this.out(command, { unsafe: true }) : 'false';
9728
9729 if (this.getGroup('waterfall')[parent.asyncParent]) {
9730 this.append('return arguments[arguments.length - 1](' + val + ');');
9731 } else {
9732 this.append(ws(_templateObject2$7, val));
9733 }
9734 } else {
9735 this.append('return;');
9736 }
9737 } else {
9738 this.append('continue;');
9739 }
9740});
9741
9742var _templateObject$13 = taggedTemplateLiteral(['\n\t\t\t\t', '.forEach(function (', ') {\n\t\t\t\t\t', '\n\t\t\t'], ['\n\t\t\t\t', '.forEach(function (', ') {\n\t\t\t\t\t', '\n\t\t\t']);
9743var _templateObject2$8 = taggedTemplateLiteral(['\n\t\t\tSnakeskin.forEach(', ', function (', ') {\n\t\t\t\t', '\n\t\t'], ['\n\t\t\tSnakeskin.forEach(', ', function (', ') {\n\t\t\t\t', '\n\t\t']);
9744var _templateObject3$7 = taggedTemplateLiteral(['\n\t\t\tSnakeskin.forIn(', ', function (', ') {\n\t\t\t\t', '\n\t\t'], ['\n\t\t\tSnakeskin.forIn(', ', function (', ') {\n\t\t\t\t', '\n\t\t']);
9745
9746Snakeskin$1.addDirective('forEach', {
9747 block: true,
9748 deferInit: true,
9749 group: ['forEach', 'iterator', 'function', 'dynamic'],
9750 notEmpty: true
9751}, function (command) {
9752 command = command.replace(/=>>/g, '=>=>');
9753
9754 var parts = command.split(/\s*=>\s*/);
9755
9756 if (!parts.length || parts.length > 3) {
9757 return this.error('invalid "' + this.name + '" declaration');
9758 }
9759
9760 var is$C = parts.length === 3;
9761
9762 this.startDir(null, {
9763 $C: is$C,
9764 params: parts[2] ? parts[1] : null
9765 });
9766
9767 var val = is$C ? this.out('$C(' + parts[0] + ')', { unsafe: true }) : this.out(parts[0], { unsafe: true }),
9768 args = this.declFnArgs('(' + parts[is$C ? 2 : 1] + ')');
9769
9770 if (is$C) {
9771 this.append(ws(_templateObject$13, val, args.decl, args.def));
9772
9773 return;
9774 }
9775
9776 this.append(ws(_templateObject2$8, val, args.decl, args.def));
9777}, function () {
9778 var p = this.structure.params;
9779
9780 if (p.$C) {
9781 this.selfThis.pop();
9782 }
9783
9784 if (p.params) {
9785 this.append('}, ' + this.out(p.params, { unsafe: true }) + ');');
9786 } else {
9787 this.append('});');
9788 }
9789});
9790
9791Snakeskin$1.addDirective('forIn', {
9792 block: true,
9793 group: ['forIn', 'iterator', 'function', 'dynamic'],
9794 notEmpty: true
9795}, function (command) {
9796 var parts = command.split(/\s*=>\s*/);
9797
9798 if (!parts.length || parts.length > 2) {
9799 return this.error('invalid "' + this.name + '" declaration');
9800 }
9801
9802 var val = this.out(parts[0], { unsafe: true }),
9803 args = this.declFnArgs('(' + parts[1] + ')');
9804
9805 this.append(ws(_templateObject3$7, val, args.decl, args.def));
9806}, function () {
9807 this.append('});');
9808});
9809
9810Snakeskin$1.addDirective('func', {
9811 block: true,
9812 group: ['func', 'function', 'dynamic'],
9813 shorthands: { '()': 'func ' }
9814}, function (command) {
9815 command = command.replace(/^=>\s*/, '');
9816
9817 var p = this.structure.params;
9818
9819 var prfx = '',
9820 pstfx = '';
9821
9822 var parent = any(this.getNonLogicParent());
9823
9824 if (this.getGroup('async')[parent.name]) {
9825 p.type = 'async';
9826
9827 var length = 0;
9828
9829 for (var i = 0; i < parent.children.length; i++) {
9830 if (this.getGroup('func')[parent.children[i].name]) {
9831 length++;
9832 }
9833
9834 if (length > 1) {
9835 break;
9836 }
9837 }
9838
9839 prfx = length > 1 ? ',' : '';
9840 } else {
9841 var _parent = any(this.hasParentMicroTemplate());
9842
9843 if (_parent) {
9844 p.parent = _parent;
9845 p.type = 'microTemplate';
9846 prfx = '__RESULT__ = new Raw';
9847 }
9848
9849 pstfx = this.getTplRuntime();
9850 }
9851
9852 var args = this.declFnArgs('(' + command + ')');
9853 this.append(prfx + '(function (' + args.decl + ') {' + args.def + pstfx);
9854}, function () {
9855 var p = this.structure.params;
9856
9857 switch (p.type) {
9858 case 'async':
9859 this.append('})');
9860 break;
9861
9862 case 'microTemplate':
9863 this.append('return Unsafe(' + this.getReturnResultDecl() + '); });');
9864 p.parent.params.strongSpace = true;
9865 this.strongSpace.push(true);
9866 break;
9867
9868 default:
9869 this.append('});');
9870 }
9871});
9872
9873Snakeskin$1.addDirective('final', {
9874 group: ['final', 'function', 'dynamic'],
9875 with: Snakeskin$1.group('Async')
9876}, function (command) {
9877 var parts = command.split('=>');
9878
9879 if (!parts.length || parts.length > 2) {
9880 return this.error('invalid "' + this.name + '" declaration');
9881 }
9882
9883 this.structure.chain = false;
9884 this.structure.params.final = true;
9885
9886 var args = this.declFnArgs('(' + parts[1] + ')');
9887 this.append('], function (' + args.decl + ') {' + args.def);
9888});
9889
9890['parallel', 'series', 'waterfall'].forEach(function (dir) {
9891 Snakeskin$1.addDirective(dir, {
9892 block: true,
9893 children: Snakeskin$1.group('func'),
9894 group: [dir, 'Async', 'async', 'dynamic']
9895 }, function (command, _ref) {
9896 var type = _ref.type;
9897
9898 this.append(this.out('async', { unsafe: true }) + '.' + type + '([');
9899 }, function () {
9900 this.append((this.structure.params.final ? '}' : ']') + ');');
9901 });
9902});
9903
9904Snakeskin$1.addDirective('literal', {
9905 filters: { global: [['undef']], local: [['undef']] },
9906 group: ['literal', 'escape', 'output'],
9907 notEmpty: true,
9908 placement: 'template',
9909 shorthands: { '{': 'literal {' },
9910 text: true
9911}, function (command) {
9912 this.append(this.wrap('\'' + this.literalBounds[0] + this.replaceTplVars(command.replace(/^\s*\{|}\s*$/g, '')) + this.literalBounds[1] + '\''));
9913});
9914
9915var _templateObject$14 = taggedTemplateLiteral(['\n\t\t\t__RETURN__ = true;\n\t\t\t__RETURN_VAL__ = ', ';\n\t\t'], ['\n\t\t\t__RETURN__ = true;\n\t\t\t__RETURN_VAL__ = ', ';\n\t\t']);
9916var _templateObject2$9 = taggedTemplateLiteral(['\n\t\t\t\t\t\tif (typeof arguments[0] === \'function\') {\n\t\t\t\t\t\t\treturn arguments[0](__RETURN_VAL__);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t'], ['\n\t\t\t\t\t\tif (typeof arguments[0] === \'function\') {\n\t\t\t\t\t\t\treturn arguments[0](__RETURN_VAL__);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t']);
9917
9918Snakeskin$1.addDirective('return', {
9919 block: true,
9920 deferInit: true,
9921 group: ['return', 'microTemplate'],
9922 placement: 'template',
9923 trim: true
9924}, function (command) {
9925 if (command.slice(-1) === '/') {
9926 this.startInlineDir(null, { command: command.slice(0, -1) });
9927 return;
9928 }
9929
9930 this.startDir(null, { command: command });
9931
9932 if (!command) {
9933 this.wrap('__RESULT__ = ' + this.getResultDecl() + ';');
9934 }
9935}, function () {
9936 var command = this.structure.params.command;
9937
9938
9939 var val = command ? this.out(command, { unsafe: true }) : this.getReturnResultDecl(),
9940 parent = any(this.hasParentFunction());
9941
9942 if (!parent || parent.block) {
9943 this.append('return ' + val + ';');
9944 return;
9945 }
9946
9947 var def = ws(_templateObject$14, val);
9948
9949 var str = '';
9950 if (parent.asyncParent) {
9951 if (this.getGroup('Async')[parent.asyncParent]) {
9952 str += def;
9953
9954 if (this.getGroup('waterfall')[parent.asyncParent]) {
9955 str += 'return arguments[arguments.length - 1](__RETURN_VAL__);';
9956 } else {
9957 str += ws(_templateObject2$9);
9958 }
9959 } else {
9960 str += 'return false;';
9961 }
9962 } else {
9963 if (parent && !this.getGroup('async')[parent.target.name]) {
9964 str += def;
9965 this.deferReturn = 1;
9966 }
9967
9968 str += 'return false;';
9969 }
9970
9971 this.append(str);
9972});
9973
9974var _templateObject$15 = taggedTemplateLiteral(['\n\t\t\t\t', '\n\t\n\t\t\t\t', '\n\t\t\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t'], ['\n\t\t\t\t', '\n\t\n\t\t\t\t', '\n\t\t\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t']);
9975var _templateObject2$10 = taggedTemplateLiteral(['\n\t\t\t\t\t\t__CALL_CACHE__ = __RESULT__,\n\t\t\t\t\t\t__CALL_TMP__ = [],\n\t\t\t\t\t\t__CALL_POS__ = 0\n\t\t\t\t\t'], ['\n\t\t\t\t\t\t__CALL_CACHE__ = __RESULT__,\n\t\t\t\t\t\t__CALL_TMP__ = [],\n\t\t\t\t\t\t__CALL_POS__ = 0\n\t\t\t\t\t']);
9976
9977Snakeskin$1.addDirective('target', {
9978 block: true,
9979 deferInit: true,
9980 group: ['target', 'microTemplate', 'var', 'void'],
9981 notEmpty: true,
9982 trim: true
9983}, function (command) {
9984 var short = command.slice(-1) === '/';
9985
9986 if (short) {
9987 command = command.slice(0, -1);
9988 }
9989
9990 var _command$split = command.split(/\s+as\s+(?=[^\s])/),
9991 _command$split2 = slicedToArray(_command$split, 2),
9992 obj = _command$split2[0],
9993 ref = _command$split2[1];
9994
9995 if (ref) {
9996 this.declVar(ref);
9997 }
9998
9999 this.startDir(null, { short: short });
10000 var str = this.declVars('__TARGET_REF__ = ' + obj, { sys: true });
10001 this.structure.params.ref = this.getVar('__TARGET_REF__');
10002
10003 if (ref) {
10004 str += this.out('var ' + ref + ' = __TARGET_REF__;', { skipFirstWord: true, unsafe: true });
10005 }
10006
10007 if (short) {
10008 this.append(str);
10009 end.call(this);
10010 this.endDir();
10011 } else {
10012 this.append(ws(_templateObject$15, str, this.declVars(ws(_templateObject2$10), { sys: true }), this.getResultDecl()));
10013 }
10014}, end);
10015
10016function end() {
10017 var p = this.structure.params;
10018
10019 if (p.strongSpace) {
10020 this.strongSpace.pop();
10021 }
10022
10023 if (!p.short) {
10024 this.append('__RESULT__ = __TARGET_END__(__RESULT__, ' + this.getVar('__CALL_TMP__') + ', ' + p.ref + ');');
10025 }
10026
10027 var parent = any(this.hasParentMicroTemplate());
10028
10029 if (parent) {
10030 this.append('__RESULT__ = new Raw(' + p.ref + ');');
10031 parent.params.strongSpace = true;
10032 this.strongSpace.push(true);
10033 } else if (!p.short) {
10034 this.append('__RESULT__ = ' + this.getVar('__CALL_CACHE__') + ';');
10035 }
10036}
10037
10038/* eslint-disable prefer-template, no-useless-escape */
10039
10040Snakeskin$1.addDirective('super', {
10041 group: 'super',
10042 placement: 'template'
10043}, function (command, _ref) {
10044 var length = _ref.length;
10045
10046 if (!this.parentTplName || this.outerLink) {
10047 return;
10048 }
10049
10050 var map = this.getGroup('inherit');
10051
10052 var obj = this.blockStructure,
10053 cache = void 0,
10054 drop = void 0;
10055
10056 while (true) {
10057 if (map[obj.name]) {
10058 var name = obj.params.name;
10059
10060
10061 cache = $router[obj.name][this.parentTplName][name];
10062 drop = this.blockTable[obj.name + '_' + name].drop;
10063
10064 if (cache) {
10065 break;
10066 }
10067 }
10068
10069 if (obj.parent && obj.parent.name !== 'root') {
10070 obj = obj.parent;
10071 } else {
10072 break;
10073 }
10074 }
10075
10076 var s = (this.needPrfx ? ADV_LEFT_BOUND : '') + LEFT_BOUND,
10077 e = RIGHT_BOUND;
10078
10079 if (cache && !drop) {
10080 var diff = this.getDiff(length),
10081 sp = this.tolerateWhitespaces ? '' : s + '__&-__' + e;
10082
10083 this.source = this.source.slice(0, this.i - diff) +
10084 // Fixme: Babel goes fucking crazy
10085 '\/\*!!= ' + s + 'super' + e + ' =\*\/' + s + '__super__ ' + this.info.line + e + cache.content + sp + s + '__end__' + e + this.source.slice(this.i + 1);
10086
10087 var l = this.lines.length - 1;
10088 this.lines[l] = this.lines[l].slice(0, this.lines[l].length - diff - 1);
10089 this.i -= diff + 1;
10090 }
10091});
10092
10093Snakeskin$1.addDirective('__super__', {
10094 block: true,
10095 group: 'ignore'
10096}, function (command) {
10097 if (!command && !this.freezeLine) {
10098 this.lines.pop();
10099 this.info.line--;
10100 }
10101
10102 if (!command || this.lines.length >= parseInt(command, 10)) {
10103 this.freezeLine++;
10104 }
10105}, function () {
10106 this.freezeLine--;
10107});
10108
10109var types$1 = {
10110 'cljs': 'application/clojurescript',
10111 'coffee': 'application/coffeescript',
10112 'dart': 'application/dart',
10113 'html': 'text/html',
10114 'js': 'text/javascript',
10115 'json': 'application/json',
10116 'ls': 'application/livescript',
10117 'ss': 'text/x-snakeskin-template',
10118 'ts': 'application/typescript'
10119};
10120
10121Snakeskin$1.addDirective('script', {
10122 block: true,
10123 filters: { global: ['attr', ['html'], ['undef']], local: [['undef']] },
10124 group: ['script', 'tag', 'output'],
10125 interpolation: true,
10126 placement: 'template',
10127 selfInclude: false,
10128 trim: true
10129}, function (command, _ref) {
10130 var raw = _ref.raw;
10131
10132 var short = raw.slice(-2) === ' /';
10133
10134 if (short) {
10135 command = command.slice(0, -2);
10136 }
10137
10138 if (command) {
10139 command = command.replace(emptyCommandParams, 'js $1');
10140 } else {
10141 command = 'js';
10142 }
10143
10144 var parts = this.getTokens(command),
10145 type = types$1[parts[0].toLowerCase()] || this.replaceTplVars(parts[0]);
10146
10147 this.append(this.getXMLTagDecl('script', '(( type = ' + type + ' )) ' + parts.slice(1).join(' ')));
10148
10149 if (short) {
10150 end$1.call(this);
10151 this.endDir();
10152 }
10153}, end$1);
10154
10155function end$1() {
10156 this.append(this.getEndXMLTagDecl());
10157}
10158
10159var types$2 = {
10160 'css': 'text/css'
10161};
10162
10163Snakeskin$1.addDirective('style', {
10164 block: true,
10165 filters: { global: ['attr', ['html'], ['undef']], local: [['undef']] },
10166 group: ['style', 'tag', 'output'],
10167 interpolation: true,
10168 placement: 'template',
10169 selfInclude: false,
10170 trim: true
10171}, function (command, _ref) {
10172 var raw = _ref.raw;
10173
10174 var short = raw.slice(-2) === ' /';
10175
10176 if (short) {
10177 command = command.slice(0, -2);
10178 }
10179
10180 if (command) {
10181 command = command.replace(emptyCommandParams, 'css $1');
10182 } else {
10183 command = 'css';
10184 }
10185
10186 var parts = this.getTokens(command),
10187 type = types$2[parts[0].toLowerCase()] || this.replaceTplVars(parts[0]);
10188
10189 this.append(this.getXMLTagDecl('style', '(( type = ' + type + ' )) ' + parts.slice(1).join(' ')));
10190
10191 if (short) {
10192 end$2.call(this);
10193 this.endDir();
10194 }
10195}, end$2);
10196
10197function end$2() {
10198 this.append(this.getEndXMLTagDecl());
10199}
10200
10201var types$3 = {
10202 'acss': {
10203 'rel': 'alternate stylesheet',
10204 'type': 'text/css'
10205 },
10206
10207 'css': {
10208 'rel': 'stylesheet',
10209 'type': 'text/css'
10210 },
10211
10212 'icon': {
10213 'rel': 'icon',
10214 'type': 'image/x-icon'
10215 }
10216};
10217
10218Snakeskin$1.addDirective('link', {
10219 block: true,
10220 filters: { global: ['attr', ['html'], ['undef']], local: [['undef']] },
10221 group: ['link', 'tag', 'output'],
10222 interpolation: true,
10223 placement: 'template',
10224 selfInclude: false,
10225 trim: true
10226}, function (command, _ref) {
10227 var raw = _ref.raw;
10228
10229 var short = raw.slice(-2) === ' /';
10230
10231 if (short) {
10232 command = command.slice(0, -2);
10233 }
10234
10235 if (command) {
10236 command = command.replace(emptyCommandParams, 'css $1');
10237 } else {
10238 command = 'css';
10239 }
10240
10241 var parts = this.getTokens(command),
10242 type = types$3[parts[0].toLowerCase()] || this.replaceTplVars(parts[0]);
10243
10244 var typeStr = '(( rel = ' + (type.rel ? '' + type.rel : type) + (type.type ? ' | type = ' + type.type : '') + ' ))';
10245
10246 this.append(this.getXMLTagDecl('link', typeStr + ' ' + parts.slice(1).join(' ')));
10247
10248 if (short) {
10249 end$3.call(this);
10250 this.endDir();
10251 }
10252}, end$3);
10253
10254function end$3() {
10255 this.append(this.getEndXMLTagDecl());
10256}
10257
10258var _templateObject$16 = taggedTemplateLiteral(['\n\t\t\t', '\n\n\t\t\t__RESULT__ = ', ';\n\t\t'], ['\n\t\t\t', '\n\n\t\t\t__RESULT__ = ', ';\n\t\t']);
10259var _templateObject2$11 = taggedTemplateLiteral(['\n\t\t\t\t\t__CALL_CACHE__ = __RESULT__,\n\t\t\t\t\t__CALL_TMP__ = [],\n\t\t\t\t\t__CALL_POS__ = 0\n\t\t\t\t'], ['\n\t\t\t\t\t__CALL_CACHE__ = __RESULT__,\n\t\t\t\t\t__CALL_TMP__ = [],\n\t\t\t\t\t__CALL_POS__ = 0\n\t\t\t\t']);
10260var _templateObject3$8 = taggedTemplateLiteral(['\n\t\t\tif (__LENGTH__(__RESULT__)) {\n\t\t\t\t', '++;\n\t\t\t\t', '.push(Unsafe(', '));\n\t\t\t}\n\t\t'], ['\n\t\t\tif (__LENGTH__(__RESULT__)) {\n\t\t\t\t', '++;\n\t\t\t\t', '.push(Unsafe(', '));\n\t\t\t}\n\t\t']);
10261var _templateObject4$4 = taggedTemplateLiteral(['\n\t\t\t\t\t', ' ? ', ' : ', '\n\t\t\t\t'], ['\n\t\t\t\t\t', ' ? ', ' : ', '\n\t\t\t\t']);
10262var _templateObject5$2 = taggedTemplateLiteral(['\n\t\t\t__RESULT__ = ', ';\n\t\t\t', '\n\t\t'], ['\n\t\t\t__RESULT__ = ', ';\n\t\t\t', '\n\t\t']);
10263
10264Snakeskin$1.addDirective('call', {
10265 block: true,
10266 deferInit: true,
10267 filters: { global: [['undef']] },
10268 group: ['call', 'microTemplate', 'output'],
10269 notEmpty: true,
10270 shorthands: { '+=': 'call ', '/+': 'end call' },
10271 trim: true
10272}, function (command) {
10273 if (command.slice(-1) === '/') {
10274 this.startInlineDir(null, { short: true });
10275 this.append(this.wrap(this.out(command.slice(0, -1))));
10276 return;
10277 }
10278
10279 this.startDir(null, {
10280 chunks: 1,
10281 command: command
10282 });
10283
10284 this.append(ws(_templateObject$16, this.declVars(ws(_templateObject2$11), { sys: true }), this.getResultDecl()));
10285}, function () {
10286 this.text = true;
10287
10288 var p = this.structure.params;
10289
10290 if (p.strongSpace) {
10291 this.strongSpace.pop();
10292 }
10293
10294 if (p.short) {
10295 return;
10296 }
10297
10298 var tmp = this.getVar('__CALL_TMP__'),
10299 pos = this.getVar('__CALL_POS__');
10300
10301 this.append(ws(_templateObject3$8, pos, tmp, this.getReturnResultDecl()));
10302
10303 var i = p.chunks,
10304 j = 0;
10305
10306 var wrapParams = '';
10307
10308 while (i--) {
10309 if (wrapParams) {
10310 wrapParams += ',';
10311 }
10312
10313 wrapParams += tmp + '[' + j++ + ']';
10314 }
10315
10316 var str = void 0;
10317 var command = p.command.replace(/([^\s]\s*)(?=\)$)/, function (str, $0) {
10318 if (str[0] !== '(') {
10319 wrapParams = ',' + wrapParams;
10320 }
10321
10322 return $0 + wrapParams;
10323 });
10324
10325 var name = this.getFnName(command);
10326
10327 if (name === '&') {
10328 var block = this.hasBlock(this.getGroup('block'), true);
10329
10330 if (block) {
10331 str = block.params.fn + this.out(command.replace(name, ''), { unsafe: true });
10332 } else {
10333 return this.error('invalid "' + this.name + '" declaration');
10334 }
10335 } else {
10336 if (j === 1) {
10337 str = ws(_templateObject4$4, pos, this.out(command), this.out(p.command));
10338 } else {
10339 str = this.out(command);
10340 }
10341 }
10342
10343 this.append(ws(_templateObject5$2, this.getVar('__CALL_CACHE__'), this.wrap(str)));
10344});
10345
10346var _templateObject$17 = taggedTemplateLiteral(['\n\t\t\t\t', '\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t'], ['\n\t\t\t\t', '\n\t\t\t\t__RESULT__ = ', ';\n\t\t\t']);
10347var _templateObject2$12 = taggedTemplateLiteral(['\n\t\t\t\t\t__RESULT__ = __PUTIN_CALL__(__RESULT__, ', ', ', ');\n\t\t\t\t\t', '++;\n\t\t\t\t'], ['\n\t\t\t\t\t__RESULT__ = __PUTIN_CALL__(__RESULT__, ', ', ', ');\n\t\t\t\t\t', '++;\n\t\t\t\t']);
10348var _templateObject3$9 = taggedTemplateLiteral(['\n\t\t\t\t\t__RESULT__ = __PUTIN_TARGET__(\n\t\t\t\t\t\t__RESULT__,\n\t\t\t\t\t\t', ',\n\t\t\t\t\t\t', ',\n\t\t\t\t\t\t\'', '\'\n\t\t\t\t\t);\n\n\t\t\t\t\t', '++;\n\t\t\t\t'], ['\n\t\t\t\t\t__RESULT__ = __PUTIN_TARGET__(\n\t\t\t\t\t\t__RESULT__,\n\t\t\t\t\t\t', ',\n\t\t\t\t\t\t', ',\n\t\t\t\t\t\t\'', '\'\n\t\t\t\t\t);\n\n\t\t\t\t\t', '++;\n\t\t\t\t']);
10349var _templateObject4$5 = taggedTemplateLiteral(['\n\t\t\t\t\t__RESULT__ = __PUTIN_TARGET__(__RESULT__, true, ', ', \'', '\');\n\t\t\t\t'], ['\n\t\t\t\t\t__RESULT__ = __PUTIN_TARGET__(__RESULT__, true, ', ', \'', '\');\n\t\t\t\t']);
10350var _templateObject5$3 = taggedTemplateLiteral(['\n\t\t\t\t\t', ';\n\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t'], ['\n\t\t\t\t\t', ';\n\t\t\t\t\t__RESULT__ = ', ';\n\t\t\t\t']);
10351
10352Snakeskin$1.addDirective('putIn', {
10353 block: true,
10354 deferInit: true,
10355 group: ['putIn', 'microTemplate', 'void'],
10356 interpolation: true,
10357 shorthands: { '*': 'putIn ', '/*': 'end putIn' },
10358 trim: true
10359}, function (ref) {
10360 var _this = this;
10361
10362 this.startDir(null, { ref: ref });
10363
10364 var p = this.structure.params,
10365 tmp = this.getVar('__CALL_TMP__'),
10366 pos = this.getVar('__CALL_POS__');
10367
10368 var def = function def() {
10369 if (!ref) {
10370 return _this.error('the directive "' + _this.name + '" must have a body');
10371 }
10372
10373 _this.append(ws(_templateObject$17, _this.declVars('__CALL_CACHE__ = __RESULT__', { sys: true }), _this.getResultDecl()));
10374 };
10375
10376 var parent = any(this.hasParentMicroTemplate());
10377
10378 if (parent) {
10379 p.parent = parent;
10380
10381 if (parent.params.strongSpace) {
10382 parent.params.strongSpace = false;
10383 this.strongSpace.pop();
10384 }
10385
10386 if (this.getGroup('call')[parent.name]) {
10387 p.type = 'call';
10388 parent.params.chunks++;
10389 this.append(ws(_templateObject2$12, pos, tmp, pos));
10390 } else if (this.getGroup('target')[parent.name]) {
10391 p.type = 'target';
10392 this.append(ws(_templateObject3$9, pos, tmp, this.replaceTplVars(ref, { unsafe: true }), pos));
10393 } else {
10394 p.type = 'microTemplate';
10395 def();
10396 }
10397 } else {
10398 def();
10399 }
10400}, function () {
10401 var p = this.structure.params,
10402 tmp = this.getVar('__CALL_TMP__');
10403
10404 if (p.strongSpace) {
10405 this.strongSpace.pop();
10406 }
10407
10408 if (p.type) {
10409 p.parent.params.strongSpace = true;
10410 this.strongSpace.push(true);
10411 }
10412
10413 switch (p.type) {
10414 case 'call':
10415 this.append('__RESULT__ = __PUTIN_CALL__(__RESULT__, true, ' + tmp + ');');
10416 break;
10417
10418 case 'target':
10419 this.append(ws(_templateObject4$5, tmp, this.replaceTplVars(p.ref, { unsafe: true })));
10420
10421 break;
10422
10423 default:
10424 this.append(ws(_templateObject5$3, this.out(p.ref + ' = Unsafe(' + this.getReturnResultDecl() + ')', { unsafe: true }), this.getVar('__CALL_CACHE__')));
10425 }
10426});
10427
10428var _templateObject$18 = taggedTemplateLiteral(['\n\t\t\t\t\tif (!', ') {\n\t\t\t\t\t\t', ' = function (', ') {\n\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t', '\n\t\t\t\t'], ['\n\t\t\t\t\tif (!', ') {\n\t\t\t\t\t\t', ' = function (', ') {\n\t\t\t\t\t\t\t', '\n\t\t\t\t\t\t\t', '\n\t\t\t\t']);
10429var _templateObject2$13 = taggedTemplateLiteral(['\n\t\t\t\t', '', '\n\t\t\t\t', '__cutLine__', '\n\n\t\t\t\t\t', '__switchLine__ ', '', '\n\t\t\t\t\t\t', '\n\t\t\t\t\t', '__end__', '\n\n\t\t\t\t', '', '\n\t\t\t\t', '__cutLine__', '\n\t\t\t'], ['\n\t\t\t\t', '', '\n\t\t\t\t', '__cutLine__', '\n\n\t\t\t\t\t', '__switchLine__ ', '', '\n\t\t\t\t\t\t', '\n\t\t\t\t\t', '__end__', '\n\n\t\t\t\t', '', '\n\t\t\t\t', '__cutLine__', '\n\t\t\t']);
10430var _templateObject3$10 = taggedTemplateLiteral(['\n\t\t\t\t\t\treturn Unsafe(', ');\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t', '\n\t\t\t'], ['\n\t\t\t\t\t\treturn Unsafe(', ');\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t', '\n\t\t\t']);
10431
10432var callBlockNameRgxp = new RegExp('^[^' + symbols + '_$][^' + w + ']*|[^' + w + ']+', 'i');
10433
10434Snakeskin$1.addDirective('block', {
10435 block: true,
10436 deferInit: true,
10437 filters: { global: [['undef']] },
10438 group: ['block', 'template', 'define', 'inherit', 'blockInherit', 'dynamic'],
10439 logic: true,
10440 notEmpty: true
10441}, function (command, _ref) {
10442 var length = _ref.length;
10443
10444 var tplName = this.tplName,
10445 name = this.getFnName(command);
10446
10447
10448 if (!name) {
10449 return this.error('invalid "' + this.name + '" name');
10450 }
10451
10452 var parts = name.split('->');
10453
10454 if (parts[1]) {
10455 name = parts[1].trim();
10456
10457 if (!tplName) {
10458 if (this.structure.parent) {
10459 return this.error('the directive "outer block" can be used only within the global space');
10460 }
10461
10462 var nms = this.environment.namespace;
10463
10464 if (!nms) {
10465 return this.error('the directive "outer block" can\'t be declared without namespace');
10466 }
10467
10468 try {
10469 tplName = this.tplName = this.normalizeBlockName(nms + concatProp(this.getBlockName(parts[0])));
10470 } catch (err) {
10471 return this.error(err.message);
10472 }
10473
10474 if (tplName in $extMap) {
10475 delete $extMap[tplName];
10476 this.clearScopeCache(tplName);
10477 }
10478
10479 var desc = this.preDefs[tplName] = this.preDefs[tplName] || {
10480 text: ''
10481 };
10482
10483 desc.startLine = this.info.line;
10484 desc.i = this.i + 1;
10485
10486 this.outerLink = name;
10487 }
10488 } else if (!this.outerLink && !this.tplName) {
10489 return this.error('the directive "' + this.name + '" can be used only within a template');
10490 }
10491
10492 if (!name || !tplName || callBlockNameRgxp.test(name)) {
10493 return this.error('invalid "' + this.name + '" declaration');
10494 }
10495
10496 var scope = $scope[this.name][tplName] = $scope[this.name][tplName] || {},
10497 parentTplName = $extMap[tplName];
10498
10499 var current = scope[name],
10500 parentScope = void 0;
10501
10502 if (parentTplName) {
10503 parentScope = $scope[this.name][parentTplName] = $scope[this.name][parentTplName] || {};
10504 }
10505
10506 if (!scope[name]) {
10507 current = scope[name] = {
10508 children: {},
10509 id: this.environment.id,
10510 name: name
10511 };
10512 }
10513
10514 if (!this.outerLink && !current.root) {
10515 var parent = parentScope && parentScope[name];
10516
10517 current.parent = parent;
10518 current.overridden = Boolean(parentTplName && this.parentTplName);
10519 current.root = parent ? parent.root : scope[name];
10520
10521 if (parent) {
10522 parent.children[tplName] = scope[name];
10523 }
10524 }
10525
10526 var start = this.i - this.startTemplateI;
10527
10528 this.startDir(null, {
10529 from: this.outerLink ? this.i - this.getDiff(length) : start + 1,
10530 name: name
10531 });
10532
10533 var structure = this.structure,
10534 dir = String(this.name);
10535
10536
10537 var params = void 0,
10538 output = void 0;
10539
10540 if (name !== command) {
10541 var outputCache = this.getBlockOutput(dir);
10542
10543 if (outputCache) {
10544 output = command.split('=>')[1];
10545 params = outputCache[name];
10546
10547 if (output != null) {
10548 params = outputCache[name] = output;
10549 }
10550 }
10551 }
10552
10553 if (this.isAdvTest()) {
10554 if ($blocks[tplName][name]) {
10555 return this.error('the block "' + name + '" is already defined');
10556 }
10557
10558 var args = this.declFnArgs(command, { dir: dir, fnName: name, parentTplName: this.parentTplName });
10559 structure.params.isCallable = args.isCallable;
10560
10561 $blocks[tplName][name] = {
10562 args: args,
10563 external: parts.length > 1,
10564 from: start - this.getDiff(length),
10565 needPrfx: this.needPrfx,
10566 output: output
10567 };
10568 }
10569
10570 if (this.isSimpleOutput()) {
10571 var _args = $blocks[tplName][name].args;
10572
10573
10574 if (_args.isCallable) {
10575 var fnDecl = structure.params.fn = 'self.' + name;
10576
10577 this.save(ws(_templateObject$18, fnDecl, fnDecl, _args.decl, this.getTplRuntime(), _args.def));
10578
10579 if (params != null) {
10580 var vars = structure.vars;
10581
10582
10583 structure.vars = structure.parent.vars;
10584
10585 var _args2 = this.getFnArgs('(' + params + ')'),
10586 tmp = [];
10587
10588 for (var i = 0; i < _args2.length; i++) {
10589 tmp.push(this.out(_args2[i], { unsafe: true }));
10590 }
10591
10592 structure.params.params = tmp.join();
10593 structure.vars = vars;
10594 }
10595 }
10596 }
10597}, function (command, _ref2) {
10598 var length = _ref2.length;
10599
10600 var p = this.structure.params,
10601 diff = this.getDiff(length);
10602
10603 var s = (this.needPrfx ? ADV_LEFT_BOUND : '') + LEFT_BOUND,
10604 e = RIGHT_BOUND;
10605
10606 if (this.outerLink === p.name) {
10607 var obj = this.preDefs[this.tplName],
10608 i = Number(obj.i);
10609
10610 obj.text += ws(_templateObject2$13, this.eol, this.source.slice(p.from, i), s, e, s, obj.startLine, e, this.source.slice(i, this.i - diff), s, e, this.eol, this.source.slice(this.i - diff, this.i + 1), s, e);
10611
10612 this.outerLink = this.tplName = undefined;
10613 return;
10614 }
10615
10616 if (this.outerLink) {
10617 return;
10618 }
10619
10620 var block = $blocks[this.tplName][p.name],
10621 output = p.params != null;
10622
10623 if (this.isSimpleOutput() && p.fn) {
10624 this.save(ws(_templateObject3$10, this.getReturnResultDecl(), output ? this.wrap(this.out(p.fn + '(' + p.params + ')')) : ''));
10625
10626 if (!output) {
10627 var parent = any(this.hasParentMicroTemplate());
10628
10629 if (parent) {
10630 this.append('__RESULT__ = new Raw(' + p.fn + ');');
10631 parent.params.strongSpace = true;
10632 this.strongSpace.push(true);
10633 }
10634 }
10635 }
10636
10637 if (this.isAdvTest()) {
10638 if (!block) {
10639 return this.error('invalid "block" declaration');
10640 }
10641
10642 var start = this.i - this.startTemplateI;
10643
10644 block.to = start + 1;
10645 block.content = this.source.slice(this.startTemplateI).slice(p.from, start - diff);
10646 }
10647});
10648
10649Snakeskin$1.addDirective('attr', {
10650 filters: { global: ['attr', ['html'], ['undef']], local: [['undef']] },
10651 group: ['attr', 'output'],
10652 interpolation: true,
10653 notEmpty: true,
10654 placement: 'template',
10655 text: true
10656}, function (command) {
10657 this.append(this.getXMLAttrsDecl(command));
10658});
10659
10660Snakeskin$1.addDirective('tag', {
10661 block: true,
10662 deferInit: true,
10663 filters: { global: ['attr', ['html'], ['undef']], local: [['undef']] },
10664 group: ['tag', 'output'],
10665 interpolation: true,
10666 placement: 'template',
10667 shorthands: { '/<': 'end tag', '<': 'tag ' },
10668 text: true,
10669 trim: true
10670}, function (command, _ref) {
10671 var raw = _ref.raw;
10672
10673 var short = raw.slice(-2) === ' /';
10674
10675 if (short) {
10676 command = command.slice(0, -2);
10677 }
10678
10679 this.startDir(null, {
10680 bemRef: this.bemRef
10681 });
10682
10683 if (command) {
10684 command = command.replace(emptyCommandParams, defaultTag + ' $1');
10685 } else {
10686 command = defaultTag;
10687 }
10688
10689 var parts = this.getTokens(command),
10690 _getXMLTagDesc = this.getXMLTagDesc(parts[0]),
10691 tag = _getXMLTagDesc.tag,
10692 id = _getXMLTagDesc.id,
10693 inline = _getXMLTagDesc.inline,
10694 inlineMap = _getXMLTagDesc.inlineMap,
10695 classes = _getXMLTagDesc.classes;
10696
10697
10698 Object.assign(this.structure.params, { inline: inline, tag: tag });
10699
10700 if (inlineMap) {
10701 this.append(this.declVars('__INLINE_TAGS__ = ' + inlineMap, { sys: true }));
10702 }
10703
10704 if (tag === '?') {
10705 return;
10706 }
10707
10708 var str = this.getXMLAttrsDeclStart() + this.getXMLTagDeclStart(tag) + this.getXMLAttrsDeclBody(parts.slice(1).join(' '));
10709
10710 var attrCache = this.getVar('$attrs'),
10711 attrHackRgxp = /_+\$attrs_+(tag_\d+)?(?=.*\+ ')/g;
10712
10713 if (id) {
10714 str += attrCache + '[\'id\'] = [\'' + id + '\'] || ' + attrCache + '[\'id\'];';
10715 }
10716
10717 if (classes.length) {
10718 var arr = [];
10719
10720 for (var i = 0; i < classes.length; i++) {
10721 arr.push('\'' + classes[i].replace(attrHackRgxp, attrCache) + '\'');
10722 }
10723
10724 str += attrCache + '[\'class\'] = [' + arr + '].concat(' + attrCache + '[\'class\'] || []);';
10725 }
10726
10727 this.append(str + this.getXMLAttrsDeclEnd() + this.getXMLTagDeclEnd(inline));
10728
10729 if (short) {
10730 end$4.call(this);
10731 this.endDir();
10732 }
10733}, end$4);
10734
10735function end$4() {
10736 var p = this.structure.params;
10737
10738 this.bemRef = p.bemRef;
10739 this.append('$class = \'' + p.bemRef + '\';');
10740 this.prevSpace = false;
10741
10742 if (p.tag === '?') {
10743 return;
10744 }
10745
10746 this.append(this.getEndXMLTagDecl(p.inline));
10747}
10748
10749Snakeskin$1.addDirective('op', {
10750 block: true,
10751 group: 'op',
10752 logic: true
10753});
10754
10755return Snakeskin$1;
10756
10757})));