]> git.mxchange.org Git - friendica.git/commitdiff
[frio] Remove jSmart dependency
authorHypolite Petovan <hypolite@mrpetovan.com>
Thu, 17 Oct 2019 01:22:15 +0000 (21:22 -0400)
committerHypolite Petovan <hypolite@mrpetovan.com>
Sat, 2 Nov 2019 16:48:03 +0000 (12:48 -0400)
view/theme/frio/frameworks/jsmart/jsmart.custom.js [deleted file]
view/theme/frio/frameworks/jsmart/jsmart.js [deleted file]
view/theme/frio/frameworks/jsmart/jsmart.min.js [deleted file]
view/theme/frio/templates/head.tpl

diff --git a/view/theme/frio/frameworks/jsmart/jsmart.custom.js b/view/theme/frio/frameworks/jsmart/jsmart.custom.js
deleted file mode 100644 (file)
index 7a611a2..0000000
+++ /dev/null
@@ -1,3456 +0,0 @@
-/*!
- * jSmart Javascript template engine
- * https://github.com/umakantp/jsmart
- *
- * Copyright 2011-2015, Max Miroshnikov <miroshnikov at gmail dot com>
- *                      Umakant Patil <me at umakantpatil dot.com>
- * jSmart is licensed under the GNU Lesser General Public License
- * http://opensource.org/licenses/LGPL-3.0
- */
-
-
-(function() {
-
-    /**
-       merges two or more objects into one
-       shallow copy for objects
-    */
-    function obMerge(ob1, ob2 /*, ...*/)
-    {
-        for (var i=1; i<arguments.length; ++i)
-        {
-           for (var nm in arguments[i])
-           {
-              ob1[nm] = arguments[i][nm];
-           }
-        }
-        return ob1;
-    }
-
-    /**
-       @return  number of own properties in ob
-    */
-    function countProperties(ob)
-    {
-        var count = 0;
-        for (var nm in ob)
-        {
-            if (ob.hasOwnProperty(nm))
-            {
-                count++;
-            }
-        }
-        return count;
-    }
-
-    /**
-       IE workaround
-    */
-    function findInArray(a, v)
-    {
-        if (Array.prototype.indexOf) {
-            return a.indexOf(v);
-        }
-        for (var i=0; i < a.length; ++i)
-        {
-            if (a[i] === v)
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    function evalString(s)
-    {
-        return s.replace(/\\t/,'\t').replace(/\\n/,'\n').replace(/\\(['"\\])/g,'$1');
-    }
-
-    /**
-       @return  s trimmed and without quotes
-    */
-    function trimQuotes(s)
-    {
-        return evalString(s.replace(/^['"](.*)['"]$/,'$1')).replace(/^\s+|\s+$/g,'');
-    }
-
-    /**
-       finds first {tag} in string
-       @param re string with regular expression or an empty string to find any tag
-       @return  null or s.match(re) result object where
-       [0] - full tag matched with delimiters (and whitespaces at the begin and the end): { tag }
-       [1] - found part from passed re
-       [index] - position of tag starting { in s
-    */
-    function findTag(re,s)
-    {
-        var openCount = 0;
-        var offset = 0;
-        var ldelim = jSmart.prototype.left_delimiter;
-        var rdelim = jSmart.prototype.right_delimiter;
-        var skipInWS = jSmart.prototype.auto_literal;
-
-        var reAny = /^\s*(.+)\s*$/i;
-        var reTag = re ? new RegExp('^\\s*('+re+')\\s*$','i') : reAny;
-
-        for (var i=0; i<s.length; ++i)
-        {
-            if (s.substr(i,ldelim.length) == ldelim)
-            {
-                if (skipInWS && i+1 < s.length && s.substr(i+1,1).match(/\s/))
-                {
-                    continue;
-                }
-                if (!openCount)
-                {
-                    s = s.slice(i);
-                    offset += parseInt(i);
-                    i = 0;
-                }
-                ++openCount;
-            }
-            else if (s.substr(i,rdelim.length) == rdelim)
-            {
-                if (skipInWS && i-1 >= 0 && s.substr(i-1,1).match(/\s/))
-                {
-                    continue;
-                }
-                if (!--openCount)
-                {
-                    var sTag = s.slice(ldelim.length,i).replace(/[\r\n]/g, ' ');
-                    var found = sTag.match(reTag);
-                    if (found)
-                    {
-                        found.index = offset;
-                        found[0] = s.slice(0,i+rdelim.length);
-                        return found;
-                    }
-                }
-                if (openCount < 0) //ignore any number of unmatched right delimiters
-                {
-                    openCount = 0;
-                }
-            }
-        }
-        return null;
-    }
-
-    function findCloseTag(reClose,reOpen,s)
-    {
-        var sInner = '';
-        var closeTag = null;
-        var openTag = null;
-        var findIndex = 0;
-
-        do
-        {
-            if (closeTag)
-            {
-                findIndex += closeTag[0].length;
-            }
-            closeTag = findTag(reClose,s);
-            if (!closeTag)
-            {
-                throw new Error('Unclosed {'+reOpen+'}');
-            }
-            sInner += s.slice(0,closeTag.index);
-            findIndex += closeTag.index;
-            s = s.slice(closeTag.index+closeTag[0].length);
-
-            openTag = findTag(reOpen,sInner);
-            if (openTag)
-            {
-                sInner = sInner.slice(openTag.index+openTag[0].length);
-            }
-        }
-        while (openTag);
-
-        closeTag.index = findIndex;
-        return closeTag;
-    }
-
-    function findElseTag(reOpen, reClose, reElse, s)
-    {
-        var offset = 0;
-        for (var elseTag=findTag(reElse,s); elseTag; elseTag=findTag(reElse,s))
-        {
-            var openTag = findTag(reOpen,s);
-            if (!openTag || openTag.index > elseTag.index)
-            {
-                elseTag.index += offset;
-                return elseTag;
-            }
-            else
-            {
-                s = s.slice(openTag.index+openTag[0].length);
-                offset += openTag.index+openTag[0].length;
-                var closeTag = findCloseTag(reClose,reOpen,s);
-                s = s.slice(closeTag.index + closeTag[0].length);
-                offset += closeTag.index + closeTag[0].length;
-            }
-        }
-        return null;
-    }
-
-    function execute(code, data)
-    {
-        if (typeof(code) == 'string')
-        {
-            with ({'__code':code})
-            {
-                with (modifiers)
-                {
-                    with (data)
-                    {
-                        try {
-                            return eval(__code);
-                        }
-                        catch(e)
-                        {
-                            throw new Error(e.message + ' in \n' + code);
-                        }
-                    }
-                }
-            }
-        }
-        return code;
-    }
-
-    /**
-     * Execute function when we have a object.
-     *
-     * @param object obj  Object of the function to be called.
-     * @param array  args Arguments to pass to a function.
-     *
-     * @return
-     * @throws Error If function obj does not exists.
-     */
-    function executeByFuncObject(obj, args) {
-        try {
-            return obj.apply(this, args);
-        } catch (e) {
-            throw new Error(e.message);
-        }
-    }
-
-    function assignVar(nm, val, data)
-    {
-        if (nm.match(/\[\]$/))  //ar[] =
-        {
-            data[ nm.replace(/\[\]$/,'') ].push(val);
-        }
-        else
-        {
-            data[nm] = val;
-        }
-    }
-
-    var buildInFunctions =
-        {
-            expression:
-            {
-                parse: function(s, tree)
-                {
-                    var e = parseExpression(s);
-
-                    tree.push({
-                        type: 'build-in',
-                        name: 'expression',
-                        expression: e.tree,
-                        params: parseParams(s.slice(e.value.length).replace(/^\s+|\s+$/g,''))
-                    });
-
-                    return e.tree;
-
-                },
-                process: function(node, data)
-                {
-                    var params = getActualParamValues(node.params, data);
-                    var res = process([node.expression],data);
-
-                    if (findInArray(params, 'nofilter') < 0)
-                    {
-                        for (var i=0; i<default_modifiers.length; ++i)
-                        {
-                            var m = default_modifiers[i];
-                            m.params.__parsed[0] = {type:'text', data:res};
-                            res = process([m],data);
-                        }
-                        if (escape_html)
-                        {
-                            res = modifiers.escape(res);
-                        }
-                        res = applyFilters(varFilters,res);
-
-                        if (tpl_modifiers.length) {
-                            __t = function(){ return res; }
-                            res = process(tpl_modifiers,data);
-                        }
-                    }
-                    return res;
-                }
-            },
-
-            operator:
-            {
-                process: function(node, data)
-                {
-                    var params = getActualParamValues(node.params, data);
-                    var arg1 = params[0];
-
-                    if (node.optype == 'binary')
-                    {
-                        var arg2 = params[1];
-                        if (node.op == '=')
-                        {
-                            getVarValue(node.params.__parsed[0], data, arg2);
-                            return '';
-                        }
-                        else if (node.op.match(/(\+=|-=|\*=|\/=|%=)/))
-                        {
-                            arg1 = getVarValue(node.params.__parsed[0], data);
-                            switch (node.op)
-                            {
-                            case '+=': arg1+=arg2; break;
-                            case '-=': arg1-=arg2; break;
-                            case '*=': arg1*=arg2; break;
-                            case '/=': arg1/=arg2; break;
-                            case '%=': arg1%=arg2; break;
-                            }
-                            return getVarValue(node.params.__parsed[0], data, arg1);
-                        }
-                        else if (node.op.match(/div/))
-                        {
-                            return (node.op!='div')^(arg1%arg2==0);
-                        }
-                        else if (node.op.match(/even/))
-                        {
-                            return (node.op!='even')^((arg1/arg2)%2==0);
-                        }
-                        else if (node.op.match(/xor/))
-                        {
-                            return (arg1||arg2) && !(arg1&&arg2);
-                        }
-
-                        switch (node.op)
-                        {
-                        case '==': return arg1==arg2;
-                        case '!=': return arg1!=arg2;
-                        case '+':  return Number(arg1)+Number(arg2);
-                        case '-':  return Number(arg1)-Number(arg2);
-                        case '*':  return Number(arg1)*Number(arg2);
-                        case '/':  return Number(arg1)/Number(arg2);
-                        case '%':  return Number(arg1)%Number(arg2);
-                        case '&&': return arg1&&arg2;
-                        case '||': return arg1||arg2;
-                        case '<':  return arg1<arg2;
-                        case '<=': return arg1<=arg2;
-                        case '>':  return arg1>arg2;
-                        case '>=': return arg1>=arg2;
-                        case '===': return arg1===arg2;
-                        case '!==': return arg1!==arg2;
-                        }
-                    }
-                    else if (node.op == '!')
-                    {
-                        return !arg1;
-                    }
-                    else
-                    {
-                        var isVar = node.params.__parsed[0].type == 'var';
-                        if (isVar)
-                        {
-                            arg1 = getVarValue(node.params.__parsed[0], data);
-                        }
-                        var v = arg1;
-                        if (node.optype == 'pre-unary')
-                        {
-                            switch (node.op)
-                            {
-                            case '-':  v=-arg1;  break;
-                            case '++': v=++arg1; break;
-                            case '--': v=--arg1; break;
-                            }
-                            if (isVar)
-                            {
-                                getVarValue(node.params.__parsed[0], data, arg1);
-                            }
-                        }
-                        else
-                        {
-                            switch (node.op)
-                            {
-                            case '++': arg1++; break;
-                            case '--': arg1--; break;
-                            }
-                            getVarValue(node.params.__parsed[0], data, arg1);
-                        }
-                        return v;
-                    }
-                }
-            },
-
-            section:
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    var subTree = [];
-                    var subTreeElse = [];
-                    tree.push({
-                        type: 'build-in',
-                        name: 'section',
-                        params: params,
-                        subTree: subTree,
-                        subTreeElse: subTreeElse
-                    });
-
-                    var findElse = findElseTag('section [^}]+', '\/section', 'sectionelse', content);
-                    if (findElse)
-                    {
-                        parse(content.slice(0,findElse.index),subTree);
-                        parse(content.slice(findElse.index+findElse[0].length).replace(/^[\r\n]/,''), subTreeElse);
-                    }
-                    else
-                    {
-                        parse(content, subTree);
-                    }
-                },
-
-                process: function(node, data)
-                {
-                    var params = getActualParamValues(node.params, data);
-
-                    var props = {};
-                    data.smarty.section[params.__get('name',null,0)] = props;
-
-                    var show = params.__get('show',true);
-                    props.show = show;
-                    if (!show)
-                    {
-                        return process(node.subTreeElse, data);
-                    }
-
-                    var from = parseInt(params.__get('start',0));
-                    var to = (params.loop instanceof Object) ? countProperties(params.loop) : isNaN(params.loop) ? 0 : parseInt(params.loop);
-                    var step = parseInt(params.__get('step',1));
-                    var max = parseInt(params.__get('max'));
-                    if (isNaN(max))
-                    {
-                        max = Number.MAX_VALUE;
-                    }
-
-                    if (from < 0)
-                    {
-                        from += to;
-                        if (from < 0)
-                        {
-                            from = 0;
-                        }
-                    }
-                    else if (from >= to)
-                    {
-                        from = to ? to-1 : 0;
-                    }
-
-                    var count = 0;
-                    var loop = 0;
-                    var i = from;
-                    for (; i>=0 && i<to && count<max; i+=step,++count)
-                    {
-                        loop = i;
-                    }
-                    props.total = count;
-                    props.loop = count;  //? - because it is so in Smarty
-
-                    count = 0;
-                    var s = '';
-                    for (i=from; i>=0 && i<to && count<max; i+=step,++count)
-                    {
-                        if (data.smarty['break'])
-                        {
-                            break;
-                        }
-
-                        props.first = (i==from);
-                        props.last = ((i+step)<0 || (i+step)>=to);
-                        props.index = i;
-                        props.index_prev = i-step;
-                        props.index_next = i+step;
-                        props.iteration = props.rownum = count+1;
-
-                        s += process(node.subTree, data);
-                        data.smarty['continue'] = false;
-                    }
-                    data.smarty['break'] = false;
-
-                    if (count)
-                    {
-                        return s;
-                    }
-                    return process(node.subTreeElse, data);
-                }
-            },
-
-            setfilter:
-            {
-                type: 'block',
-                parseParams: function(paramStr)
-                {
-                    return [parseExpression('__t()|' + paramStr).tree];
-                },
-
-                parse: function(params, tree, content)
-                {
-                    tree.push({
-                        type: 'build-in',
-                        name: 'setfilter',
-                        params: params,
-                        subTree: parse(content,[])
-                    });
-                },
-
-                process: function(node, data)
-                {
-                    tpl_modifiers = node.params;
-                    var s = process(node.subTree, data);
-                    tpl_modifiers = [];
-                    return s;
-                }
-            },
-
-            'for':
-            {
-                type: 'block',
-                parseParams: function(paramStr)
-                {
-                    var res = paramStr.match(/^\s*\$(\w+)\s*=\s*([^\s]+)\s*to\s*([^\s]+)\s*(?:step\s*([^\s]+))?\s*(.*)$/);
-                    if (!res)
-                    {
-                        throw new Error('Invalid {for} parameters: '+paramStr);
-                    }
-                    return parseParams("varName='"+res[1]+"' from="+res[2]+" to="+res[3]+" step="+(res[4]?res[4]:'1')+" "+res[5]);
-                },
-
-                parse: function(params, tree, content)
-                {
-                    var subTree = [];
-                    var subTreeElse = [];
-                    tree.push({
-                        type: 'build-in',
-                        name: 'for',
-                        params: params,
-                        subTree: subTree,
-                        subTreeElse: subTreeElse
-                    });
-
-                    var findElse = findElseTag('for\\s[^}]+', '\/for', 'forelse', content);
-                    if (findElse)
-                    {
-                        parse(content.slice(0,findElse.index),subTree);
-                        parse(content.slice(findElse.index+findElse[0].length), subTreeElse);
-                    }
-                    else
-                    {
-                        parse(content, subTree);
-                    }
-                },
-
-                process: function(node, data)
-                {
-                    var params = getActualParamValues(node.params, data);
-                    var from = parseInt(params.__get('from'));
-                    var to = parseInt(params.__get('to'));
-                    var step = parseInt(params.__get('step'));
-                    if (isNaN(step))
-                    {
-                        step = 1;
-                    }
-                    var max = parseInt(params.__get('max'));
-                    if (isNaN(max))
-                    {
-                        max = Number.MAX_VALUE;
-                    }
-
-                    var count = 0;
-                    var s = '';
-                    var total = Math.min( Math.ceil( ((step > 0 ? to-from : from-to)+1) / Math.abs(step)  ), max);
-
-                    for (var i=parseInt(params.from); count<total; i+=step,++count)
-                    {
-                        if (data.smarty['break'])
-                        {
-                            break;
-                        }
-                        data[params.varName] = i;
-                        s += process(node.subTree, data);
-                        data.smarty['continue'] = false;
-                    }
-                    data.smarty['break'] = false;
-
-                    if (!count)
-                    {
-                        s = process(node.subTreeElse, data);
-                    }
-                    return s;
-                }
-            },
-
-            'if':
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    var subTreeIf = [];
-                    var subTreeElse = [];
-                    tree.push({
-                        type: 'build-in',
-                        name: 'if',
-                        params: params,
-                        subTreeIf: subTreeIf,
-                        subTreeElse: subTreeElse
-                    });
-
-                    var findElse = findElseTag('if\\s+[^}]+', '\/if', 'else[^}]*', content);
-                    if (findElse)
-                    {
-                        parse(content.slice(0,findElse.index),subTreeIf);
-
-                        content = content.slice(findElse.index+findElse[0].length);
-                        var findElseIf = findElse[1].match(/^else\s*if(.*)/);
-                        if (findElseIf)
-                        {
-                            buildInFunctions['if'].parse(parseParams(findElseIf[1]), subTreeElse, content.replace(/^\n/,''));
-                        }
-                        else
-                        {
-                            parse(content.replace(/^\n/,''), subTreeElse);
-                        }
-                    }
-                    else
-                    {
-                        parse(content, subTreeIf);
-                    }
-                },
-
-                process: function(node, data) {
-                    var value = getActualParamValues(node.params,data)[0];
-                    // Zero length arrays or empty associative arrays are false in PHP.
-                    if (value && !((value instanceof Array && value.length == 0)
-                        || (typeof value == 'object' && isEmptyObject(value)))
-                    ) {
-                        return process(node.subTreeIf, data);
-                    } else {
-                        return process(node.subTreeElse, data);
-                    }
-                }
-            },
-
-            foreach:
-            {
-                type: 'block',
-                parseParams: function(paramStr)
-                {
-                    var params = {};
-                    var res = paramStr.match(/^\s*([$].+)\s*as\s*[$](\w+)\s*(=>\s*[$](\w+))?\s*$/i);
-                    if (res) //Smarty 3.x syntax => Smarty 2.x syntax
-                    {
-                        paramStr = 'from='+res[1] + ' item='+(res[4]||res[2]);
-                        if (res[4])
-                        {
-                            paramStr += ' key='+res[2];
-                        }
-                    }
-                    return parseParams(paramStr);
-                },
-
-                parse: function(params, tree, content)
-                {
-                    var subTree = [];
-                    var subTreeElse = [];
-                    tree.push({
-                        type: 'build-in',
-                        name: 'foreach',
-                        params: params,
-                        subTree: subTree,
-                        subTreeElse: subTreeElse
-                    });
-
-                    var findElse = findElseTag('foreach\\s[^}]+', '\/foreach', 'foreachelse', content);
-                    if (findElse)
-                    {
-                        parse(content.slice(0,findElse.index),subTree);
-                        parse(content.slice(findElse.index+findElse[0].length).replace(/^[\r\n]/,''), subTreeElse);
-                    }
-                    else
-                    {
-                        parse(content, subTree);
-                    }
-                },
-
-                process: function(node, data)
-                {
-                    var params = getActualParamValues(node.params, data);
-                    var a = params.from;
-                    if (typeof a == 'undefined')
-                    {
-                        a = [];
-                    }
-                    if (typeof a != 'object')
-                    {
-                        a = [a];
-                    }
-
-                    var total = countProperties(a);
-
-                    data[params.item+'__total'] = total;
-                    if ('name' in params)
-                    {
-                        data.smarty.foreach[params.name] = {};
-                        data.smarty.foreach[params.name].total = total;
-                    }
-
-                    var s = '';
-                    var i=0;
-                    for (var key in a)
-                    {
-                        if (!a.hasOwnProperty(key))
-                        {
-                            continue;
-                        }
-
-                        if (data.smarty['break'])
-                        {
-                            break;
-                        }
-
-                        data[params.item+'__key'] = isNaN(key) ? key : parseInt(key);
-                        if ('key' in params)
-                        {
-                            data[params.key] = data[params.item+'__key'];
-                        }
-                        data[params.item] = a[key];
-                        data[params.item+'__index'] = parseInt(i);
-                        data[params.item+'__iteration'] = parseInt(i+1);
-                        data[params.item+'__first'] = (i===0);
-                        data[params.item+'__last'] = (i==total-1);
-
-                        if ('name' in params)
-                        {
-                            data.smarty.foreach[params.name].index = parseInt(i);
-                            data.smarty.foreach[params.name].iteration = parseInt(i+1);
-                            data.smarty.foreach[params.name].first = (i===0) ? 1 : '';
-                            data.smarty.foreach[params.name].last = (i==total-1) ? 1 : '';
-                        }
-
-                        ++i;
-
-                        s += process(node.subTree, data);
-                        data.smarty['continue'] = false;
-                    }
-                    data.smarty['break'] = false;
-
-                    data[params.item+'__show'] = (i>0);
-                    if (params.name)
-                    {
-                        data.smarty.foreach[params.name].show = (i>0) ? 1 : '';
-                    }
-                    if (i>0)
-                    {
-                        return s;
-                    }
-                    return process(node.subTreeElse, data);
-                }
-            },
-
-            'function':
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    var subTree = [];
-                    plugins[trimQuotes(params.name?params.name:params[0])] =
-                        {
-                            type: 'function',
-                            subTree: subTree,
-                            defautParams: params,
-                            process: function(params, data)
-                            {
-                                var defaults = getActualParamValues(this.defautParams,data);
-                                delete defaults.name;
-                                return process(this.subTree, obMerge({},data,defaults,params));
-                            }
-                        };
-                    parse(content, subTree);
-                }
-            },
-
-            php:
-            {
-                type: 'block',
-                parse: function(params, tree, content) {}
-            },
-
-            'extends':
-            {
-                type: 'function',
-                parse: function(params, tree)
-                {
-                    tree.splice(0,tree.length);
-                    getTemplate(trimQuotes(params.file?params.file:params[0]),tree);
-                }
-            },
-
-            block:
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    tree.push({
-                        type: 'build-in',
-                        name: 'block',
-                        params: params
-                    });
-                    params.append = findInArray(params,'append') >= 0;
-                    params.prepend = findInArray(params,'prepend') >= 0;
-                    params.hide = findInArray(params,'hide') >= 0;
-                    params.hasChild = params.hasParent = false;
-
-                    onParseVar = function(nm)
-                    {
-                        if (nm.match(/^\s*[$]smarty.block.child\s*$/))
-                        {
-                            params.hasChild = true;
-                        }
-                        if (nm.match(/^\s*[$]smarty.block.parent\s*$/))
-                        {
-                            params.hasParent = true;
-                        }
-                    }
-                    var tree = parse(content, []);
-                    onParseVar = function(nm) {}
-
-                    var blockName = trimQuotes(params.name?params.name:params[0]);
-                    if (!(blockName in blocks))
-                    {
-                        blocks[blockName] = [];
-                    }
-                    blocks[blockName].push({tree:tree, params:params});
-                },
-
-                process: function(node, data)
-                {
-                    data.smarty.block.parent = data.smarty.block.child = '';
-                    var blockName = trimQuotes(node.params.name?node.params.name:node.params[0]);
-                    this.processBlocks(blocks[blockName], blocks[blockName].length-1, data);
-                    return data.smarty.block.child;
-                },
-
-                processBlocks: function(blockAncestry, i, data)
-                {
-                    if (!i && blockAncestry[i].params.hide) {
-                        data.smarty.block.child = '';
-                        return;
-                    }
-                    var append = true;
-                    var prepend = false;
-                    for (; i>=0; --i)
-                    {
-                        if (blockAncestry[i].params.hasParent)
-                        {
-                            var tmpChild = data.smarty.block.child;
-                            data.smarty.block.child = '';
-                            this.processBlocks(blockAncestry, i-1, data);
-                            data.smarty.block.parent = data.smarty.block.child;
-                            data.smarty.block.child = tmpChild;
-                        }
-
-                        var tmpChild = data.smarty.block.child;
-                        var s = process(blockAncestry[i].tree, data);
-                        data.smarty.block.child = tmpChild;
-
-                        if (blockAncestry[i].params.hasChild)
-                        {
-                            data.smarty.block.child = s;
-                        }
-                        else if (append)
-                        {
-                            data.smarty.block.child = s + data.smarty.block.child;
-                        }
-                        else if (prepend)
-                        {
-                            data.smarty.block.child += s;
-                        }
-                        append = blockAncestry[i].params.append;
-                        prepend = blockAncestry[i].params.prepend;
-                    }
-                }
-            },
-
-            strip:
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    parse(content.replace(/[ \t]*[\r\n]+[ \t]*/g, ''), tree);
-                }
-            },
-
-            literal:
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    parseText(content, tree);
-                }
-            },
-
-            ldelim:
-            {
-                type: 'function',
-                parse: function(params, tree)
-                {
-                    parseText(jSmart.prototype.left_delimiter, tree);
-                }
-            },
-
-            rdelim:
-            {
-                type: 'function',
-                parse: function(params, tree)
-                {
-                    parseText(jSmart.prototype.right_delimiter, tree);
-                }
-            },
-
-            'while':
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    tree.push({
-                        type: 'build-in',
-                        name: 'while',
-                        params: params,
-                        subTree: parse(content, [])
-                    });
-                },
-
-                process: function(node, data)
-                {
-                    var s = '';
-                    while (getActualParamValues(node.params,data)[0])
-                    {
-                        if (data.smarty['break'])
-                        {
-                            break;
-                        }
-                        s += process(node.subTree, data);
-                        data.smarty['continue'] = false;
-                    }
-                    data.smarty['break'] = false;
-                    return s;
-                }
-            }
-        };
-
-    var plugins = {};
-    var modifiers = {};
-    var files = {};
-    var blocks = null;
-    var scripts = null;
-    var tpl_modifiers = [];
-
-    function parse(s, tree)
-    {
-        for (var openTag=findTag('',s); openTag; openTag=findTag('',s))
-        {
-            if (openTag.index)
-            {
-                parseText(s.slice(0,openTag.index),tree);
-            }
-            s = s.slice(openTag.index + openTag[0].length);
-
-            var res = openTag[1].match(/^\s*(\w+)(.*)$/);
-            if (res)         //function
-            {
-                var nm = res[1];
-                var paramStr = (res.length>2) ? res[2].replace(/^\s+|\s+$/g,'') : '';
-
-                if (nm in buildInFunctions)
-                {
-                    var buildIn = buildInFunctions[nm];
-                    var params = ('parseParams' in buildIn ? buildIn.parseParams : parseParams)(paramStr);
-                    if (buildIn.type == 'block')
-                    {
-                        s = s.replace(/^\n/,'');  //remove new line after block open tag (like in Smarty)
-                        var closeTag = findCloseTag('\/'+nm, nm+' +[^}]*', s);
-                        buildIn.parse(params, tree, s.slice(0,closeTag.index));
-                        s = s.slice(closeTag.index+closeTag[0].length);
-                    }
-                    else
-                    {
-                        buildIn.parse(params, tree);
-                        if (nm == 'extends')
-                        {
-                            tree = []; //throw away further parsing except for {block}
-                        }
-                    }
-                    s = s.replace(/^\n/,'');
-                }
-                else if (nm in plugins)
-                {
-                    var plugin = plugins[nm];
-                    if (plugin.type == 'block')
-                    {
-                        var closeTag = findCloseTag('\/'+nm, nm+' +[^}]*', s);
-                        parsePluginBlock(nm, parseParams(paramStr), tree, s.slice(0,closeTag.index));
-                        s = s.slice(closeTag.index+closeTag[0].length);
-                    }
-                    else if (plugin.type == 'function')
-                    {
-                        parsePluginFunc(nm, parseParams(paramStr), tree);
-                    }
-                    if (nm=='append' || nm=='assign' || nm=='capture' || nm=='eval' || nm=='include')
-                    {
-                        s = s.replace(/^\n/,'');
-                    }
-                }
-                else   //variable
-                {
-                    buildInFunctions.expression.parse(openTag[1],tree);
-                }
-            }
-            else         //variable
-            {
-                var node = buildInFunctions.expression.parse(openTag[1],tree);
-                if (node.type=='build-in' && node.name=='operator' && node.op == '=')
-                {
-                    s = s.replace(/^\n/,'');
-                }
-            }
-        }
-        if (s)
-        {
-            parseText(s, tree);
-        }
-        return tree;
-    }
-
-    function parseText(text, tree)
-    {
-        if (parseText.parseEmbeddedVars)
-        {
-            var re = /([$][\w@]+)|`([^`]*)`/;
-            for (var found=re.exec(text); found; found=re.exec(text))
-            {
-                tree.push({type: 'text', data: text.slice(0,found.index)});
-                tree.push( parseExpression(found[1] ? found[1] : found[2]).tree );
-                text = text.slice(found.index + found[0].length);
-            }
-        }
-        tree.push({type: 'text', data: text});
-        return tree;
-    }
-
-    function parseFunc(name, params, tree)
-    {
-        params.__parsed.name = parseText(name,[])[0];
-        tree.push({
-            type: 'plugin',
-            name: '__func',
-            params: params
-        });
-        return tree;
-    }
-
-    function parseOperator(op, type, precedence, tree)
-    {
-        tree.push({
-            type: 'build-in',
-            name: 'operator',
-            op: op,
-            optype: type,
-            precedence: precedence,
-            params: {}
-        });
-    }
-
-    function parseVar(s, e, nm)
-    {
-        var rootName = e.token;
-        var parts = [{type:'text', data:nm.replace(/^(\w+)@(key|index|iteration|first|last|show|total)/gi, "$1__$2")}];
-
-        var re = /^(?:\.|\s*->\s*|\[\s*)/;
-        for (var op=s.match(re); op; op=s.match(re))
-        {
-            e.token += op[0];
-            s = s.slice(op[0].length);
-
-            var eProp = {value:'', tree:[]};
-            if (op[0].match(/\[/))
-            {
-                eProp = parseExpression(s);
-                if (eProp)
-                {
-                    e.token += eProp.value;
-                    parts.push( eProp.tree );
-                    s = s.slice(eProp.value.length);
-                }
-
-                var closeOp = s.match(/\s*\]/);
-                if (closeOp)
-                {
-                    e.token += closeOp[0];
-                    s = s.slice(closeOp[0].length);
-                }
-            }
-            else
-            {
-                var parseMod = parseModifiers.stop;
-                parseModifiers.stop = true;
-                if (lookUp(s,eProp))
-                {
-                    e.token += eProp.value;
-                    var part = eProp.tree[0];
-                    if (part.type == 'plugin' && part.name == '__func')
-                    {
-                        part.hasOwner = true;
-                    }
-                    parts.push( part );
-                    s = s.slice(eProp.value.length);
-                }
-                else
-                {
-                    eProp = false;
-                }
-                parseModifiers.stop = parseMod;
-            }
-
-            if (!eProp)
-            {
-                parts.push({type:'text', data:''});
-            }
-        }
-
-        e.tree.push({type: 'var', parts: parts});
-
-        e.value += e.token.substr(rootName.length);
-
-        onParseVar(e.token);
-
-        return s;
-    }
-
-    function onParseVar(nm)  {}
-
-
-    var tokens =
-        [
-            {
-                re: /^\$([\w@]+)/,   //var
-                parse: function(e, s)
-                {
-                    parseModifiers(parseVar(s, e, RegExp.$1), e);
-                }
-            },
-            {
-                re: /^(true|false)/i,  //bool
-                parse: function(e, s)
-                {
-                    parseText(e.token.match(/true/i) ? '1' : '', e.tree);
-                }
-            },
-            {
-                re: /^'([^'\\]*(?:\\.[^'\\]*)*)'/, //single quotes
-                parse: function(e, s)
-                {
-                    parseText(evalString(RegExp.$1), e.tree);
-                    parseModifiers(s, e);
-                }
-            },
-            {
-                re: /^"([^"\\]*(?:\\.[^"\\]*)*)"/,  //double quotes
-                parse: function(e, s)
-                {
-                    var v = evalString(RegExp.$1);
-                    var isVar = v.match(tokens[0].re);
-                    if (isVar)
-                    {
-                        var eVar = {token:isVar[0], tree:[]};
-                        parseVar(v, eVar, isVar[1]);
-                        if (eVar.token.length == v.length)
-                        {
-                            e.tree.push( eVar.tree[0] );
-                            return;
-                        }
-                    }
-                    parseText.parseEmbeddedVars = true;
-                    e.tree.push({
-                        type: 'plugin',
-                        name: '__quoted',
-                        params: {__parsed: parse(v,[])}
-                    });
-                    parseText.parseEmbeddedVars = false;
-                    parseModifiers(s, e);
-                }
-            },
-            {
-                re: /^(\w+)\s*[(]([)]?)/,  //func()
-                parse: function(e, s)
-                {
-                    var fnm = RegExp.$1;
-                    var noArgs = RegExp.$2;
-                    var params = parseParams(noArgs?'':s,/^\s*,\s*/);
-                    parseFunc(fnm, params, e.tree);
-                    e.value += params.toString();
-                    parseModifiers(s.slice(params.toString().length), e);
-                }
-            },
-            {
-                re: /^\s*\(\s*/,  //expression in parentheses
-                parse: function(e, s)
-                {
-                    var parens = [];
-                    e.tree.push(parens);
-                    parens.parent = e.tree;
-                    e.tree = parens;
-                }
-            },
-            {
-                re: /^\s*\)\s*/,
-                parse: function(e, s)
-                {
-                    if (e.tree.parent) //it may be the end of func() or (expr)
-                    {
-                        e.tree = e.tree.parent;
-                    }
-                }
-            },
-            {
-                re: /^\s*(\+\+|--)\s*/,
-                parse: function(e, s)
-                {
-                    if (e.tree.length && e.tree[e.tree.length-1].type == 'var')
-                    {
-                        parseOperator(RegExp.$1, 'post-unary', 1, e.tree);
-                    }
-                    else
-                    {
-                        parseOperator(RegExp.$1, 'pre-unary', 1, e.tree);
-                    }
-                }
-            },
-            {
-                re: /^\s*(===|!==|==|!=)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1, 'binary', 6, e.tree);
-                }
-            },
-            {
-                re: /^\s+(eq|ne|neq)\s+/i,
-                parse: function(e, s)
-                {
-                    var op = RegExp.$1.replace(/ne(q)?/,'!=').replace(/eq/,'==');
-                    parseOperator(op, 'binary', 6, e.tree);
-                }
-            },
-            {
-                re: /^\s*!\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator('!', 'pre-unary', 2, e.tree);
-                }
-            },
-            {
-                re: /^\s+not\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator('!', 'pre-unary', 2, e.tree);
-                }
-            },
-            {
-                re: /^\s*(=|\+=|-=|\*=|\/=|%=)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1, 'binary', 10, e.tree);
-                }
-            },
-            {
-                re: /^\s*(\*|\/|%)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1, 'binary', 3, e.tree);
-                }
-            },
-            {
-                re: /^\s+mod\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator('%', 'binary', 3, e.tree);
-                }
-            },
-            {
-                re: /^\s*(\+|-)\s*/,
-                parse: function(e, s)
-                {
-                    if (!e.tree.length || e.tree[e.tree.length-1].name == 'operator')
-                    {
-                        parseOperator(RegExp.$1, 'pre-unary', 4, e.tree);
-                    }
-                    else
-                    {
-                        parseOperator(RegExp.$1, 'binary', 4, e.tree);
-                    }
-                }
-            },
-            {
-                re: /^\s*(<=|>=|<>|<|>)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1.replace(/<>/,'!='), 'binary', 5, e.tree);
-                }
-            },
-            {
-                re: /^\s+(lt|lte|le|gt|gte|ge)\s+/i,
-                parse: function(e, s)
-                {
-                    var op = RegExp.$1.replace(/lt/,'<').replace(/l(t)?e/,'<=').replace(/gt/,'>').replace(/g(t)?e/,'>=');
-                    parseOperator(op, 'binary', 5, e.tree);
-                }
-            },
-            {
-                re: /^\s+(is\s+(not\s+)?div\s+by)\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$2?'div_not':'div', 'binary', 7, e.tree);
-                }
-            },
-            {
-                re: /^\s+is\s+(not\s+)?(even|odd)(\s+by\s+)?\s*/i,
-                parse: function(e, s)
-                {
-                    var op = RegExp.$1 ? ((RegExp.$2=='odd')?'even':'even_not') : ((RegExp.$2=='odd')?'even_not':'even');
-                    parseOperator(op, 'binary', 7, e.tree);
-                    if (!RegExp.$3)
-                    {
-                        parseText('1', e.tree);
-                    }
-                }
-            },
-            {
-                re: /^\s*(&&)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1, 'binary', 8, e.tree);
-                }
-            },
-            {
-                re: /^\s*(\|\|)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1, 'binary', 9, e.tree);
-                }
-            },
-            {
-                re: /^\s+and\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator('&&', 'binary', 11, e.tree);
-                }
-            },
-            {
-                re: /^\s+xor\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator('xor', 'binary', 12, e.tree);
-                }
-            },
-            {
-                re: /^\s+or\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator('||', 'binary', 13, e.tree);
-                }
-            },
-            {
-                re: /^#(\w+)#/,  //config variable
-                parse: function(e, s)
-                {
-                    var eVar = {token:'$smarty',tree:[]};
-                    parseVar('.config.'+RegExp.$1, eVar, 'smarty');
-                    e.tree.push( eVar.tree[0] );
-                    parseModifiers(s, e);
-                }
-            },
-            {
-                re: /^\s*\[\s*/,   //array
-                parse: function(e, s)
-                {
-                    var params = parseParams(s, /^\s*,\s*/, /^('[^'\\]*(?:\\.[^'\\]*)*'|"[^"\\]*(?:\\.[^"\\]*)*"|\w+)\s*=>\s*/);
-                    parsePluginFunc('__array',params,e.tree);
-                    e.value += params.toString();
-                    var paren = s.slice(params.toString().length).match(/\s*\]/);
-                    if (paren)
-                    {
-                        e.value += paren[0];
-                    }
-                }
-            },
-            {
-                re: /^[\d.]+/, //number
-                parse: function(e, s)
-                {
-                    if (e.token.indexOf('.') > -1) {
-                        e.token = parseFloat(e.token);
-                    } else {
-                        e.token = parseInt(e.token, 10);
-                    }
-                    parseText(e.token, e.tree);
-                    parseModifiers(s, e);
-                }
-            },
-            {
-                re: /^\w+/, //static
-                parse: function(e, s)
-                {
-                    parseText(e.token, e.tree);
-                    parseModifiers(s, e);
-                }
-            }
-        ];
-
-    function parseModifiers(s, e)
-    {
-        if (parseModifiers.stop)
-        {
-            return;
-        }
-
-        var modifier = s.match(/^\|(\w+)/);
-        if (!modifier)
-        {
-            return;
-        }
-
-        e.value += modifier[0];
-
-        var fnm = modifier[1]=='default' ? 'defaultValue' : modifier[1];
-        s = s.slice(modifier[0].length).replace(/^\s+/,'');
-
-        parseModifiers.stop = true;
-        var params = [];
-        for (var colon=s.match(/^\s*:\s*/); colon; colon=s.match(/^\s*:\s*/))
-        {
-            e.value += s.slice(0,colon[0].length);
-            s = s.slice(colon[0].length);
-
-            var param = {value:'', tree:[]};
-            if (lookUp(s, param))
-            {
-                e.value += param.value;
-                params.push(param.tree[0]);
-                s = s.slice(param.value.length);
-            }
-            else
-            {
-                parseText('',params);
-            }
-        }
-        parseModifiers.stop = false;
-
-        params.unshift(e.tree.pop());  //modifiers have the highest priority
-        e.tree.push(parseFunc(fnm,{__parsed:params},[])[0]);
-
-        parseModifiers(s, e);  //modifiers can be combined
-    }
-
-    function lookUp(s,e)
-    {
-        if (!s)
-        {
-            return false;
-        }
-
-        if (s.substr(0,jSmart.prototype.left_delimiter.length)==jSmart.prototype.left_delimiter)
-        {
-            var tag = findTag('',s);
-            if (tag)
-            {
-                e.token = tag[0];
-                e.value += tag[0];
-                parse(tag[0], e.tree);
-                parseModifiers(s.slice(e.value.length), e);
-                return true;
-            }
-        }
-
-        for (var i=0; i<tokens.length; ++i)
-        {
-            if (s.match(tokens[i].re))
-            {
-                e.token = RegExp.lastMatch;
-                e.value += RegExp.lastMatch;
-                tokens[i].parse(e, s.slice(e.token.length));
-                return true;
-            }
-        }
-        return false;
-    }
-
-    function bundleOp(i, tree, precedence)
-    {
-        var op = tree[i];
-        if (op.name == 'operator' && op.precedence == precedence && !op.params.__parsed)
-        {
-            if (op.optype == 'binary')
-            {
-                op.params.__parsed = [tree[i-1],tree[i+1]];
-                tree.splice(i-1,3,op);
-                return true;
-            }
-            else if (op.optype == 'post-unary')
-            {
-                op.params.__parsed = [tree[i-1]];
-                tree.splice(i-1,2,op);
-                return true;
-            }
-
-            op.params.__parsed = [tree[i+1]];
-            tree.splice(i,2,op);
-        }
-        return false;
-    }
-
-    function composeExpression(tree)
-    {
-        var i = 0;
-        for (i=0; i<tree.length; ++i)
-        {
-            if (tree[i] instanceof Array)
-            {
-                tree[i] = composeExpression(tree[i])
-            }
-        }
-
-        for (var precedence=1; precedence<14; ++precedence)
-        {
-            if (precedence==2 || precedence==10)
-            {
-                for (i=tree.length; i>0; --i)
-                {
-                    i -= bundleOp(i-1, tree, precedence);
-                }
-            }
-            else
-            {
-                for (i=0; i<tree.length; ++i)
-                {
-                    i -= bundleOp(i, tree, precedence);
-                }
-            }
-        }
-        return tree[0]; //only one node must be left
-    }
-
-    function parseExpression(s)
-    {
-        var e = { value:'', tree:[] };
-        while (lookUp(s.slice(e.value.length), e)){}
-        if (!e.tree.length)
-        {
-            return false;
-        }
-        e.tree = composeExpression(e.tree);
-        return e;
-    }
-
-    function parseParams(paramsStr, reDelim, reName)
-    {
-        var s = paramsStr.replace(/\n/g,' ').replace(/^\s+|\s+$/g,'');
-        var params = [];
-        params.__parsed = [];
-        var paramsStr = '';
-
-        if (!s)
-        {
-            return params;
-        }
-
-        if (!reDelim)
-        {
-            reDelim = /^\s+/;
-            reName = /^(\w+)\s*=\s*/;
-        }
-
-        while (s)
-        {
-            var nm = null;
-            if (reName)
-            {
-                var foundName = s.match(reName);
-                if (foundName)
-                {
-                    nm = trimQuotes(foundName[1]);
-                    paramsStr += s.slice(0,foundName[0].length);
-                    s = s.slice(foundName[0].length);
-                }
-            }
-
-            var param = parseExpression(s);
-            if (!param)
-            {
-                break;
-            }
-
-            if (nm)
-            {
-                params[nm] = param.value;
-                params.__parsed[nm] = param.tree;
-            }
-            else
-            {
-                params.push(param.value);
-                params.__parsed.push(param.tree);
-            }
-
-            paramsStr += s.slice(0,param.value.length);
-            s = s.slice(param.value.length);
-
-            var foundDelim = s.match(reDelim);
-            if (foundDelim)
-            {
-                paramsStr += s.slice(0,foundDelim[0].length);
-                s = s.slice(foundDelim[0].length);
-            }
-            else
-            {
-                break;
-            }
-        }
-        params.toString = function() { return paramsStr; }
-        return params;
-    }
-
-    function parsePluginBlock(name, params, tree, content)
-    {
-        tree.push({
-            type: 'plugin',
-            name: name,
-            params: params,
-            subTree: parse(content,[])
-        });
-    }
-
-    function parsePluginFunc(name, params, tree)
-    {
-        tree.push({
-            type: 'plugin',
-            name: name,
-            params: params
-        });
-    }
-
-    function getActualParamValues(params,data)
-    {
-        var actualParams = [];
-        for (var nm in params.__parsed)
-        {
-            if (params.__parsed.hasOwnProperty(nm))
-            {
-                var v = process([params.__parsed[nm]], data);
-                actualParams[nm] = v;
-            }
-        }
-
-        actualParams.__get = function(nm,defVal,id)
-        {
-            if (nm in actualParams && typeof(actualParams[nm]) != 'undefined')
-            {
-                return actualParams[nm];
-            }
-            if (typeof(id)!='undefined' && typeof(actualParams[id]) != 'undefined')
-            {
-                return actualParams[id];
-            }
-            if (defVal === null)
-            {
-                throw new Error("The required attribute '"+nm+"' is missing");
-            }
-            return defVal;
-        };
-        return actualParams;
-    }
-
-    /**
-     * Returns boolean true if object is empty otherwise false.
-     *
-     * @param object hash Object you are testing against.
-     *
-     * @return boolean
-     */
-    function isEmptyObject(hash) {
-        for (var i in hash) {
-            if (hash.hasOwnProperty(i)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    function getVarValue(node, data, val)
-    {
-        var v = data;
-        var nm = '';
-        for (var i=0; i<node.parts.length; ++i)
-        {
-            var part = node.parts[i];
-            if (part.type == 'plugin' && part.name == '__func' && part.hasOwner)
-            {
-                data.__owner = v;
-                v = process([node.parts[i]],data);
-                delete data.__owner;
-            }
-            else
-            {
-                nm = process([part],data);
-
-                //section name
-                if (nm in data.smarty.section && part.type=='text' && process([node.parts[0]],data)!='smarty')
-                {
-                    nm = data.smarty.section[nm].index;
-                }
-
-                //add to array
-                if (!nm && typeof val != 'undefined' && v instanceof Array)
-                {
-                    nm = v.length;
-                }
-
-                //set new value
-                if (typeof val != 'undefined' && i==node.parts.length-1)
-                {
-                    v[nm] = val;
-                }
-
-                if (typeof v == 'object' && v !== null && nm in v)
-                {
-                    v = v[nm];
-                }
-                else
-                {
-                    if (typeof val == 'undefined')
-                    {
-                        return val;
-                    }
-                    v[nm] = {};
-                    v = v[nm];
-                }
-            }
-        }
-        return v;
-    }
-
-    function process(tree, data)
-    {
-        var res = '';
-        for (var i=0; i<tree.length; ++i)
-        {
-            var s = '';
-            var node = tree[i];
-            if (node.type == 'text')
-            {
-                s = node.data;
-            }
-            else if (node.type == 'var')
-            {
-                s = getVarValue(node,data);
-            }
-            else if (node.type == 'build-in')
-            {
-                s = buildInFunctions[node.name].process(node,data);
-            }
-            else if (node.type == 'plugin')
-            {
-                var plugin = plugins[node.name];
-                if (plugin.type == 'block')
-                {
-                    var repeat = {value:true};
-                    plugin.process(getActualParamValues(node.params,data), '', data, repeat);
-                    while (repeat.value)
-                    {
-                        repeat.value = false;
-                        s += plugin.process(
-                            getActualParamValues(node.params,data),
-                            process(node.subTree, data),
-                            data,
-                            repeat
-                        );
-                    }
-                }
-                else if (plugin.type == 'function')
-                {
-                    s = plugin.process(getActualParamValues(node.params,data), data);
-                }
-            }
-            if (typeof s == 'boolean')
-            {
-                s = s ? '1' : '';
-            }
-            if (s == null) {
-                s = '';
-            }
-            if (tree.length == 1)
-            {
-                return s;
-            }
-            res += s!==null ? s : '';
-
-            if (data.smarty['continue'] || data.smarty['break'])
-            {
-                return res;
-            }
-        }
-        return res;
-    }
-
-    function getTemplate(name, tree, nocache)
-    {
-        if (nocache || !(name in files))
-        {
-            var tpl = jSmart.prototype.getTemplate(name);
-            if (typeof(tpl) != 'string')
-            {
-                throw new Error('No template for '+ name);
-            }
-            parse(applyFilters(jSmart.prototype.filters_global.pre, stripComments(tpl.replace(/\r\n/g,'\n'))), tree);
-            files[name] = tree;
-        }
-        else
-        {
-            tree = files[name];
-        }
-        return tree;
-    }
-
-    function stripComments(s)
-    {
-        var sRes = '';
-        for (var openTag=s.match(/{{\*/); openTag; openTag=s.match(/{{\*/))
-        {
-            sRes += s.slice(0,openTag.index);
-            s = s.slice(openTag.index+openTag[0].length);
-            var closeTag = s.match(/\*}}/);
-            if (!closeTag)
-            {
-                throw new Error('Unclosed {*');
-            }
-            s = s.slice(closeTag.index+closeTag[0].length);
-        }
-        return sRes + s;
-    }
-
-    function applyFilters(filters, s)
-    {
-        for (var i=0; i<filters.length; ++i)
-        {
-            s = filters[i](s);
-        }
-        return s;
-    }
-
-
-    jSmart = function(tpl)
-    {
-        this.tree = [];
-        this.tree.blocks = {};
-        this.scripts = {};
-        this.default_modifiers = [];
-        this.filters = {'variable':[], 'post':[]};
-        this.smarty = {
-            'smarty': {
-                block: {},
-                'break': false,
-                capture: {},
-                'continue': false,
-                counter: {},
-                cycle: {},
-                foreach: {},
-                section: {},
-                now: Math.floor( (new Date()).getTime()/1000 ),
-                'const': {},
-                config: {},
-                current_dir: '/',
-                template: '',
-                ldelim: jSmart.prototype.left_delimiter,
-                rdelim: jSmart.prototype.right_delimiter,
-                version: '2.15.0'
-            }
-        };
-        blocks = this.tree.blocks;
-        parse(
-            applyFilters(jSmart.prototype.filters_global.pre, stripComments((new String(tpl?tpl:'')).replace(/\r\n/g,'\n'))),
-            this.tree
-        );
-    };
-
-    jSmart.prototype.fetch = function(data)
-    {
-        blocks = this.tree.blocks;
-        scripts = this.scripts;
-        escape_html = this.escape_html;
-        default_modifiers = jSmart.prototype.default_modifiers_global.concat(this.default_modifiers);
-        this.data = obMerge((typeof data == 'object') ? data : {}, this.smarty);
-        varFilters = jSmart.prototype.filters_global.variable.concat(this.filters.variable);
-        var res = process(this.tree, this.data);
-        if (jSmart.prototype.debugging)
-        {
-            plugins.debug.process([],this.data);
-        }
-        return applyFilters(jSmart.prototype.filters_global.post.concat(this.filters.post), res);
-    };
-
-    jSmart.prototype.escape_html = false;
-
-    /**
-       @param type  valid values are 'function', 'block', 'modifier'
-       @param callback  func(params,data)  or  block(params,content,data,repeat)
-    */
-    jSmart.prototype.registerPlugin = function(type, name, callback)
-    {
-        if (type == 'modifier')
-        {
-            modifiers[name] = callback;
-        }
-        else
-        {
-            plugins[name] = {'type': type, 'process': callback};
-        }
-    };
-
-    /**
-       @param type  valid values are 'pre', 'variable', 'post'
-       @param callback function(textValue) { ... }
-    */
-    jSmart.prototype.registerFilter = function(type, callback)
-    {
-        (this.tree ? this.filters : jSmart.prototype.filters_global)[type=='output'?'post':type].push(callback);
-    }
-
-    jSmart.prototype.filters_global = {'pre':[],'variable':[],'post':[]};
-
-    jSmart.prototype.configLoad = function(confValues, section, data)
-    {
-        data = data ? data : this.data;
-        var s = confValues.replace(/\r\n/g,'\n').replace(/^\s+|\s+$/g,'');
-        var re = /^\s*(?:\[([^\]]+)\]|(?:(\w+)[ \t]*=[ \t]*("""|'[^'\\\n]*(?:\\.[^'\\\n]*)*'|"[^"\\\n]*(?:\\.[^"\\\n]*)*"|[^\n]*)))/m;
-        var currSect = '';
-        for (var f=s.match(re); f; f=s.match(re))
-        {
-                s = s.slice(f.index+f[0].length);
-                if (f[1])
-                {
-                         currSect = f[1];
-                }
-                else if ((!currSect || currSect == section) && currSect.substr(0,1) != '.')
-                {
-                         if (f[3] == '"""')
-                         {
-                                  var triple = s.match(/"""/);
-                                  if (triple)
-                                  {
-                                           data.smarty.config[f[2]] = s.slice(0,triple.index);
-                                           s = s.slice(triple.index + triple[0].length);
-                                  }
-                         }
-                         else
-                         {
-                                  data.smarty.config[f[2]] = trimQuotes(f[3]);
-                         }
-                }
-                var newln = s.match(/\n+/);
-                if (newln)
-                {
-                         s = s.slice(newln.index + newln[0].length);
-                }
-                else
-                {
-                         break;
-                }
-        }
-    }
-
-    jSmart.prototype.clearConfig = function(varName)
-    {
-        if (varName)
-        {
-            delete this.data.smarty.config[varName];
-        }
-        else
-        {
-            this.data.smarty.config = {};
-        }
-    }
-
-    /**
-       add modifier to implicitly apply to every variable in a template
-       @param modifiers  single string (e.g. "replace:'from':'to'")
-                         or array of strings (e.g. ['escape:"htmlall"', "replace:'from':'to'"])
-     */
-    jSmart.prototype.addDefaultModifier = function(modifiers)
-    {
-        if (!(modifiers instanceof Array))
-        {
-            modifiers = [modifiers];
-        }
-
-        for (var i=0; i<modifiers.length; ++i)
-        {
-            var e = { value:'', tree:[0] };
-            parseModifiers('|'+modifiers[i], e);
-            (this.tree ? this.default_modifiers : this.default_modifiers_global).push( e.tree[0] );
-        }
-    }
-
-    jSmart.prototype.default_modifiers_global = [];
-
-    /**
-       override this function
-       @param name  value of 'file' parameter in {include} and {extends}
-       @return template text
-    */
-    jSmart.prototype.getTemplate = function(name)
-    {
-        throw new Error('No template for ' + name);
-    }
-
-    /**
-       override this function
-       @param name  value of 'file' parameter in {fetch}
-       @return file content
-    */
-    jSmart.prototype.getFile = function(name)
-    {
-        throw new Error('No file for ' + name);
-    }
-
-    /**
-       override this function
-       @param name  value of 'file' parameter in {include_php} and {include_javascript}
-                     or value of 'script' parameter in {insert}
-       @return Javascript script
-    */
-    jSmart.prototype.getJavascript = function(name)
-    {
-        throw new Error('No Javascript for ' + name);
-    }
-
-    /**
-       override this function
-       @param name  value of 'file' parameter in {config_load}
-       @return config file content
-    */
-    jSmart.prototype.getConfig = function(name)
-    {
-        throw new Error('No config for ' + name);
-    }
-
-
-
-    /**
-       whether to skip tags in open brace { followed by white space(s) and close brace } with white space(s) before
-    */
-    jSmart.prototype.auto_literal = true;
-
-    jSmart.prototype.left_delimiter = '{';
-    jSmart.prototype.right_delimiter = '}';
-
-    /** enables the debugging console */
-    jSmart.prototype.debugging = false;
-
-
-    jSmart.prototype.PHPJS = function(fnm, modifier)
-    {
-        if (eval('typeof '+fnm) == 'function')
-        {
-            return (typeof window == 'object') ? window : global;
-        }
-        else if (typeof(PHP_JS) == 'function')
-        {
-            return new PHP_JS();
-        }
-        throw new Error("Modifier '" + modifier + "' uses JavaScript port of PHP function '" + fnm + "'. You can find one at http://phpjs.org");
-    }
-
-    jSmart.prototype.makeTimeStamp = function(s)
-    {
-        if (!s)
-        {
-            return Math.floor( (new Date()).getTime()/1000 );
-        }
-        if (isNaN(s))
-        {
-            var tm = jSmart.prototype.PHPJS('strtotime','date_format').strtotime(s);
-            if (tm == -1 || tm === false) {
-                return Math.floor( (new Date()).getTime()/1000 );
-            }
-            return tm;
-        }
-        s = new String(s);
-        if (s.length == 14) //mysql timestamp format of YYYYMMDDHHMMSS
-        {
-            return Math.floor( (new Date(s.substr(0,4),s.substr(4,2)-1,s.substr(6,2),s.substr(8,2),s.substr(10,2)).getTime()/1000 ) );
-        }
-        return parseInt(s);
-    }
-
-
-
-    /**
-       register custom functions
-    */
-    jSmart.prototype.registerPlugin(
-        'function',
-        '__array',
-        function(params, data)
-        {
-            var a = [];
-            for (var nm in params)
-            {
-                if (params.hasOwnProperty(nm) && params[nm] && typeof params[nm] != 'function')
-                {
-                    a[nm] = params[nm];
-                }
-            }
-            return a;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        '__func',
-        function(params, data) {
-            var paramNames = [], paramValues = {}, paramData = [];
-            for (var i=0; i<params.length; ++i) {
-                paramNames.push(params.name+'__p'+i);
-                paramData.push(params[i]);
-                paramValues[params.name+'__p'+i] = params[i];
-            }
-            var fname, mergedParams = obMerge({}, data, paramValues);
-            if (('__owner' in data && params.name in data.__owner)) {
-                fname = '__owner.'+params.name;
-                return execute(fname + '(' + paramNames.join(',') + ')', mergedParams);
-            } else if (modifiers.hasOwnProperty(params.name)) {
-                fname = modifiers[params.name]
-                return executeByFuncObject(fname, paramData, mergedParams);
-            } else {
-                fname = params.name;
-                return execute(fname + '(' + paramNames.join(',') + ')', mergedParams);
-            }
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        '__quoted',
-        function(params, data)
-        {
-            return params.join('');
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'append',
-        function(params, data)
-        {
-            var varName = params.__get('var',null,0);
-            if (!(varName in data) || !(data[varName] instanceof Array))
-            {
-                data[varName] = [];
-            }
-            var index = params.__get('index',false);
-            var val = params.__get('value',null,1);
-            if (index === false)
-            {
-                data[varName].push(val);
-            }
-            else
-            {
-                data[varName][index] = val;
-            }
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'assign',
-        function(params, data)
-        {
-            assignVar(params.__get('var',null,0), params.__get('value',null,1), data);
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'break',
-        function(params, data)
-        {
-            data.smarty['break'] = true;
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'call',
-        function(params, data)
-        {
-            var fname = params.__get('name',null,0);
-            delete params.name;
-            var assignTo = params.__get('assign',false);
-            delete params.assign;
-            var s = plugins[fname].process(params, data);
-            if (assignTo)
-            {
-                assignVar(assignTo, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'block',
-        'capture',
-        function(params, content, data, repeat)
-        {
-            if (content)
-            {
-                content = content.replace(/^\n/,'');
-                data.smarty.capture[params.__get('name','default',0)] = content;
-
-                if ('assign' in params)
-                {
-                    assignVar(params.assign, content, data);
-                }
-
-                var append = params.__get('append',false);
-                if (append)
-                {
-                    if (append in data)
-                    {
-                        if (data[append] instanceof Array)
-                        {
-                            data[append].push(content);
-                        }
-                    }
-                                       else
-                                       {
-                                                data[append] = [content];
-                                       }
-                }
-            }
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'continue',
-        function(params, data)
-        {
-            data.smarty['continue'] = true;
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'counter',
-        function(params, data)
-        {
-            var name = params.__get('name','default');
-            if (name in data.smarty.counter)
-            {
-                var counter = data.smarty.counter[name];
-                if ('start' in params)
-                {
-                    counter.value = parseInt(params['start']);
-                }
-                else
-                {
-                    counter.value = parseInt(counter.value);
-                    counter.skip = parseInt(counter.skip);
-                    if ('down' == counter.direction)
-                    {
-                        counter.value -= counter.skip;
-                    }
-                    else
-                    {
-                        counter.value += counter.skip;
-                    }
-                }
-                counter.skip = params.__get('skip',counter.skip);
-                counter.direction = params.__get('direction',counter.direction);
-                counter.assign = params.__get('assign',counter.assign);
-            }
-            else
-            {
-                data.smarty.counter[name] = {
-                    value: parseInt(params.__get('start',1)),
-                    skip: parseInt(params.__get('skip',1)),
-                    direction: params.__get('direction','up'),
-                    assign: params.__get('assign',false)
-                };
-            }
-
-            if (data.smarty.counter[name].assign)
-            {
-                data[data.smarty.counter[name].assign] = data.smarty.counter[name].value;
-                return '';
-            }
-
-            if (params.__get('print',true))
-            {
-                return data.smarty.counter[name].value;
-            }
-
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'cycle',
-        function(params, data)
-        {
-            var name = params.__get('name','default');
-            var reset = params.__get('reset',false);
-            if (!(name in data.smarty.cycle))
-            {
-                data.smarty.cycle[name] = {arr: [''], delimiter: params.__get('delimiter',','), index: 0};
-                reset = true;
-            }
-
-            if (params.__get('delimiter',false))
-            {
-                data.smarty.cycle[name].delimiter = params.delimiter;
-            }
-            var values = params.__get('values',false);
-            if (values)
-            {
-                var arr = [];
-                if (values instanceof Object)
-                {
-                    for (nm in values)
-                    {
-                        arr.push(values[nm]);
-                    }
-                }
-                else
-                {
-                    arr = values.split(data.smarty.cycle[name].delimiter);
-                }
-
-                if (arr.length != data.smarty.cycle[name].arr.length || arr[0] != data.smarty.cycle[name].arr[0])
-                {
-                    data.smarty.cycle[name].arr = arr;
-                    data.smarty.cycle[name].index = 0;
-                    reset = true;
-                }
-            }
-
-            if (params.__get('advance','true'))
-            {
-                data.smarty.cycle[name].index += 1;
-            }
-            if (data.smarty.cycle[name].index >= data.smarty.cycle[name].arr.length || reset)
-            {
-                data.smarty.cycle[name].index = 0;
-            }
-
-            if (params.__get('assign',false))
-            {
-                assignVar(params.assign, data.smarty.cycle[name].arr[ data.smarty.cycle[name].index ], data);
-                return '';
-            }
-
-            if (params.__get('print',true))
-            {
-                return data.smarty.cycle[name].arr[ data.smarty.cycle[name].index ];
-            }
-
-            return '';
-        }
-    );
-
-    jSmart.prototype.print_r = function(v,indent)
-    {
-        if (v instanceof Object)
-        {
-            var s = ((v instanceof Array) ? 'Array['+v.length+']' : 'Object') + '<br>';
-            for (var nm in v)
-            {
-                if (v.hasOwnProperty(nm))
-                {
-                    s += indent + '&nbsp;&nbsp;<strong>' + nm + '</strong> : ' + jSmart.prototype.print_r(v[nm],indent+'&nbsp;&nbsp;&nbsp;') + '<br>';
-                }
-            }
-            return s;
-        }
-        return v;
-    }
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'debug',
-        function(params, data)
-        {
-            if (typeof dbgWnd != 'undefined')
-            {
-                dbgWnd.close();
-            }
-            dbgWnd = window.open('','','width=680,height=600,resizable,scrollbars=yes');
-            var sVars = '';
-            var i=0;
-            for (var nm in data)
-            {
-                sVars += '<tr class=' + (++i%2?'odd':'even') + '><td><strong>' + nm + '</strong></td><td>' + jSmart.prototype.print_r(data[nm],'') + '</td></tr>';
-            }
-            dbgWnd.document.write(" \
-               <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'> \
-               <head> \
-                           <title>jSmart Debug Console</title> \
-                  <style type='text/css'> \
-                     table {width: 100%;} \
-                     td {vertical-align:top;width: 50%;} \
-                     .even td {background-color: #fafafa;} \
-                  </style> \
-               </head> \
-               <body> \
-                  <h1>jSmart Debug Console</h1> \
-                  <h2>assigned template variables</h2> \
-                  <table>" + sVars + "</table> \
-               </body> \
-               </html> \
-            ");
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'eval',
-        function(params, data)
-        {
-            var tree = [];
-            parse(params.__get('var','',0), tree);
-            var s = process(tree, data);
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'fetch',
-        function(params, data)
-        {
-            var s = jSmart.prototype.getFile(params.__get('file',null,0));
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_checkboxes',
-        function (params, data) {
-            var type = params.__get('type','checkbox'),
-                name = params.__get('name',type),
-                realName = params.__get('name',type),
-                values = params.__get('values',params.options),
-                output = params.__get('options',[]),
-                useName = ('options' in params),
-                selected = params.__get('selected',false),
-                separator = params.__get('separator',''),
-                labels = Boolean(params.__get('labels',true)),
-                label_ids = Boolean(params.__get('label_ids',false)),
-                p,
-                res = [],
-                i = 0,
-                s = '',
-                value,
-                id;
-
-            if (type == 'checkbox') {
-                name += '[]';
-            }
-            if (!useName) {
-                for (p in params.output) {
-                    output.push(params.output[p]);
-                }
-            }
-
-            for (p in values) {
-                if (values.hasOwnProperty(p)) {
-                    value = (useName ? p : values[p]);
-                    id = realName + '_' + value;
-                    s = (labels ? ( label_ids ? '<label for="'+id+'">' : '<label>') : '');
-
-                    s += '<input type="' + type + '" name="' + name + '" value="' + value + '" ';
-                    if (label_ids) {
-                        s += 'id="'+id+'" ';
-                    }
-                    if (selected == (useName ? p : values[p])) {
-                        s += 'checked="checked" ';
-                    }
-                    s += '/>' + output[useName?p:i++];
-                    s += (labels ? '</label>' : '');
-                    s += separator;
-                    res.push(s);
-                }
-            }
-            if ('assign' in params) {
-                assignVar(params.assign, res, data);
-                return '';
-            }
-            return res.join('\n');
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_image',
-        function (params, data) {
-            var url = params.__get('file', null),
-                width = params.__get('width', false),
-                height = params.__get('height', false),
-                alt = params.__get('alt', ''),
-                href = params.__get('href', params.__get('link', false)),
-                path_prefix = params.__get('path_prefix', ''),
-                paramNames = {file:1, width:1, height:1, alt:1, href:1, basedir:1, path_prefix:1, link:1},
-                s = '<img src="' + path_prefix + url + '"' + ' alt="'+alt+'"' + (width ? ' width="'+width+'"':'') + (height ? ' height="'+height+'"':''),
-                p;
-
-            for (p in params) {
-                if (params.hasOwnProperty(p) && typeof(params[p]) == 'string') {
-                    if (!(p in paramNames)) {
-                        s += ' ' + p + '="' + params[p] + '"';
-                    }
-                }
-            }
-            s += ' />';
-            return href ? '<a href="'+href+'">'+s+'</a>' : s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_options',
-        function(params, data)
-        {
-            var values = params.__get('values',params.options);
-            var output = params.__get('options',[]);
-            var useName = ('options' in params);
-            var p;
-            if (!useName)
-            {
-                for (p in params.output)
-                {
-                    output.push(params.output[p]);
-                }
-            }
-            var selected = params.__get('selected',false);
-
-            var res = [];
-            var s = '';
-            var i = 0;
-            for (p in values)
-            {
-                if (values.hasOwnProperty(p))
-                {
-                    s = '<option value="' + (useName ? p : values[p]) + '"';
-                    if (selected == (useName ? p : values[p]))
-                    {
-                        s += ' selected="selected"';
-                    }
-                    s += '>' + output[useName ? p : i++] + '</option>';
-                    res.push(s);
-                }
-            }
-            var name = params.__get('name',false);
-            return (name ? ('<select name="' + name + '">\n' + res.join('\n') + '\n</select>') : res.join('\n')) + '\n';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_radios',
-        function(params, data)
-        {
-            params.type = 'radio';
-            return plugins.html_checkboxes.process(params,data);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_select_date',
-        function(params, data)
-        {
-            var prefix = params.__get('prefix','Date_');
-            var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
-
-            var s = '';
-            s += '<select name="'+prefix+'Month">\n';
-            var i=0;
-            for (i=0; i<months.length; ++i)
-            {
-                s += '<option value="' + i + '">' + months[i] + '</option>\n';
-            }
-            s += '</select>\n'
-
-            s += '<select name="'+prefix+'Day">\n';
-            for (i=0; i<31; ++i)
-            {
-                s += '<option value="' + i + '">' + i + '</option>\n';
-            }
-            s += '</select>\n'
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_table',
-        function(params, data)
-        {
-            var loop = [];
-            var p;
-            if (params.loop instanceof Array)
-            {
-                loop = params.loop
-            }
-            else
-            {
-                for (p in params.loop)
-                {
-                    if (params.loop.hasOwnProperty(p))
-                    {
-                        loop.push( params.loop[p] );
-                    }
-                }
-            }
-            var rows = params.__get('rows',false);
-            var cols = params.__get('cols',false);
-            if (!cols)
-            {
-                cols = rows ? Math.ceil(loop.length/rows) : 3;
-            }
-            var colNames = [];
-            if (isNaN(cols))
-            {
-                if (typeof cols == 'object')
-                {
-                    for (p in cols)
-                    {
-                        if (cols.hasOwnProperty(p))
-                        {
-                            colNames.push(cols[p]);
-                        }
-                    }
-                }
-                else
-                {
-                    colNames = cols.split(/\s*,\s*/);
-                }
-                cols = colNames.length;
-            }
-            rows = rows ? rows : Math.ceil(loop.length/cols);
-
-            var inner = params.__get('inner','cols');
-            var caption = params.__get('caption','');
-            var table_attr = params.__get('table_attr','border="1"');
-            var th_attr = params.__get('th_attr',false);
-            if (th_attr && typeof th_attr != 'object')
-            {
-                th_attr = [th_attr];
-            }
-            var tr_attr = params.__get('tr_attr',false);
-            if (tr_attr && typeof tr_attr != 'object')
-            {
-                tr_attr = [tr_attr];
-            }
-            var td_attr = params.__get('td_attr',false);
-            if (td_attr && typeof td_attr != 'object')
-            {
-                td_attr = [td_attr];
-            }
-            var trailpad = params.__get('trailpad','&nbsp;');
-            var hdir = params.__get('hdir','right');
-            var vdir = params.__get('vdir','down');
-
-            var s = '';
-            for (var row=0; row<rows; ++row)
-            {
-                s += '<tr' + (tr_attr ? ' '+tr_attr[row%tr_attr.length] : '') + '>\n';
-                for (var col=0; col<cols; ++col)
-                {
-                    var idx = (inner=='cols') ? ((vdir=='down'?row:rows-1-row) * cols + (hdir=='right'?col:cols-1-col)) : ((hdir=='right'?col:cols-1-col) * rows + (vdir=='down'?row:rows-1-row));
-
-                    s += '<td' + (td_attr ? ' '+td_attr[col%td_attr.length] : '') + '>' + (idx < loop.length ? loop[idx] : trailpad) + '</td>\n';
-                }
-                s += '</tr>\n';
-            }
-
-            var sHead = '';
-            if (colNames.length)
-            {
-                sHead = '\n<thead><tr>';
-                for (var i=0; i<colNames.length; ++i)
-                {
-                    sHead += '\n<th' + (th_attr ? ' '+th_attr[i%th_attr.length] : '') + '>' + colNames[hdir=='right'?i:colNames.length-1-i] + '</th>';
-                }
-                sHead += '\n</tr></thead>';
-            }
-
-            return '<table ' + table_attr + '>' + (caption?'\n<caption>'+caption+'</caption>':'') + sHead + '\n<tbody>\n' + s + '</tbody>\n</table>\n';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'include',
-        function(params, data)
-        {
-            var file = params.__get('file',null,0);
-            var incData = obMerge({},data,params);
-            incData.smarty.template = file;
-            var s = process(getTemplate(file,[],findInArray(params,'nocache')>=0), incData);
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'include_javascript',
-        function(params, data)
-        {
-            var file = params.__get('file',null,0);
-            if (params.__get('once',true) && file in scripts)
-            {
-                return '';
-            }
-            scripts[file] = true;
-            var s = execute(jSmart.prototype.getJavascript(file), {'$this':data});
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'include_php',
-        function(params, data)
-        {
-            return plugins['include_javascript'].process(params,data);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'insert',
-        function(params, data)
-        {
-            var fparams = {};
-            for (var nm in params)
-            {
-                if (params.hasOwnProperty(nm) && isNaN(nm) && params[nm] && typeof params[nm] == 'string' && nm != 'name' && nm != 'assign' && nm != 'script')
-                {
-                    fparams[nm] = params[nm];
-                }
-            }
-            var prefix = 'insert_';
-            if ('script' in params)
-            {
-                eval(jSmart.prototype.getJavascript(params.script));
-                prefix = 'smarty_insert_';
-            }
-            var func = eval(prefix+params.__get('name',null,0));
-            var s = func(fparams, data);
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'block',
-        'javascript',
-        function(params, content, data, repeat)
-        {
-            data['$this'] = data;
-            execute(content,data);
-            delete data['$this'];
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'config_load',
-        function(params, data)
-        {
-            jSmart.prototype.configLoad(jSmart.prototype.getConfig(params.__get('file',null,0)), params.__get('section','',1), data);
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'mailto',
-        function(params, data)
-        {
-            var address = params.__get('address',null);
-            var encode = params.__get('encode','none');
-            var text = params.__get('text',address);
-            var cc = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('cc','')).replace('%40','@');
-            var bcc = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('bcc','')).replace('%40','@');
-            var followupto = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('followupto','')).replace('%40','@');
-            var subject = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode( params.__get('subject','') );
-            var newsgroups = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('newsgroups',''));
-            var extra = params.__get('extra','');
-
-            address += (cc?'?cc='+cc:'');
-            address += (bcc?(cc?'&':'?')+'bcc='+bcc:'');
-            address += (subject ? ((cc||bcc)?'&':'?') + 'subject='+subject : '');
-            address += (newsgroups ? ((cc||bcc||subject)?'&':'?') + 'newsgroups='+newsgroups : '');
-            address += (followupto ? ((cc||bcc||subject||newsgroups)?'&':'?') + 'followupto='+followupto : '');
-
-            s = '<a href="mailto:' + address + '" ' + extra + '>' + text + '</a>';
-
-            if (encode == 'javascript')
-            {
-                s = "document.write('" + s + "');";
-                var sEncoded = '';
-                for (var i=0; i<s.length; ++i)
-                {
-                    sEncoded += '%' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(s.substr(i,1));
-                }
-                return '<script type="text/javascript">eval(unescape(\'' + sEncoded + "'))</script>";
-            }
-            else if (encode == 'javascript_charcode')
-            {
-                var codes = [];
-                for (var i=0; i<s.length; ++i)
-                {
-                    codes.push(jSmart.prototype.PHPJS('ord','mailto').ord(s.substr(i,1)));
-                }
-                return '<script type="text/javascript" language="javascript">\n<!--\n{document.write(String.fromCharCode('
-                    + codes.join(',') + '))}\n//-->\n</script>\n';
-            }
-            else if (encode == 'hex')
-            {
-                if (address.match(/^.+\?.+$/))
-                {
-                    throw new Error('mailto: hex encoding does not work with extra attributes. Try javascript.');
-                }
-                var aEncoded = '';
-                for (var i=0; i<address.length; ++i)
-                {
-                    if (address.substr(i,1).match(/\w/))
-                    {
-                        aEncoded += '%' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(address.substr(i,1));
-                    }
-                    else
-                    {
-                        aEncoded += address.substr(i,1);
-                    }
-                }
-                aEncoded = aEncoded.toLowerCase();
-                var tEncoded = '';
-                for (var i=0; i<text.length; ++i)
-                {
-                    tEncoded += '&#x' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(text.substr(i,1)) + ';';
-                }
-                tEncoded = tEncoded.toLowerCase();
-                return '<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;' + aEncoded + '" ' + extra + '>' + tEncoded + '</a>';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'math',
-        function(params, data)
-        {
-            with (Math)
-            {
-                with (params)
-                {
-                    var res = eval(params.__get('equation',null).replace(/pi\(\s*\)/g,'PI'));
-                }
-            }
-
-            if ('format' in params)
-            {
-                res = jSmart.prototype.PHPJS('sprintf','math').sprintf(params.format,res);
-            }
-
-            if ('assign' in params)
-            {
-                assignVar(params.assign, res, data);
-                return '';
-            }
-            return res;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'block',
-        'nocache',
-        function(params, content, data, repeat)
-        {
-            return content;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'block',
-        'textformat',
-        function(params, content, data, repeat)
-        {
-            if (!content) {
-                return '';
-            }
-
-            content = new String(content);
-
-            var wrap = params.__get('wrap',80);
-            var wrap_char = params.__get('wrap_char','\n');
-            var wrap_cut = params.__get('wrap_cut',false);
-            var indent_char = params.__get('indent_char',' ');
-            var indent = params.__get('indent',0);
-            var indentStr = (new Array(indent+1)).join(indent_char);
-            var indent_first = params.__get('indent_first',0);
-            var indentFirstStr = (new Array(indent_first+1)).join(indent_char);
-
-            var style = params.__get('style','');
-
-            if (style == 'email') {
-                wrap = 72;
-            }
-
-            var paragraphs = content.split(/[\r\n]{2}/);
-            for (var i=0; i<paragraphs.length; ++i) {
-                var p = paragraphs[i];
-                if (!p) {
-                    continue;
-                }
-                p = p.replace(/^\s+|\s+$/,'').replace(/\s+/g,' ');
-                if (indent_first> 0 ) {
-                    p = indentFirstStr + p;
-                }
-                p = modifiers.wordwrap(p, wrap-indent, wrap_char, wrap_cut);
-                if (indent > 0) {
-                    p = p.replace(/^/mg, indentStr);
-                }
-                paragraphs[i] = p;
-            }
-            var s = paragraphs.join(wrap_char+wrap_char);
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-
-    /**
-       register modifiers
-    */
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'capitalize',
-        function(s, upDigits, lcRest) {
-            if (typeof s != 'string') {
-                return s;
-            }
-            var re = new RegExp(upDigits ? '[^a-zA-Z_\u00E0-\u00FC]+' : '[^a-zA-Z0-9_\u00E0-\u00FC]');
-            var found = null;
-            var res = '';
-            if (lcRest) {
-                s = s.toLowerCase();
-            }
-            for (found=s.match(re); found; found=s.match(re))
-            {
-                    var word = s.slice(0,found.index);
-                if (word.match(/\d/))
-                {
-                    res += word;
-                }
-                else
-                {
-                        res += word.charAt(0).toUpperCase() + word.slice(1);
-                }
-                res += s.slice(found.index, found.index+found[0].length);
-                    s = s.slice(found.index+found[0].length);
-            }
-            if (s.match(/\d/))
-            {
-                return res + s;
-            }
-            return res + s.charAt(0).toUpperCase() + s.slice(1);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'cat',
-        function(s, value)
-        {
-            value = value ? value : '';
-            return new String(s) + value;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'count',
-        function(v, recursive)
-        {
-            if (v === null || typeof v === 'undefined') {
-                return 0;
-            } else if (v.constructor !== Array && v.constructor !== Object) {
-                return 1;
-            }
-
-            recursive = Boolean(recursive);
-            var k, cnt = 0;
-            for (k in v)
-            {
-                if (v.hasOwnProperty(k))
-                {
-                    cnt++;
-                    if (recursive && v[k] && (v[k].constructor === Array || v[k].constructor === Object)) {
-                        cnt += modifiers.count(v[k], true);
-                    }
-                }
-            }
-            return cnt;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'count_characters',
-        function(s, includeWhitespaces)
-        {
-            s = new String(s);
-            return includeWhitespaces ? s.length : s.replace(/\s/g,'').length;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'count_paragraphs',
-        function(s)
-        {
-            var found = (new String(s)).match(/\n+/g);
-            if (found)
-            {
-                    return found.length+1;
-            }
-            return 1;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'count_sentences',
-        function(s)
-        {
-            if (typeof s == 'string')
-            {
-                var found = s.match(/[^\s]\.(?!\w)/g);
-                if (found)
-                {
-                        return found.length;
-                }
-            }
-            return 0;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'count_words',
-        function(s)
-        {
-            if (typeof s == 'string')
-            {
-                var found = s.match(/\w+/g);
-                if (found)
-                {
-                        return found.length;
-                }
-            }
-            return 0;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'date_format',
-        function(s, fmt, defaultDate)
-        {
-            return jSmart.prototype.PHPJS('strftime','date_format').strftime(fmt?fmt:'%b %e, %Y', jSmart.prototype.makeTimeStamp(s?s:defaultDate));
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'defaultValue',
-        function(s, value)
-        {
-            return (s && s!='null' && s!='undefined') ? s : (value ? value : '');
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'unescape',
-        function(s, esc_type, char_set)
-        {
-            s = new String(s);
-            esc_type = esc_type || 'html';
-            char_set = char_set || 'UTF-8';
-
-            switch (esc_type)
-            {
-            case 'html':
-                return s.replace(/&lt;/g, '<').replace(/&gt;/g,'>').replace(/&#039;/g,"'").replace(/&quot;/g,'"');
-            case 'entity':
-            case 'htmlall':
-                return jSmart.prototype.PHPJS('html_entity_decode','unescape').html_entity_decode(s, 1);
-            case 'url':
-                return jSmart.prototype.PHPJS('rawurldecode','unescape').rawurldecode(s);
-            };
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'escape',
-        function(s, esc_type, char_set, double_encode)
-        {
-            s = new String(s);
-            esc_type = esc_type || 'html';
-            char_set = char_set || 'UTF-8';
-            double_encode = (typeof double_encode != 'undefined') ? Boolean(double_encode) : true;
-
-            switch (esc_type)
-            {
-            case 'html':
-                if (double_encode) {
-                                  s = s.replace(/&/g, '&amp;');
-                         }
-                return s.replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/'/g,'&#039;').replace(/"/g,'&quot;');
-            case 'htmlall':
-                return jSmart.prototype.PHPJS('htmlentities','escape').htmlentities(s, 3, char_set);
-            case 'url':
-                return jSmart.prototype.PHPJS('rawurlencode','escape').rawurlencode(s);
-            case 'urlpathinfo':
-                return jSmart.prototype.PHPJS('rawurlencode','escape').rawurlencode(s).replace(/%2F/g, '/');
-            case 'quotes':
-                return s.replace(/(^|[^\\])'/g, "$1\\'");
-            case 'hex':
-                var res = '';
-                for (var i=0; i<s.length; ++i)
-                {
-                    res += '%' + jSmart.prototype.PHPJS('bin2hex','escape').bin2hex(s.substr(i,1)).toLowerCase();
-                }
-                return res;
-            case 'hexentity':
-                var res = '';
-                for (var i=0; i<s.length; ++i) {
-                    res += '&#x' + jSmart.prototype.PHPJS('bin2hex','escape').bin2hex(s.substr(i,1)) + ';';
-                }
-                return res;
-            case 'decentity':
-                var res = '';
-                for (var i=0; i<s.length; ++i) {
-                    res += '&#' + jSmart.prototype.PHPJS('ord','escape').ord(s.substr(i,1)) + ';';
-                }
-                return res;
-            case 'mail':
-                return s.replace(/@/g,' [AT] ').replace(/[.]/g,' [DOT] ');
-            case 'nonstd':
-                var res = '';
-                for (var i=0; i<s.length; ++i)
-                {
-                    var _ord = jSmart.prototype.PHPJS('ord','escape').ord(s.substr(i,1));
-                    if (_ord >= 126) {
-                        res += '&#' + _ord + ';';
-                    } else {
-                        res += s.substr(i, 1);
-                    }
-
-                }
-                return res;
-            case 'javascript':
-                return s.replace(/\\/g,'\\\\').replace(/'/g,"\\'").replace(/"/g,'\\"').replace(/\r/g,'\\r').replace(/\n/g,'\\n').replace(/<\//g,'<\/');
-            };
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'indent',
-        function(s, repeat, indentWith)
-        {
-            s = new String(s);
-            repeat = repeat ? repeat : 4;
-            indentWith = indentWith ? indentWith : ' ';
-
-            var indentStr = '';
-            while (repeat--)
-            {
-                indentStr += indentWith;
-            }
-
-            var tail = s.match(/\n+$/);
-            return indentStr + s.replace(/\n+$/,'').replace(/\n/g,'\n'+indentStr) + (tail ? tail[0] : '');
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'lower',
-        function(s)
-        {
-            return new String(s).toLowerCase();
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'nl2br',
-        function(s)
-        {
-            return new String(s).replace(/\n/g,'<br />\n');
-        }
-    );
-
-    /**
-        only modifiers (flags) 'i' and 'm' are supported
-        backslashes should be escaped e.g. \\s
-    */
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'regex_replace',
-        function(s, re, replaceWith)
-        {
-            var pattern = re.match(/^ *\/(.*)\/(.*) *$/);
-            return (new String(s)).replace(new RegExp(pattern[1],'g'+(pattern.length>1?pattern[2]:'')), replaceWith);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'replace',
-        function(s, search, replaceWith)
-        {
-            if (!search)
-            {
-                return s;
-            }
-            s = new String(s);
-            search = new String(search);
-            replaceWith = new String(replaceWith);
-            var res = '';
-            var pos = -1;
-            for (pos=s.indexOf(search); pos>=0; pos=s.indexOf(search))
-            {
-                res += s.slice(0,pos) + replaceWith;
-                pos += search.length;
-                s = s.slice(pos);
-            }
-            return res + s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'spacify',
-        function(s, space)
-        {
-            if (!space)
-            {
-                space = ' ';
-            }
-            return (new String(s)).replace(/(\n|.)(?!$)/g,'$1'+space);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'noprint',
-        function(s)
-        {
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'string_format',
-        function(s, fmt)
-        {
-            return jSmart.prototype.PHPJS('sprintf','string_format').sprintf(fmt,s);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'strip',
-        function(s, replaceWith)
-        {
-            replaceWith = replaceWith ? replaceWith : ' ';
-            return (new String(s)).replace(/[\s]+/g, replaceWith);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'strip_tags',
-        function(s, addSpace)
-        {
-            addSpace = (addSpace==null) ? true : addSpace;
-            return (new String(s)).replace(/<[^>]*?>/g, addSpace ? ' ' : '');
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'truncate',
-        function(s, length, etc, breakWords, middle)
-        {
-            s = new String(s);
-            length = length ? length : 80;
-            etc = (etc!=null) ? etc : '...';
-
-            if (s.length <= length)
-            {
-                return s;
-            }
-
-            length -= Math.min(length,etc.length);
-            if (middle)
-            {
-                //one of floor()'s should be replaced with ceil() but it so in Smarty
-                return s.slice(0,Math.floor(length/2)) + etc + s.slice(s.length-Math.floor(length/2));
-            }
-
-            if (!breakWords)
-            {
-                s = s.slice(0,length+1).replace(/\s+?(\S+)?$/,'');
-            }
-
-            return s.slice(0,length) + etc;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'upper',
-        function(s)
-        {
-            return (new String(s)).toUpperCase();
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'wordwrap',
-        function(s, width, wrapWith, breakWords)
-        {
-               width = width || 80;
-               wrapWith = wrapWith || '\n';
-
-               var lines = (new String(s)).split('\n');
-               for (var i=0; i<lines.length; ++i)
-               {
-                       var line = lines[i];
-                var parts = ''
-                       while (line.length > width)
-                       {
-                    var pos = 0;
-                    var found = line.slice(pos).match(/\s+/);
-                    for (;found && (pos+found.index)<=width; found=line.slice(pos).match(/\s+/))
-                    {
-                        pos += found.index + found[0].length;
-                    }
-                    pos = pos || (breakWords ? width : (found ? found.index+found[0].length : line.length));
-                    parts += line.slice(0,pos).replace(/\s+$/,'');// + wrapWith;
-                    if (pos < line.length)
-                    {
-                        parts += wrapWith;
-                    }
-                    line = line.slice(pos);
-                }
-                       lines[i] = parts + line;
-               }
-               return lines.join('\n');
-        }
-    );
-
-
-    String.prototype.fetch = function(data)
-    {
-        var tpl = new jSmart(this);
-        return tpl.fetch(data);
-    };
-
-    if (typeof module === "object" && module && typeof module.exports === "object") {
-        module.exports = jSmart;
-    } else {
-        if (typeof global !== "undefined") {
-            global.jSmart = jSmart;
-        }
-
-        if (typeof define === "function" && define.amd) {
-            define("jSmart", [], function () { return jSmart; });
-        }
-    }
-})();
diff --git a/view/theme/frio/frameworks/jsmart/jsmart.js b/view/theme/frio/frameworks/jsmart/jsmart.js
deleted file mode 100644 (file)
index 758e928..0000000
+++ /dev/null
@@ -1,3456 +0,0 @@
-/*!
- * jSmart Javascript template engine
- * https://github.com/umakantp/jsmart
- *
- * Copyright 2011-2015, Max Miroshnikov <miroshnikov at gmail dot com>
- *                      Umakant Patil <me at umakantpatil dot.com>
- * jSmart is licensed under the GNU Lesser General Public License
- * http://opensource.org/licenses/LGPL-3.0
- */
-
-
-(function() {
-
-    /**
-       merges two or more objects into one
-       shallow copy for objects
-    */
-    function obMerge(ob1, ob2 /*, ...*/)
-    {
-        for (var i=1; i<arguments.length; ++i)
-        {
-           for (var nm in arguments[i])
-           {
-              ob1[nm] = arguments[i][nm];
-           }
-        }
-        return ob1;
-    }
-
-    /**
-       @return  number of own properties in ob
-    */
-    function countProperties(ob)
-    {
-        var count = 0;
-        for (var nm in ob)
-        {
-            if (ob.hasOwnProperty(nm))
-            {
-                count++;
-            }
-        }
-        return count;
-    }
-
-    /**
-       IE workaround
-    */
-    function findInArray(a, v)
-    {
-        if (Array.prototype.indexOf) {
-            return a.indexOf(v);
-        }
-        for (var i=0; i < a.length; ++i)
-        {
-            if (a[i] === v)
-            {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    function evalString(s)
-    {
-        return s.replace(/\\t/,'\t').replace(/\\n/,'\n').replace(/\\(['"\\])/g,'$1');
-    }
-
-    /**
-       @return  s trimmed and without quotes
-    */
-    function trimQuotes(s)
-    {
-        return evalString(s.replace(/^['"](.*)['"]$/,'$1')).replace(/^\s+|\s+$/g,'');
-    }
-
-    /**
-       finds first {tag} in string
-       @param re string with regular expression or an empty string to find any tag
-       @return  null or s.match(re) result object where
-       [0] - full tag matched with delimiters (and whitespaces at the begin and the end): { tag }
-       [1] - found part from passed re
-       [index] - position of tag starting { in s
-    */
-    function findTag(re,s)
-    {
-        var openCount = 0;
-        var offset = 0;
-        var ldelim = jSmart.prototype.left_delimiter;
-        var rdelim = jSmart.prototype.right_delimiter;
-        var skipInWS = jSmart.prototype.auto_literal;
-
-        var reAny = /^\s*(.+)\s*$/i;
-        var reTag = re ? new RegExp('^\\s*('+re+')\\s*$','i') : reAny;
-
-        for (var i=0; i<s.length; ++i)
-        {
-            if (s.substr(i,ldelim.length) == ldelim)
-            {
-                if (skipInWS && i+1 < s.length && s.substr(i+1,1).match(/\s/))
-                {
-                    continue;
-                }
-                if (!openCount)
-                {
-                    s = s.slice(i);
-                    offset += parseInt(i);
-                    i = 0;
-                }
-                ++openCount;
-            }
-            else if (s.substr(i,rdelim.length) == rdelim)
-            {
-                if (skipInWS && i-1 >= 0 && s.substr(i-1,1).match(/\s/))
-                {
-                    continue;
-                }
-                if (!--openCount)
-                {
-                    var sTag = s.slice(ldelim.length,i).replace(/[\r\n]/g, ' ');
-                    var found = sTag.match(reTag);
-                    if (found)
-                    {
-                        found.index = offset;
-                        found[0] = s.slice(0,i+rdelim.length);
-                        return found;
-                    }
-                }
-                if (openCount < 0) //ignore any number of unmatched right delimiters
-                {
-                    openCount = 0;
-                }
-            }
-        }
-        return null;
-    }
-
-    function findCloseTag(reClose,reOpen,s)
-    {
-        var sInner = '';
-        var closeTag = null;
-        var openTag = null;
-        var findIndex = 0;
-
-        do
-        {
-            if (closeTag)
-            {
-                findIndex += closeTag[0].length;
-            }
-            closeTag = findTag(reClose,s);
-            if (!closeTag)
-            {
-                throw new Error('Unclosed {'+reOpen+'}');
-            }
-            sInner += s.slice(0,closeTag.index);
-            findIndex += closeTag.index;
-            s = s.slice(closeTag.index+closeTag[0].length);
-
-            openTag = findTag(reOpen,sInner);
-            if (openTag)
-            {
-                sInner = sInner.slice(openTag.index+openTag[0].length);
-            }
-        }
-        while (openTag);
-
-        closeTag.index = findIndex;
-        return closeTag;
-    }
-
-    function findElseTag(reOpen, reClose, reElse, s)
-    {
-        var offset = 0;
-        for (var elseTag=findTag(reElse,s); elseTag; elseTag=findTag(reElse,s))
-        {
-            var openTag = findTag(reOpen,s);
-            if (!openTag || openTag.index > elseTag.index)
-            {
-                elseTag.index += offset;
-                return elseTag;
-            }
-            else
-            {
-                s = s.slice(openTag.index+openTag[0].length);
-                offset += openTag.index+openTag[0].length;
-                var closeTag = findCloseTag(reClose,reOpen,s);
-                s = s.slice(closeTag.index + closeTag[0].length);
-                offset += closeTag.index + closeTag[0].length;
-            }
-        }
-        return null;
-    }
-
-    function execute(code, data)
-    {
-        if (typeof(code) == 'string')
-        {
-            with ({'__code':code})
-            {
-                with (modifiers)
-                {
-                    with (data)
-                    {
-                        try {
-                            return eval(__code);
-                        }
-                        catch(e)
-                        {
-                            throw new Error(e.message + ' in \n' + code);
-                        }
-                    }
-                }
-            }
-        }
-        return code;
-    }
-
-    /**
-     * Execute function when we have a object.
-     *
-     * @param object obj  Object of the function to be called.
-     * @param array  args Arguments to pass to a function.
-     *
-     * @return
-     * @throws Error If function obj does not exists.
-     */
-    function executeByFuncObject(obj, args) {
-        try {
-            return obj.apply(this, args);
-        } catch (e) {
-            throw new Error(e.message);
-        }
-    }
-
-    function assignVar(nm, val, data)
-    {
-        if (nm.match(/\[\]$/))  //ar[] =
-        {
-            data[ nm.replace(/\[\]$/,'') ].push(val);
-        }
-        else
-        {
-            data[nm] = val;
-        }
-    }
-
-    var buildInFunctions =
-        {
-            expression:
-            {
-                parse: function(s, tree)
-                {
-                    var e = parseExpression(s);
-
-                    tree.push({
-                        type: 'build-in',
-                        name: 'expression',
-                        expression: e.tree,
-                        params: parseParams(s.slice(e.value.length).replace(/^\s+|\s+$/g,''))
-                    });
-
-                    return e.tree;
-
-                },
-                process: function(node, data)
-                {
-                    var params = getActualParamValues(node.params, data);
-                    var res = process([node.expression],data);
-
-                    if (findInArray(params, 'nofilter') < 0)
-                    {
-                        for (var i=0; i<default_modifiers.length; ++i)
-                        {
-                            var m = default_modifiers[i];
-                            m.params.__parsed[0] = {type:'text', data:res};
-                            res = process([m],data);
-                        }
-                        if (escape_html)
-                        {
-                            res = modifiers.escape(res);
-                        }
-                        res = applyFilters(varFilters,res);
-
-                        if (tpl_modifiers.length) {
-                            __t = function(){ return res; }
-                            res = process(tpl_modifiers,data);
-                        }
-                    }
-                    return res;
-                }
-            },
-
-            operator:
-            {
-                process: function(node, data)
-                {
-                    var params = getActualParamValues(node.params, data);
-                    var arg1 = params[0];
-
-                    if (node.optype == 'binary')
-                    {
-                        var arg2 = params[1];
-                        if (node.op == '=')
-                        {
-                            getVarValue(node.params.__parsed[0], data, arg2);
-                            return '';
-                        }
-                        else if (node.op.match(/(\+=|-=|\*=|\/=|%=)/))
-                        {
-                            arg1 = getVarValue(node.params.__parsed[0], data);
-                            switch (node.op)
-                            {
-                            case '+=': arg1+=arg2; break;
-                            case '-=': arg1-=arg2; break;
-                            case '*=': arg1*=arg2; break;
-                            case '/=': arg1/=arg2; break;
-                            case '%=': arg1%=arg2; break;
-                            }
-                            return getVarValue(node.params.__parsed[0], data, arg1);
-                        }
-                        else if (node.op.match(/div/))
-                        {
-                            return (node.op!='div')^(arg1%arg2==0);
-                        }
-                        else if (node.op.match(/even/))
-                        {
-                            return (node.op!='even')^((arg1/arg2)%2==0);
-                        }
-                        else if (node.op.match(/xor/))
-                        {
-                            return (arg1||arg2) && !(arg1&&arg2);
-                        }
-
-                        switch (node.op)
-                        {
-                        case '==': return arg1==arg2;
-                        case '!=': return arg1!=arg2;
-                        case '+':  return Number(arg1)+Number(arg2);
-                        case '-':  return Number(arg1)-Number(arg2);
-                        case '*':  return Number(arg1)*Number(arg2);
-                        case '/':  return Number(arg1)/Number(arg2);
-                        case '%':  return Number(arg1)%Number(arg2);
-                        case '&&': return arg1&&arg2;
-                        case '||': return arg1||arg2;
-                        case '<':  return arg1<arg2;
-                        case '<=': return arg1<=arg2;
-                        case '>':  return arg1>arg2;
-                        case '>=': return arg1>=arg2;
-                        case '===': return arg1===arg2;
-                        case '!==': return arg1!==arg2;
-                        }
-                    }
-                    else if (node.op == '!')
-                    {
-                        return !arg1;
-                    }
-                    else
-                    {
-                        var isVar = node.params.__parsed[0].type == 'var';
-                        if (isVar)
-                        {
-                            arg1 = getVarValue(node.params.__parsed[0], data);
-                        }
-                        var v = arg1;
-                        if (node.optype == 'pre-unary')
-                        {
-                            switch (node.op)
-                            {
-                            case '-':  v=-arg1;  break;
-                            case '++': v=++arg1; break;
-                            case '--': v=--arg1; break;
-                            }
-                            if (isVar)
-                            {
-                                getVarValue(node.params.__parsed[0], data, arg1);
-                            }
-                        }
-                        else
-                        {
-                            switch (node.op)
-                            {
-                            case '++': arg1++; break;
-                            case '--': arg1--; break;
-                            }
-                            getVarValue(node.params.__parsed[0], data, arg1);
-                        }
-                        return v;
-                    }
-                }
-            },
-
-            section:
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    var subTree = [];
-                    var subTreeElse = [];
-                    tree.push({
-                        type: 'build-in',
-                        name: 'section',
-                        params: params,
-                        subTree: subTree,
-                        subTreeElse: subTreeElse
-                    });
-
-                    var findElse = findElseTag('section [^}]+', '\/section', 'sectionelse', content);
-                    if (findElse)
-                    {
-                        parse(content.slice(0,findElse.index),subTree);
-                        parse(content.slice(findElse.index+findElse[0].length).replace(/^[\r\n]/,''), subTreeElse);
-                    }
-                    else
-                    {
-                        parse(content, subTree);
-                    }
-                },
-
-                process: function(node, data)
-                {
-                    var params = getActualParamValues(node.params, data);
-
-                    var props = {};
-                    data.smarty.section[params.__get('name',null,0)] = props;
-
-                    var show = params.__get('show',true);
-                    props.show = show;
-                    if (!show)
-                    {
-                        return process(node.subTreeElse, data);
-                    }
-
-                    var from = parseInt(params.__get('start',0));
-                    var to = (params.loop instanceof Object) ? countProperties(params.loop) : isNaN(params.loop) ? 0 : parseInt(params.loop);
-                    var step = parseInt(params.__get('step',1));
-                    var max = parseInt(params.__get('max'));
-                    if (isNaN(max))
-                    {
-                        max = Number.MAX_VALUE;
-                    }
-
-                    if (from < 0)
-                    {
-                        from += to;
-                        if (from < 0)
-                        {
-                            from = 0;
-                        }
-                    }
-                    else if (from >= to)
-                    {
-                        from = to ? to-1 : 0;
-                    }
-
-                    var count = 0;
-                    var loop = 0;
-                    var i = from;
-                    for (; i>=0 && i<to && count<max; i+=step,++count)
-                    {
-                        loop = i;
-                    }
-                    props.total = count;
-                    props.loop = count;  //? - because it is so in Smarty
-
-                    count = 0;
-                    var s = '';
-                    for (i=from; i>=0 && i<to && count<max; i+=step,++count)
-                    {
-                        if (data.smarty['break'])
-                        {
-                            break;
-                        }
-
-                        props.first = (i==from);
-                        props.last = ((i+step)<0 || (i+step)>=to);
-                        props.index = i;
-                        props.index_prev = i-step;
-                        props.index_next = i+step;
-                        props.iteration = props.rownum = count+1;
-
-                        s += process(node.subTree, data);
-                        data.smarty['continue'] = false;
-                    }
-                    data.smarty['break'] = false;
-
-                    if (count)
-                    {
-                        return s;
-                    }
-                    return process(node.subTreeElse, data);
-                }
-            },
-
-            setfilter:
-            {
-                type: 'block',
-                parseParams: function(paramStr)
-                {
-                    return [parseExpression('__t()|' + paramStr).tree];
-                },
-
-                parse: function(params, tree, content)
-                {
-                    tree.push({
-                        type: 'build-in',
-                        name: 'setfilter',
-                        params: params,
-                        subTree: parse(content,[])
-                    });
-                },
-
-                process: function(node, data)
-                {
-                    tpl_modifiers = node.params;
-                    var s = process(node.subTree, data);
-                    tpl_modifiers = [];
-                    return s;
-                }
-            },
-
-            'for':
-            {
-                type: 'block',
-                parseParams: function(paramStr)
-                {
-                    var res = paramStr.match(/^\s*\$(\w+)\s*=\s*([^\s]+)\s*to\s*([^\s]+)\s*(?:step\s*([^\s]+))?\s*(.*)$/);
-                    if (!res)
-                    {
-                        throw new Error('Invalid {for} parameters: '+paramStr);
-                    }
-                    return parseParams("varName='"+res[1]+"' from="+res[2]+" to="+res[3]+" step="+(res[4]?res[4]:'1')+" "+res[5]);
-                },
-
-                parse: function(params, tree, content)
-                {
-                    var subTree = [];
-                    var subTreeElse = [];
-                    tree.push({
-                        type: 'build-in',
-                        name: 'for',
-                        params: params,
-                        subTree: subTree,
-                        subTreeElse: subTreeElse
-                    });
-
-                    var findElse = findElseTag('for\\s[^}]+', '\/for', 'forelse', content);
-                    if (findElse)
-                    {
-                        parse(content.slice(0,findElse.index),subTree);
-                        parse(content.slice(findElse.index+findElse[0].length), subTreeElse);
-                    }
-                    else
-                    {
-                        parse(content, subTree);
-                    }
-                },
-
-                process: function(node, data)
-                {
-                    var params = getActualParamValues(node.params, data);
-                    var from = parseInt(params.__get('from'));
-                    var to = parseInt(params.__get('to'));
-                    var step = parseInt(params.__get('step'));
-                    if (isNaN(step))
-                    {
-                        step = 1;
-                    }
-                    var max = parseInt(params.__get('max'));
-                    if (isNaN(max))
-                    {
-                        max = Number.MAX_VALUE;
-                    }
-
-                    var count = 0;
-                    var s = '';
-                    var total = Math.min( Math.ceil( ((step > 0 ? to-from : from-to)+1) / Math.abs(step)  ), max);
-
-                    for (var i=parseInt(params.from); count<total; i+=step,++count)
-                    {
-                        if (data.smarty['break'])
-                        {
-                            break;
-                        }
-                        data[params.varName] = i;
-                        s += process(node.subTree, data);
-                        data.smarty['continue'] = false;
-                    }
-                    data.smarty['break'] = false;
-
-                    if (!count)
-                    {
-                        s = process(node.subTreeElse, data);
-                    }
-                    return s;
-                }
-            },
-
-            'if':
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    var subTreeIf = [];
-                    var subTreeElse = [];
-                    tree.push({
-                        type: 'build-in',
-                        name: 'if',
-                        params: params,
-                        subTreeIf: subTreeIf,
-                        subTreeElse: subTreeElse
-                    });
-
-                    var findElse = findElseTag('if\\s+[^}]+', '\/if', 'else[^}]*', content);
-                    if (findElse)
-                    {
-                        parse(content.slice(0,findElse.index),subTreeIf);
-
-                        content = content.slice(findElse.index+findElse[0].length);
-                        var findElseIf = findElse[1].match(/^else\s*if(.*)/);
-                        if (findElseIf)
-                        {
-                            buildInFunctions['if'].parse(parseParams(findElseIf[1]), subTreeElse, content.replace(/^\n/,''));
-                        }
-                        else
-                        {
-                            parse(content.replace(/^\n/,''), subTreeElse);
-                        }
-                    }
-                    else
-                    {
-                        parse(content, subTreeIf);
-                    }
-                },
-
-                process: function(node, data) {
-                    var value = getActualParamValues(node.params,data)[0];
-                    // Zero length arrays or empty associative arrays are false in PHP.
-                    if (value && !((value instanceof Array && value.length == 0)
-                        || (typeof value == 'object' && isEmptyObject(value)))
-                    ) {
-                        return process(node.subTreeIf, data);
-                    } else {
-                        return process(node.subTreeElse, data);
-                    }
-                }
-            },
-
-            foreach:
-            {
-                type: 'block',
-                parseParams: function(paramStr)
-                {
-                    var params = {};
-                    var res = paramStr.match(/^\s*([$].+)\s*as\s*[$](\w+)\s*(=>\s*[$](\w+))?\s*$/i);
-                    if (res) //Smarty 3.x syntax => Smarty 2.x syntax
-                    {
-                        paramStr = 'from='+res[1] + ' item='+(res[4]||res[2]);
-                        if (res[4])
-                        {
-                            paramStr += ' key='+res[2];
-                        }
-                    }
-                    return parseParams(paramStr);
-                },
-
-                parse: function(params, tree, content)
-                {
-                    var subTree = [];
-                    var subTreeElse = [];
-                    tree.push({
-                        type: 'build-in',
-                        name: 'foreach',
-                        params: params,
-                        subTree: subTree,
-                        subTreeElse: subTreeElse
-                    });
-
-                    var findElse = findElseTag('foreach\\s[^}]+', '\/foreach', 'foreachelse', content);
-                    if (findElse)
-                    {
-                        parse(content.slice(0,findElse.index),subTree);
-                        parse(content.slice(findElse.index+findElse[0].length).replace(/^[\r\n]/,''), subTreeElse);
-                    }
-                    else
-                    {
-                        parse(content, subTree);
-                    }
-                },
-
-                process: function(node, data)
-                {
-                    var params = getActualParamValues(node.params, data);
-                    var a = params.from;
-                    if (typeof a == 'undefined')
-                    {
-                        a = [];
-                    }
-                    if (typeof a != 'object')
-                    {
-                        a = [a];
-                    }
-
-                    var total = countProperties(a);
-
-                    data[params.item+'__total'] = total;
-                    if ('name' in params)
-                    {
-                        data.smarty.foreach[params.name] = {};
-                        data.smarty.foreach[params.name].total = total;
-                    }
-
-                    var s = '';
-                    var i=0;
-                    for (var key in a)
-                    {
-                        if (!a.hasOwnProperty(key))
-                        {
-                            continue;
-                        }
-
-                        if (data.smarty['break'])
-                        {
-                            break;
-                        }
-
-                        data[params.item+'__key'] = isNaN(key) ? key : parseInt(key);
-                        if ('key' in params)
-                        {
-                            data[params.key] = data[params.item+'__key'];
-                        }
-                        data[params.item] = a[key];
-                        data[params.item+'__index'] = parseInt(i);
-                        data[params.item+'__iteration'] = parseInt(i+1);
-                        data[params.item+'__first'] = (i===0);
-                        data[params.item+'__last'] = (i==total-1);
-
-                        if ('name' in params)
-                        {
-                            data.smarty.foreach[params.name].index = parseInt(i);
-                            data.smarty.foreach[params.name].iteration = parseInt(i+1);
-                            data.smarty.foreach[params.name].first = (i===0) ? 1 : '';
-                            data.smarty.foreach[params.name].last = (i==total-1) ? 1 : '';
-                        }
-
-                        ++i;
-
-                        s += process(node.subTree, data);
-                        data.smarty['continue'] = false;
-                    }
-                    data.smarty['break'] = false;
-
-                    data[params.item+'__show'] = (i>0);
-                    if (params.name)
-                    {
-                        data.smarty.foreach[params.name].show = (i>0) ? 1 : '';
-                    }
-                    if (i>0)
-                    {
-                        return s;
-                    }
-                    return process(node.subTreeElse, data);
-                }
-            },
-
-            'function':
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    var subTree = [];
-                    plugins[trimQuotes(params.name?params.name:params[0])] =
-                        {
-                            type: 'function',
-                            subTree: subTree,
-                            defautParams: params,
-                            process: function(params, data)
-                            {
-                                var defaults = getActualParamValues(this.defautParams,data);
-                                delete defaults.name;
-                                return process(this.subTree, obMerge({},data,defaults,params));
-                            }
-                        };
-                    parse(content, subTree);
-                }
-            },
-
-            php:
-            {
-                type: 'block',
-                parse: function(params, tree, content) {}
-            },
-
-            'extends':
-            {
-                type: 'function',
-                parse: function(params, tree)
-                {
-                    tree.splice(0,tree.length);
-                    getTemplate(trimQuotes(params.file?params.file:params[0]),tree);
-                }
-            },
-
-            block:
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    tree.push({
-                        type: 'build-in',
-                        name: 'block',
-                        params: params
-                    });
-                    params.append = findInArray(params,'append') >= 0;
-                    params.prepend = findInArray(params,'prepend') >= 0;
-                    params.hide = findInArray(params,'hide') >= 0;
-                    params.hasChild = params.hasParent = false;
-
-                    onParseVar = function(nm)
-                    {
-                        if (nm.match(/^\s*[$]smarty.block.child\s*$/))
-                        {
-                            params.hasChild = true;
-                        }
-                        if (nm.match(/^\s*[$]smarty.block.parent\s*$/))
-                        {
-                            params.hasParent = true;
-                        }
-                    }
-                    var tree = parse(content, []);
-                    onParseVar = function(nm) {}
-
-                    var blockName = trimQuotes(params.name?params.name:params[0]);
-                    if (!(blockName in blocks))
-                    {
-                        blocks[blockName] = [];
-                    }
-                    blocks[blockName].push({tree:tree, params:params});
-                },
-
-                process: function(node, data)
-                {
-                    data.smarty.block.parent = data.smarty.block.child = '';
-                    var blockName = trimQuotes(node.params.name?node.params.name:node.params[0]);
-                    this.processBlocks(blocks[blockName], blocks[blockName].length-1, data);
-                    return data.smarty.block.child;
-                },
-
-                processBlocks: function(blockAncestry, i, data)
-                {
-                    if (!i && blockAncestry[i].params.hide) {
-                        data.smarty.block.child = '';
-                        return;
-                    }
-                    var append = true;
-                    var prepend = false;
-                    for (; i>=0; --i)
-                    {
-                        if (blockAncestry[i].params.hasParent)
-                        {
-                            var tmpChild = data.smarty.block.child;
-                            data.smarty.block.child = '';
-                            this.processBlocks(blockAncestry, i-1, data);
-                            data.smarty.block.parent = data.smarty.block.child;
-                            data.smarty.block.child = tmpChild;
-                        }
-
-                        var tmpChild = data.smarty.block.child;
-                        var s = process(blockAncestry[i].tree, data);
-                        data.smarty.block.child = tmpChild;
-
-                        if (blockAncestry[i].params.hasChild)
-                        {
-                            data.smarty.block.child = s;
-                        }
-                        else if (append)
-                        {
-                            data.smarty.block.child = s + data.smarty.block.child;
-                        }
-                        else if (prepend)
-                        {
-                            data.smarty.block.child += s;
-                        }
-                        append = blockAncestry[i].params.append;
-                        prepend = blockAncestry[i].params.prepend;
-                    }
-                }
-            },
-
-            strip:
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    parse(content.replace(/[ \t]*[\r\n]+[ \t]*/g, ''), tree);
-                }
-            },
-
-            literal:
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    parseText(content, tree);
-                }
-            },
-
-            ldelim:
-            {
-                type: 'function',
-                parse: function(params, tree)
-                {
-                    parseText(jSmart.prototype.left_delimiter, tree);
-                }
-            },
-
-            rdelim:
-            {
-                type: 'function',
-                parse: function(params, tree)
-                {
-                    parseText(jSmart.prototype.right_delimiter, tree);
-                }
-            },
-
-            'while':
-            {
-                type: 'block',
-                parse: function(params, tree, content)
-                {
-                    tree.push({
-                        type: 'build-in',
-                        name: 'while',
-                        params: params,
-                        subTree: parse(content, [])
-                    });
-                },
-
-                process: function(node, data)
-                {
-                    var s = '';
-                    while (getActualParamValues(node.params,data)[0])
-                    {
-                        if (data.smarty['break'])
-                        {
-                            break;
-                        }
-                        s += process(node.subTree, data);
-                        data.smarty['continue'] = false;
-                    }
-                    data.smarty['break'] = false;
-                    return s;
-                }
-            }
-        };
-
-    var plugins = {};
-    var modifiers = {};
-    var files = {};
-    var blocks = null;
-    var scripts = null;
-    var tpl_modifiers = [];
-
-    function parse(s, tree)
-    {
-        for (var openTag=findTag('',s); openTag; openTag=findTag('',s))
-        {
-            if (openTag.index)
-            {
-                parseText(s.slice(0,openTag.index),tree);
-            }
-            s = s.slice(openTag.index + openTag[0].length);
-
-            var res = openTag[1].match(/^\s*(\w+)(.*)$/);
-            if (res)         //function
-            {
-                var nm = res[1];
-                var paramStr = (res.length>2) ? res[2].replace(/^\s+|\s+$/g,'') : '';
-
-                if (nm in buildInFunctions)
-                {
-                    var buildIn = buildInFunctions[nm];
-                    var params = ('parseParams' in buildIn ? buildIn.parseParams : parseParams)(paramStr);
-                    if (buildIn.type == 'block')
-                    {
-                        s = s.replace(/^\n/,'');  //remove new line after block open tag (like in Smarty)
-                        var closeTag = findCloseTag('\/'+nm, nm+' +[^}]*', s);
-                        buildIn.parse(params, tree, s.slice(0,closeTag.index));
-                        s = s.slice(closeTag.index+closeTag[0].length);
-                    }
-                    else
-                    {
-                        buildIn.parse(params, tree);
-                        if (nm == 'extends')
-                        {
-                            tree = []; //throw away further parsing except for {block}
-                        }
-                    }
-                    s = s.replace(/^\n/,'');
-                }
-                else if (nm in plugins)
-                {
-                    var plugin = plugins[nm];
-                    if (plugin.type == 'block')
-                    {
-                        var closeTag = findCloseTag('\/'+nm, nm+' +[^}]*', s);
-                        parsePluginBlock(nm, parseParams(paramStr), tree, s.slice(0,closeTag.index));
-                        s = s.slice(closeTag.index+closeTag[0].length);
-                    }
-                    else if (plugin.type == 'function')
-                    {
-                        parsePluginFunc(nm, parseParams(paramStr), tree);
-                    }
-                    if (nm=='append' || nm=='assign' || nm=='capture' || nm=='eval' || nm=='include')
-                    {
-                        s = s.replace(/^\n/,'');
-                    }
-                }
-                else   //variable
-                {
-                    buildInFunctions.expression.parse(openTag[1],tree);
-                }
-            }
-            else         //variable
-            {
-                var node = buildInFunctions.expression.parse(openTag[1],tree);
-                if (node.type=='build-in' && node.name=='operator' && node.op == '=')
-                {
-                    s = s.replace(/^\n/,'');
-                }
-            }
-        }
-        if (s)
-        {
-            parseText(s, tree);
-        }
-        return tree;
-    }
-
-    function parseText(text, tree)
-    {
-        if (parseText.parseEmbeddedVars)
-        {
-            var re = /([$][\w@]+)|`([^`]*)`/;
-            for (var found=re.exec(text); found; found=re.exec(text))
-            {
-                tree.push({type: 'text', data: text.slice(0,found.index)});
-                tree.push( parseExpression(found[1] ? found[1] : found[2]).tree );
-                text = text.slice(found.index + found[0].length);
-            }
-        }
-        tree.push({type: 'text', data: text});
-        return tree;
-    }
-
-    function parseFunc(name, params, tree)
-    {
-        params.__parsed.name = parseText(name,[])[0];
-        tree.push({
-            type: 'plugin',
-            name: '__func',
-            params: params
-        });
-        return tree;
-    }
-
-    function parseOperator(op, type, precedence, tree)
-    {
-        tree.push({
-            type: 'build-in',
-            name: 'operator',
-            op: op,
-            optype: type,
-            precedence: precedence,
-            params: {}
-        });
-    }
-
-    function parseVar(s, e, nm)
-    {
-        var rootName = e.token;
-        var parts = [{type:'text', data:nm.replace(/^(\w+)@(key|index|iteration|first|last|show|total)/gi, "$1__$2")}];
-
-        var re = /^(?:\.|\s*->\s*|\[\s*)/;
-        for (var op=s.match(re); op; op=s.match(re))
-        {
-            e.token += op[0];
-            s = s.slice(op[0].length);
-
-            var eProp = {value:'', tree:[]};
-            if (op[0].match(/\[/))
-            {
-                eProp = parseExpression(s);
-                if (eProp)
-                {
-                    e.token += eProp.value;
-                    parts.push( eProp.tree );
-                    s = s.slice(eProp.value.length);
-                }
-
-                var closeOp = s.match(/\s*\]/);
-                if (closeOp)
-                {
-                    e.token += closeOp[0];
-                    s = s.slice(closeOp[0].length);
-                }
-            }
-            else
-            {
-                var parseMod = parseModifiers.stop;
-                parseModifiers.stop = true;
-                if (lookUp(s,eProp))
-                {
-                    e.token += eProp.value;
-                    var part = eProp.tree[0];
-                    if (part.type == 'plugin' && part.name == '__func')
-                    {
-                        part.hasOwner = true;
-                    }
-                    parts.push( part );
-                    s = s.slice(eProp.value.length);
-                }
-                else
-                {
-                    eProp = false;
-                }
-                parseModifiers.stop = parseMod;
-            }
-
-            if (!eProp)
-            {
-                parts.push({type:'text', data:''});
-            }
-        }
-
-        e.tree.push({type: 'var', parts: parts});
-
-        e.value += e.token.substr(rootName.length);
-
-        onParseVar(e.token);
-
-        return s;
-    }
-
-    function onParseVar(nm)  {}
-
-
-    var tokens =
-        [
-            {
-                re: /^\$([\w@]+)/,   //var
-                parse: function(e, s)
-                {
-                    parseModifiers(parseVar(s, e, RegExp.$1), e);
-                }
-            },
-            {
-                re: /^(true|false)/i,  //bool
-                parse: function(e, s)
-                {
-                    parseText(e.token.match(/true/i) ? '1' : '', e.tree);
-                }
-            },
-            {
-                re: /^'([^'\\]*(?:\\.[^'\\]*)*)'/, //single quotes
-                parse: function(e, s)
-                {
-                    parseText(evalString(RegExp.$1), e.tree);
-                    parseModifiers(s, e);
-                }
-            },
-            {
-                re: /^"([^"\\]*(?:\\.[^"\\]*)*)"/,  //double quotes
-                parse: function(e, s)
-                {
-                    var v = evalString(RegExp.$1);
-                    var isVar = v.match(tokens[0].re);
-                    if (isVar)
-                    {
-                        var eVar = {token:isVar[0], tree:[]};
-                        parseVar(v, eVar, isVar[1]);
-                        if (eVar.token.length == v.length)
-                        {
-                            e.tree.push( eVar.tree[0] );
-                            return;
-                        }
-                    }
-                    parseText.parseEmbeddedVars = true;
-                    e.tree.push({
-                        type: 'plugin',
-                        name: '__quoted',
-                        params: {__parsed: parse(v,[])}
-                    });
-                    parseText.parseEmbeddedVars = false;
-                    parseModifiers(s, e);
-                }
-            },
-            {
-                re: /^(\w+)\s*[(]([)]?)/,  //func()
-                parse: function(e, s)
-                {
-                    var fnm = RegExp.$1;
-                    var noArgs = RegExp.$2;
-                    var params = parseParams(noArgs?'':s,/^\s*,\s*/);
-                    parseFunc(fnm, params, e.tree);
-                    e.value += params.toString();
-                    parseModifiers(s.slice(params.toString().length), e);
-                }
-            },
-            {
-                re: /^\s*\(\s*/,  //expression in parentheses
-                parse: function(e, s)
-                {
-                    var parens = [];
-                    e.tree.push(parens);
-                    parens.parent = e.tree;
-                    e.tree = parens;
-                }
-            },
-            {
-                re: /^\s*\)\s*/,
-                parse: function(e, s)
-                {
-                    if (e.tree.parent) //it may be the end of func() or (expr)
-                    {
-                        e.tree = e.tree.parent;
-                    }
-                }
-            },
-            {
-                re: /^\s*(\+\+|--)\s*/,
-                parse: function(e, s)
-                {
-                    if (e.tree.length && e.tree[e.tree.length-1].type == 'var')
-                    {
-                        parseOperator(RegExp.$1, 'post-unary', 1, e.tree);
-                    }
-                    else
-                    {
-                        parseOperator(RegExp.$1, 'pre-unary', 1, e.tree);
-                    }
-                }
-            },
-            {
-                re: /^\s*(===|!==|==|!=)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1, 'binary', 6, e.tree);
-                }
-            },
-            {
-                re: /^\s+(eq|ne|neq)\s+/i,
-                parse: function(e, s)
-                {
-                    var op = RegExp.$1.replace(/ne(q)?/,'!=').replace(/eq/,'==');
-                    parseOperator(op, 'binary', 6, e.tree);
-                }
-            },
-            {
-                re: /^\s*!\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator('!', 'pre-unary', 2, e.tree);
-                }
-            },
-            {
-                re: /^\s+not\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator('!', 'pre-unary', 2, e.tree);
-                }
-            },
-            {
-                re: /^\s*(=|\+=|-=|\*=|\/=|%=)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1, 'binary', 10, e.tree);
-                }
-            },
-            {
-                re: /^\s*(\*|\/|%)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1, 'binary', 3, e.tree);
-                }
-            },
-            {
-                re: /^\s+mod\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator('%', 'binary', 3, e.tree);
-                }
-            },
-            {
-                re: /^\s*(\+|-)\s*/,
-                parse: function(e, s)
-                {
-                    if (!e.tree.length || e.tree[e.tree.length-1].name == 'operator')
-                    {
-                        parseOperator(RegExp.$1, 'pre-unary', 4, e.tree);
-                    }
-                    else
-                    {
-                        parseOperator(RegExp.$1, 'binary', 4, e.tree);
-                    }
-                }
-            },
-            {
-                re: /^\s*(<=|>=|<>|<|>)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1.replace(/<>/,'!='), 'binary', 5, e.tree);
-                }
-            },
-            {
-                re: /^\s+(lt|lte|le|gt|gte|ge)\s+/i,
-                parse: function(e, s)
-                {
-                    var op = RegExp.$1.replace(/lt/,'<').replace(/l(t)?e/,'<=').replace(/gt/,'>').replace(/g(t)?e/,'>=');
-                    parseOperator(op, 'binary', 5, e.tree);
-                }
-            },
-            {
-                re: /^\s+(is\s+(not\s+)?div\s+by)\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$2?'div_not':'div', 'binary', 7, e.tree);
-                }
-            },
-            {
-                re: /^\s+is\s+(not\s+)?(even|odd)(\s+by\s+)?\s*/i,
-                parse: function(e, s)
-                {
-                    var op = RegExp.$1 ? ((RegExp.$2=='odd')?'even':'even_not') : ((RegExp.$2=='odd')?'even_not':'even');
-                    parseOperator(op, 'binary', 7, e.tree);
-                    if (!RegExp.$3)
-                    {
-                        parseText('1', e.tree);
-                    }
-                }
-            },
-            {
-                re: /^\s*(&&)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1, 'binary', 8, e.tree);
-                }
-            },
-            {
-                re: /^\s*(\|\|)\s*/,
-                parse: function(e, s)
-                {
-                    parseOperator(RegExp.$1, 'binary', 9, e.tree);
-                }
-            },
-            {
-                re: /^\s+and\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator('&&', 'binary', 11, e.tree);
-                }
-            },
-            {
-                re: /^\s+xor\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator('xor', 'binary', 12, e.tree);
-                }
-            },
-            {
-                re: /^\s+or\s+/i,
-                parse: function(e, s)
-                {
-                    parseOperator('||', 'binary', 13, e.tree);
-                }
-            },
-            {
-                re: /^#(\w+)#/,  //config variable
-                parse: function(e, s)
-                {
-                    var eVar = {token:'$smarty',tree:[]};
-                    parseVar('.config.'+RegExp.$1, eVar, 'smarty');
-                    e.tree.push( eVar.tree[0] );
-                    parseModifiers(s, e);
-                }
-            },
-            {
-                re: /^\s*\[\s*/,   //array
-                parse: function(e, s)
-                {
-                    var params = parseParams(s, /^\s*,\s*/, /^('[^'\\]*(?:\\.[^'\\]*)*'|"[^"\\]*(?:\\.[^"\\]*)*"|\w+)\s*=>\s*/);
-                    parsePluginFunc('__array',params,e.tree);
-                    e.value += params.toString();
-                    var paren = s.slice(params.toString().length).match(/\s*\]/);
-                    if (paren)
-                    {
-                        e.value += paren[0];
-                    }
-                }
-            },
-            {
-                re: /^[\d.]+/, //number
-                parse: function(e, s)
-                {
-                    if (e.token.indexOf('.') > -1) {
-                        e.token = parseFloat(e.token);
-                    } else {
-                        e.token = parseInt(e.token, 10);
-                    }
-                    parseText(e.token, e.tree);
-                    parseModifiers(s, e);
-                }
-            },
-            {
-                re: /^\w+/, //static
-                parse: function(e, s)
-                {
-                    parseText(e.token, e.tree);
-                    parseModifiers(s, e);
-                }
-            }
-        ];
-
-    function parseModifiers(s, e)
-    {
-        if (parseModifiers.stop)
-        {
-            return;
-        }
-
-        var modifier = s.match(/^\|(\w+)/);
-        if (!modifier)
-        {
-            return;
-        }
-
-        e.value += modifier[0];
-
-        var fnm = modifier[1]=='default' ? 'defaultValue' : modifier[1];
-        s = s.slice(modifier[0].length).replace(/^\s+/,'');
-
-        parseModifiers.stop = true;
-        var params = [];
-        for (var colon=s.match(/^\s*:\s*/); colon; colon=s.match(/^\s*:\s*/))
-        {
-            e.value += s.slice(0,colon[0].length);
-            s = s.slice(colon[0].length);
-
-            var param = {value:'', tree:[]};
-            if (lookUp(s, param))
-            {
-                e.value += param.value;
-                params.push(param.tree[0]);
-                s = s.slice(param.value.length);
-            }
-            else
-            {
-                parseText('',params);
-            }
-        }
-        parseModifiers.stop = false;
-
-        params.unshift(e.tree.pop());  //modifiers have the highest priority
-        e.tree.push(parseFunc(fnm,{__parsed:params},[])[0]);
-
-        parseModifiers(s, e);  //modifiers can be combined
-    }
-
-    function lookUp(s,e)
-    {
-        if (!s)
-        {
-            return false;
-        }
-
-        if (s.substr(0,jSmart.prototype.left_delimiter.length)==jSmart.prototype.left_delimiter)
-        {
-            var tag = findTag('',s);
-            if (tag)
-            {
-                e.token = tag[0];
-                e.value += tag[0];
-                parse(tag[0], e.tree);
-                parseModifiers(s.slice(e.value.length), e);
-                return true;
-            }
-        }
-
-        for (var i=0; i<tokens.length; ++i)
-        {
-            if (s.match(tokens[i].re))
-            {
-                e.token = RegExp.lastMatch;
-                e.value += RegExp.lastMatch;
-                tokens[i].parse(e, s.slice(e.token.length));
-                return true;
-            }
-        }
-        return false;
-    }
-
-    function bundleOp(i, tree, precedence)
-    {
-        var op = tree[i];
-        if (op.name == 'operator' && op.precedence == precedence && !op.params.__parsed)
-        {
-            if (op.optype == 'binary')
-            {
-                op.params.__parsed = [tree[i-1],tree[i+1]];
-                tree.splice(i-1,3,op);
-                return true;
-            }
-            else if (op.optype == 'post-unary')
-            {
-                op.params.__parsed = [tree[i-1]];
-                tree.splice(i-1,2,op);
-                return true;
-            }
-
-            op.params.__parsed = [tree[i+1]];
-            tree.splice(i,2,op);
-        }
-        return false;
-    }
-
-    function composeExpression(tree)
-    {
-        var i = 0;
-        for (i=0; i<tree.length; ++i)
-        {
-            if (tree[i] instanceof Array)
-            {
-                tree[i] = composeExpression(tree[i])
-            }
-        }
-
-        for (var precedence=1; precedence<14; ++precedence)
-        {
-            if (precedence==2 || precedence==10)
-            {
-                for (i=tree.length; i>0; --i)
-                {
-                    i -= bundleOp(i-1, tree, precedence);
-                }
-            }
-            else
-            {
-                for (i=0; i<tree.length; ++i)
-                {
-                    i -= bundleOp(i, tree, precedence);
-                }
-            }
-        }
-        return tree[0]; //only one node must be left
-    }
-
-    function parseExpression(s)
-    {
-        var e = { value:'', tree:[] };
-        while (lookUp(s.slice(e.value.length), e)){}
-        if (!e.tree.length)
-        {
-            return false;
-        }
-        e.tree = composeExpression(e.tree);
-        return e;
-    }
-
-    function parseParams(paramsStr, reDelim, reName)
-    {
-        var s = paramsStr.replace(/\n/g,' ').replace(/^\s+|\s+$/g,'');
-        var params = [];
-        params.__parsed = [];
-        var paramsStr = '';
-
-        if (!s)
-        {
-            return params;
-        }
-
-        if (!reDelim)
-        {
-            reDelim = /^\s+/;
-            reName = /^(\w+)\s*=\s*/;
-        }
-
-        while (s)
-        {
-            var nm = null;
-            if (reName)
-            {
-                var foundName = s.match(reName);
-                if (foundName)
-                {
-                    nm = trimQuotes(foundName[1]);
-                    paramsStr += s.slice(0,foundName[0].length);
-                    s = s.slice(foundName[0].length);
-                }
-            }
-
-            var param = parseExpression(s);
-            if (!param)
-            {
-                break;
-            }
-
-            if (nm)
-            {
-                params[nm] = param.value;
-                params.__parsed[nm] = param.tree;
-            }
-            else
-            {
-                params.push(param.value);
-                params.__parsed.push(param.tree);
-            }
-
-            paramsStr += s.slice(0,param.value.length);
-            s = s.slice(param.value.length);
-
-            var foundDelim = s.match(reDelim);
-            if (foundDelim)
-            {
-                paramsStr += s.slice(0,foundDelim[0].length);
-                s = s.slice(foundDelim[0].length);
-            }
-            else
-            {
-                break;
-            }
-        }
-        params.toString = function() { return paramsStr; }
-        return params;
-    }
-
-    function parsePluginBlock(name, params, tree, content)
-    {
-        tree.push({
-            type: 'plugin',
-            name: name,
-            params: params,
-            subTree: parse(content,[])
-        });
-    }
-
-    function parsePluginFunc(name, params, tree)
-    {
-        tree.push({
-            type: 'plugin',
-            name: name,
-            params: params
-        });
-    }
-
-    function getActualParamValues(params,data)
-    {
-        var actualParams = [];
-        for (var nm in params.__parsed)
-        {
-            if (params.__parsed.hasOwnProperty(nm))
-            {
-                var v = process([params.__parsed[nm]], data);
-                actualParams[nm] = v;
-            }
-        }
-
-        actualParams.__get = function(nm,defVal,id)
-        {
-            if (nm in actualParams && typeof(actualParams[nm]) != 'undefined')
-            {
-                return actualParams[nm];
-            }
-            if (typeof(id)!='undefined' && typeof(actualParams[id]) != 'undefined')
-            {
-                return actualParams[id];
-            }
-            if (defVal === null)
-            {
-                throw new Error("The required attribute '"+nm+"' is missing");
-            }
-            return defVal;
-        };
-        return actualParams;
-    }
-
-    /**
-     * Returns boolean true if object is empty otherwise false.
-     *
-     * @param object hash Object you are testing against.
-     *
-     * @return boolean
-     */
-    function isEmptyObject(hash) {
-        for (var i in hash) {
-            if (hash.hasOwnProperty(i)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    function getVarValue(node, data, val)
-    {
-        var v = data;
-        var nm = '';
-        for (var i=0; i<node.parts.length; ++i)
-        {
-            var part = node.parts[i];
-            if (part.type == 'plugin' && part.name == '__func' && part.hasOwner)
-            {
-                data.__owner = v;
-                v = process([node.parts[i]],data);
-                delete data.__owner;
-            }
-            else
-            {
-                nm = process([part],data);
-
-                //section name
-                if (nm in data.smarty.section && part.type=='text' && process([node.parts[0]],data)!='smarty')
-                {
-                    nm = data.smarty.section[nm].index;
-                }
-
-                //add to array
-                if (!nm && typeof val != 'undefined' && v instanceof Array)
-                {
-                    nm = v.length;
-                }
-
-                //set new value
-                if (typeof val != 'undefined' && i==node.parts.length-1)
-                {
-                    v[nm] = val;
-                }
-
-                if (typeof v == 'object' && v !== null && nm in v)
-                {
-                    v = v[nm];
-                }
-                else
-                {
-                    if (typeof val == 'undefined')
-                    {
-                        return val;
-                    }
-                    v[nm] = {};
-                    v = v[nm];
-                }
-            }
-        }
-        return v;
-    }
-
-    function process(tree, data)
-    {
-        var res = '';
-        for (var i=0; i<tree.length; ++i)
-        {
-            var s = '';
-            var node = tree[i];
-            if (node.type == 'text')
-            {
-                s = node.data;
-            }
-            else if (node.type == 'var')
-            {
-                s = getVarValue(node,data);
-            }
-            else if (node.type == 'build-in')
-            {
-                s = buildInFunctions[node.name].process(node,data);
-            }
-            else if (node.type == 'plugin')
-            {
-                var plugin = plugins[node.name];
-                if (plugin.type == 'block')
-                {
-                    var repeat = {value:true};
-                    plugin.process(getActualParamValues(node.params,data), '', data, repeat);
-                    while (repeat.value)
-                    {
-                        repeat.value = false;
-                        s += plugin.process(
-                            getActualParamValues(node.params,data),
-                            process(node.subTree, data),
-                            data,
-                            repeat
-                        );
-                    }
-                }
-                else if (plugin.type == 'function')
-                {
-                    s = plugin.process(getActualParamValues(node.params,data), data);
-                }
-            }
-            if (typeof s == 'boolean')
-            {
-                s = s ? '1' : '';
-            }
-            if (s == null) {
-                s = '';
-            }
-            if (tree.length == 1)
-            {
-                return s;
-            }
-            res += s!==null ? s : '';
-
-            if (data.smarty['continue'] || data.smarty['break'])
-            {
-                return res;
-            }
-        }
-        return res;
-    }
-
-    function getTemplate(name, tree, nocache)
-    {
-        if (nocache || !(name in files))
-        {
-            var tpl = jSmart.prototype.getTemplate(name);
-            if (typeof(tpl) != 'string')
-            {
-                throw new Error('No template for '+ name);
-            }
-            parse(applyFilters(jSmart.prototype.filters_global.pre, stripComments(tpl.replace(/\r\n/g,'\n'))), tree);
-            files[name] = tree;
-        }
-        else
-        {
-            tree = files[name];
-        }
-        return tree;
-    }
-
-    function stripComments(s)
-    {
-        var sRes = '';
-        for (var openTag=s.match(/{\*/); openTag; openTag=s.match(/{\*/))
-        {
-            sRes += s.slice(0,openTag.index);
-            s = s.slice(openTag.index+openTag[0].length);
-            var closeTag = s.match(/\*}/);
-            if (!closeTag)
-            {
-                throw new Error('Unclosed {*');
-            }
-            s = s.slice(closeTag.index+closeTag[0].length);
-        }
-        return sRes + s;
-    }
-
-    function applyFilters(filters, s)
-    {
-        for (var i=0; i<filters.length; ++i)
-        {
-            s = filters[i](s);
-        }
-        return s;
-    }
-
-
-    jSmart = function(tpl)
-    {
-        this.tree = [];
-        this.tree.blocks = {};
-        this.scripts = {};
-        this.default_modifiers = [];
-        this.filters = {'variable':[], 'post':[]};
-        this.smarty = {
-            'smarty': {
-                block: {},
-                'break': false,
-                capture: {},
-                'continue': false,
-                counter: {},
-                cycle: {},
-                foreach: {},
-                section: {},
-                now: Math.floor( (new Date()).getTime()/1000 ),
-                'const': {},
-                config: {},
-                current_dir: '/',
-                template: '',
-                ldelim: jSmart.prototype.left_delimiter,
-                rdelim: jSmart.prototype.right_delimiter,
-                version: '2.15.0'
-            }
-        };
-        blocks = this.tree.blocks;
-        parse(
-            applyFilters(jSmart.prototype.filters_global.pre, stripComments((new String(tpl?tpl:'')).replace(/\r\n/g,'\n'))),
-            this.tree
-        );
-    };
-
-    jSmart.prototype.fetch = function(data)
-    {
-        blocks = this.tree.blocks;
-        scripts = this.scripts;
-        escape_html = this.escape_html;
-        default_modifiers = jSmart.prototype.default_modifiers_global.concat(this.default_modifiers);
-        this.data = obMerge((typeof data == 'object') ? data : {}, this.smarty);
-        varFilters = jSmart.prototype.filters_global.variable.concat(this.filters.variable);
-        var res = process(this.tree, this.data);
-        if (jSmart.prototype.debugging)
-        {
-            plugins.debug.process([],this.data);
-        }
-        return applyFilters(jSmart.prototype.filters_global.post.concat(this.filters.post), res);
-    };
-
-    jSmart.prototype.escape_html = false;
-
-    /**
-       @param type  valid values are 'function', 'block', 'modifier'
-       @param callback  func(params,data)  or  block(params,content,data,repeat)
-    */
-    jSmart.prototype.registerPlugin = function(type, name, callback)
-    {
-        if (type == 'modifier')
-        {
-            modifiers[name] = callback;
-        }
-        else
-        {
-            plugins[name] = {'type': type, 'process': callback};
-        }
-    };
-
-    /**
-       @param type  valid values are 'pre', 'variable', 'post'
-       @param callback function(textValue) { ... }
-    */
-    jSmart.prototype.registerFilter = function(type, callback)
-    {
-        (this.tree ? this.filters : jSmart.prototype.filters_global)[type=='output'?'post':type].push(callback);
-    }
-
-    jSmart.prototype.filters_global = {'pre':[],'variable':[],'post':[]};
-
-    jSmart.prototype.configLoad = function(confValues, section, data)
-    {
-        data = data ? data : this.data;
-        var s = confValues.replace(/\r\n/g,'\n').replace(/^\s+|\s+$/g,'');
-        var re = /^\s*(?:\[([^\]]+)\]|(?:(\w+)[ \t]*=[ \t]*("""|'[^'\\\n]*(?:\\.[^'\\\n]*)*'|"[^"\\\n]*(?:\\.[^"\\\n]*)*"|[^\n]*)))/m;
-        var currSect = '';
-        for (var f=s.match(re); f; f=s.match(re))
-        {
-                s = s.slice(f.index+f[0].length);
-                if (f[1])
-                {
-                         currSect = f[1];
-                }
-                else if ((!currSect || currSect == section) && currSect.substr(0,1) != '.')
-                {
-                         if (f[3] == '"""')
-                         {
-                                  var triple = s.match(/"""/);
-                                  if (triple)
-                                  {
-                                           data.smarty.config[f[2]] = s.slice(0,triple.index);
-                                           s = s.slice(triple.index + triple[0].length);
-                                  }
-                         }
-                         else
-                         {
-                                  data.smarty.config[f[2]] = trimQuotes(f[3]);
-                         }
-                }
-                var newln = s.match(/\n+/);
-                if (newln)
-                {
-                         s = s.slice(newln.index + newln[0].length);
-                }
-                else
-                {
-                         break;
-                }
-        }
-    }
-
-    jSmart.prototype.clearConfig = function(varName)
-    {
-        if (varName)
-        {
-            delete this.data.smarty.config[varName];
-        }
-        else
-        {
-            this.data.smarty.config = {};
-        }
-    }
-
-    /**
-       add modifier to implicitly apply to every variable in a template
-       @param modifiers  single string (e.g. "replace:'from':'to'")
-                         or array of strings (e.g. ['escape:"htmlall"', "replace:'from':'to'"])
-     */
-    jSmart.prototype.addDefaultModifier = function(modifiers)
-    {
-        if (!(modifiers instanceof Array))
-        {
-            modifiers = [modifiers];
-        }
-
-        for (var i=0; i<modifiers.length; ++i)
-        {
-            var e = { value:'', tree:[0] };
-            parseModifiers('|'+modifiers[i], e);
-            (this.tree ? this.default_modifiers : this.default_modifiers_global).push( e.tree[0] );
-        }
-    }
-
-    jSmart.prototype.default_modifiers_global = [];
-
-    /**
-       override this function
-       @param name  value of 'file' parameter in {include} and {extends}
-       @return template text
-    */
-    jSmart.prototype.getTemplate = function(name)
-    {
-        throw new Error('No template for ' + name);
-    }
-
-    /**
-       override this function
-       @param name  value of 'file' parameter in {fetch}
-       @return file content
-    */
-    jSmart.prototype.getFile = function(name)
-    {
-        throw new Error('No file for ' + name);
-    }
-
-    /**
-       override this function
-       @param name  value of 'file' parameter in {include_php} and {include_javascript}
-                     or value of 'script' parameter in {insert}
-       @return Javascript script
-    */
-    jSmart.prototype.getJavascript = function(name)
-    {
-        throw new Error('No Javascript for ' + name);
-    }
-
-    /**
-       override this function
-       @param name  value of 'file' parameter in {config_load}
-       @return config file content
-    */
-    jSmart.prototype.getConfig = function(name)
-    {
-        throw new Error('No config for ' + name);
-    }
-
-
-
-    /**
-       whether to skip tags in open brace { followed by white space(s) and close brace } with white space(s) before
-    */
-    jSmart.prototype.auto_literal = true;
-
-    jSmart.prototype.left_delimiter = '{';
-    jSmart.prototype.right_delimiter = '}';
-
-    /** enables the debugging console */
-    jSmart.prototype.debugging = false;
-
-
-    jSmart.prototype.PHPJS = function(fnm, modifier)
-    {
-        if (eval('typeof '+fnm) == 'function')
-        {
-            return (typeof window == 'object') ? window : global;
-        }
-        else if (typeof(PHP_JS) == 'function')
-        {
-            return new PHP_JS();
-        }
-        throw new Error("Modifier '" + modifier + "' uses JavaScript port of PHP function '" + fnm + "'. You can find one at http://phpjs.org");
-    }
-
-    jSmart.prototype.makeTimeStamp = function(s)
-    {
-        if (!s)
-        {
-            return Math.floor( (new Date()).getTime()/1000 );
-        }
-        if (isNaN(s))
-        {
-            var tm = jSmart.prototype.PHPJS('strtotime','date_format').strtotime(s);
-            if (tm == -1 || tm === false) {
-                return Math.floor( (new Date()).getTime()/1000 );
-            }
-            return tm;
-        }
-        s = new String(s);
-        if (s.length == 14) //mysql timestamp format of YYYYMMDDHHMMSS
-        {
-            return Math.floor( (new Date(s.substr(0,4),s.substr(4,2)-1,s.substr(6,2),s.substr(8,2),s.substr(10,2)).getTime()/1000 ) );
-        }
-        return parseInt(s);
-    }
-
-
-
-    /**
-       register custom functions
-    */
-    jSmart.prototype.registerPlugin(
-        'function',
-        '__array',
-        function(params, data)
-        {
-            var a = [];
-            for (var nm in params)
-            {
-                if (params.hasOwnProperty(nm) && params[nm] && typeof params[nm] != 'function')
-                {
-                    a[nm] = params[nm];
-                }
-            }
-            return a;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        '__func',
-        function(params, data) {
-            var paramNames = [], paramValues = {}, paramData = [];
-            for (var i=0; i<params.length; ++i) {
-                paramNames.push(params.name+'__p'+i);
-                paramData.push(params[i]);
-                paramValues[params.name+'__p'+i] = params[i];
-            }
-            var fname, mergedParams = obMerge({}, data, paramValues);
-            if (('__owner' in data && params.name in data.__owner)) {
-                fname = '__owner.'+params.name;
-                return execute(fname + '(' + paramNames.join(',') + ')', mergedParams);
-            } else if (modifiers.hasOwnProperty(params.name)) {
-                fname = modifiers[params.name]
-                return executeByFuncObject(fname, paramData, mergedParams);
-            } else {
-                fname = params.name;
-                return execute(fname + '(' + paramNames.join(',') + ')', mergedParams);
-            }
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        '__quoted',
-        function(params, data)
-        {
-            return params.join('');
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'append',
-        function(params, data)
-        {
-            var varName = params.__get('var',null,0);
-            if (!(varName in data) || !(data[varName] instanceof Array))
-            {
-                data[varName] = [];
-            }
-            var index = params.__get('index',false);
-            var val = params.__get('value',null,1);
-            if (index === false)
-            {
-                data[varName].push(val);
-            }
-            else
-            {
-                data[varName][index] = val;
-            }
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'assign',
-        function(params, data)
-        {
-            assignVar(params.__get('var',null,0), params.__get('value',null,1), data);
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'break',
-        function(params, data)
-        {
-            data.smarty['break'] = true;
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'call',
-        function(params, data)
-        {
-            var fname = params.__get('name',null,0);
-            delete params.name;
-            var assignTo = params.__get('assign',false);
-            delete params.assign;
-            var s = plugins[fname].process(params, data);
-            if (assignTo)
-            {
-                assignVar(assignTo, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'block',
-        'capture',
-        function(params, content, data, repeat)
-        {
-            if (content)
-            {
-                content = content.replace(/^\n/,'');
-                data.smarty.capture[params.__get('name','default',0)] = content;
-
-                if ('assign' in params)
-                {
-                    assignVar(params.assign, content, data);
-                }
-
-                var append = params.__get('append',false);
-                if (append)
-                {
-                    if (append in data)
-                    {
-                        if (data[append] instanceof Array)
-                        {
-                            data[append].push(content);
-                        }
-                    }
-                                       else
-                                       {
-                                                data[append] = [content];
-                                       }
-                }
-            }
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'continue',
-        function(params, data)
-        {
-            data.smarty['continue'] = true;
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'counter',
-        function(params, data)
-        {
-            var name = params.__get('name','default');
-            if (name in data.smarty.counter)
-            {
-                var counter = data.smarty.counter[name];
-                if ('start' in params)
-                {
-                    counter.value = parseInt(params['start']);
-                }
-                else
-                {
-                    counter.value = parseInt(counter.value);
-                    counter.skip = parseInt(counter.skip);
-                    if ('down' == counter.direction)
-                    {
-                        counter.value -= counter.skip;
-                    }
-                    else
-                    {
-                        counter.value += counter.skip;
-                    }
-                }
-                counter.skip = params.__get('skip',counter.skip);
-                counter.direction = params.__get('direction',counter.direction);
-                counter.assign = params.__get('assign',counter.assign);
-            }
-            else
-            {
-                data.smarty.counter[name] = {
-                    value: parseInt(params.__get('start',1)),
-                    skip: parseInt(params.__get('skip',1)),
-                    direction: params.__get('direction','up'),
-                    assign: params.__get('assign',false)
-                };
-            }
-
-            if (data.smarty.counter[name].assign)
-            {
-                data[data.smarty.counter[name].assign] = data.smarty.counter[name].value;
-                return '';
-            }
-
-            if (params.__get('print',true))
-            {
-                return data.smarty.counter[name].value;
-            }
-
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'cycle',
-        function(params, data)
-        {
-            var name = params.__get('name','default');
-            var reset = params.__get('reset',false);
-            if (!(name in data.smarty.cycle))
-            {
-                data.smarty.cycle[name] = {arr: [''], delimiter: params.__get('delimiter',','), index: 0};
-                reset = true;
-            }
-
-            if (params.__get('delimiter',false))
-            {
-                data.smarty.cycle[name].delimiter = params.delimiter;
-            }
-            var values = params.__get('values',false);
-            if (values)
-            {
-                var arr = [];
-                if (values instanceof Object)
-                {
-                    for (nm in values)
-                    {
-                        arr.push(values[nm]);
-                    }
-                }
-                else
-                {
-                    arr = values.split(data.smarty.cycle[name].delimiter);
-                }
-
-                if (arr.length != data.smarty.cycle[name].arr.length || arr[0] != data.smarty.cycle[name].arr[0])
-                {
-                    data.smarty.cycle[name].arr = arr;
-                    data.smarty.cycle[name].index = 0;
-                    reset = true;
-                }
-            }
-
-            if (params.__get('advance','true'))
-            {
-                data.smarty.cycle[name].index += 1;
-            }
-            if (data.smarty.cycle[name].index >= data.smarty.cycle[name].arr.length || reset)
-            {
-                data.smarty.cycle[name].index = 0;
-            }
-
-            if (params.__get('assign',false))
-            {
-                assignVar(params.assign, data.smarty.cycle[name].arr[ data.smarty.cycle[name].index ], data);
-                return '';
-            }
-
-            if (params.__get('print',true))
-            {
-                return data.smarty.cycle[name].arr[ data.smarty.cycle[name].index ];
-            }
-
-            return '';
-        }
-    );
-
-    jSmart.prototype.print_r = function(v,indent)
-    {
-        if (v instanceof Object)
-        {
-            var s = ((v instanceof Array) ? 'Array['+v.length+']' : 'Object') + '<br>';
-            for (var nm in v)
-            {
-                if (v.hasOwnProperty(nm))
-                {
-                    s += indent + '&nbsp;&nbsp;<strong>' + nm + '</strong> : ' + jSmart.prototype.print_r(v[nm],indent+'&nbsp;&nbsp;&nbsp;') + '<br>';
-                }
-            }
-            return s;
-        }
-        return v;
-    }
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'debug',
-        function(params, data)
-        {
-            if (typeof dbgWnd != 'undefined')
-            {
-                dbgWnd.close();
-            }
-            dbgWnd = window.open('','','width=680,height=600,resizable,scrollbars=yes');
-            var sVars = '';
-            var i=0;
-            for (var nm in data)
-            {
-                sVars += '<tr class=' + (++i%2?'odd':'even') + '><td><strong>' + nm + '</strong></td><td>' + jSmart.prototype.print_r(data[nm],'') + '</td></tr>';
-            }
-            dbgWnd.document.write(" \
-               <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'> \
-               <head> \
-                           <title>jSmart Debug Console</title> \
-                  <style type='text/css'> \
-                     table {width: 100%;} \
-                     td {vertical-align:top;width: 50%;} \
-                     .even td {background-color: #fafafa;} \
-                  </style> \
-               </head> \
-               <body> \
-                  <h1>jSmart Debug Console</h1> \
-                  <h2>assigned template variables</h2> \
-                  <table>" + sVars + "</table> \
-               </body> \
-               </html> \
-            ");
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'eval',
-        function(params, data)
-        {
-            var tree = [];
-            parse(params.__get('var','',0), tree);
-            var s = process(tree, data);
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'fetch',
-        function(params, data)
-        {
-            var s = jSmart.prototype.getFile(params.__get('file',null,0));
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_checkboxes',
-        function (params, data) {
-            var type = params.__get('type','checkbox'),
-                name = params.__get('name',type),
-                realName = params.__get('name',type),
-                values = params.__get('values',params.options),
-                output = params.__get('options',[]),
-                useName = ('options' in params),
-                selected = params.__get('selected',false),
-                separator = params.__get('separator',''),
-                labels = Boolean(params.__get('labels',true)),
-                label_ids = Boolean(params.__get('label_ids',false)),
-                p,
-                res = [],
-                i = 0,
-                s = '',
-                value,
-                id;
-
-            if (type == 'checkbox') {
-                name += '[]';
-            }
-            if (!useName) {
-                for (p in params.output) {
-                    output.push(params.output[p]);
-                }
-            }
-
-            for (p in values) {
-                if (values.hasOwnProperty(p)) {
-                    value = (useName ? p : values[p]);
-                    id = realName + '_' + value;
-                    s = (labels ? ( label_ids ? '<label for="'+id+'">' : '<label>') : '');
-
-                    s += '<input type="' + type + '" name="' + name + '" value="' + value + '" ';
-                    if (label_ids) {
-                        s += 'id="'+id+'" ';
-                    }
-                    if (selected == (useName ? p : values[p])) {
-                        s += 'checked="checked" ';
-                    }
-                    s += '/>' + output[useName?p:i++];
-                    s += (labels ? '</label>' : '');
-                    s += separator;
-                    res.push(s);
-                }
-            }
-            if ('assign' in params) {
-                assignVar(params.assign, res, data);
-                return '';
-            }
-            return res.join('\n');
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_image',
-        function (params, data) {
-            var url = params.__get('file', null),
-                width = params.__get('width', false),
-                height = params.__get('height', false),
-                alt = params.__get('alt', ''),
-                href = params.__get('href', params.__get('link', false)),
-                path_prefix = params.__get('path_prefix', ''),
-                paramNames = {file:1, width:1, height:1, alt:1, href:1, basedir:1, path_prefix:1, link:1},
-                s = '<img src="' + path_prefix + url + '"' + ' alt="'+alt+'"' + (width ? ' width="'+width+'"':'') + (height ? ' height="'+height+'"':''),
-                p;
-
-            for (p in params) {
-                if (params.hasOwnProperty(p) && typeof(params[p]) == 'string') {
-                    if (!(p in paramNames)) {
-                        s += ' ' + p + '="' + params[p] + '"';
-                    }
-                }
-            }
-            s += ' />';
-            return href ? '<a href="'+href+'">'+s+'</a>' : s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_options',
-        function(params, data)
-        {
-            var values = params.__get('values',params.options);
-            var output = params.__get('options',[]);
-            var useName = ('options' in params);
-            var p;
-            if (!useName)
-            {
-                for (p in params.output)
-                {
-                    output.push(params.output[p]);
-                }
-            }
-            var selected = params.__get('selected',false);
-
-            var res = [];
-            var s = '';
-            var i = 0;
-            for (p in values)
-            {
-                if (values.hasOwnProperty(p))
-                {
-                    s = '<option value="' + (useName ? p : values[p]) + '"';
-                    if (selected == (useName ? p : values[p]))
-                    {
-                        s += ' selected="selected"';
-                    }
-                    s += '>' + output[useName ? p : i++] + '</option>';
-                    res.push(s);
-                }
-            }
-            var name = params.__get('name',false);
-            return (name ? ('<select name="' + name + '">\n' + res.join('\n') + '\n</select>') : res.join('\n')) + '\n';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_radios',
-        function(params, data)
-        {
-            params.type = 'radio';
-            return plugins.html_checkboxes.process(params,data);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_select_date',
-        function(params, data)
-        {
-            var prefix = params.__get('prefix','Date_');
-            var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
-
-            var s = '';
-            s += '<select name="'+prefix+'Month">\n';
-            var i=0;
-            for (i=0; i<months.length; ++i)
-            {
-                s += '<option value="' + i + '">' + months[i] + '</option>\n';
-            }
-            s += '</select>\n'
-
-            s += '<select name="'+prefix+'Day">\n';
-            for (i=0; i<31; ++i)
-            {
-                s += '<option value="' + i + '">' + i + '</option>\n';
-            }
-            s += '</select>\n'
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'html_table',
-        function(params, data)
-        {
-            var loop = [];
-            var p;
-            if (params.loop instanceof Array)
-            {
-                loop = params.loop
-            }
-            else
-            {
-                for (p in params.loop)
-                {
-                    if (params.loop.hasOwnProperty(p))
-                    {
-                        loop.push( params.loop[p] );
-                    }
-                }
-            }
-            var rows = params.__get('rows',false);
-            var cols = params.__get('cols',false);
-            if (!cols)
-            {
-                cols = rows ? Math.ceil(loop.length/rows) : 3;
-            }
-            var colNames = [];
-            if (isNaN(cols))
-            {
-                if (typeof cols == 'object')
-                {
-                    for (p in cols)
-                    {
-                        if (cols.hasOwnProperty(p))
-                        {
-                            colNames.push(cols[p]);
-                        }
-                    }
-                }
-                else
-                {
-                    colNames = cols.split(/\s*,\s*/);
-                }
-                cols = colNames.length;
-            }
-            rows = rows ? rows : Math.ceil(loop.length/cols);
-
-            var inner = params.__get('inner','cols');
-            var caption = params.__get('caption','');
-            var table_attr = params.__get('table_attr','border="1"');
-            var th_attr = params.__get('th_attr',false);
-            if (th_attr && typeof th_attr != 'object')
-            {
-                th_attr = [th_attr];
-            }
-            var tr_attr = params.__get('tr_attr',false);
-            if (tr_attr && typeof tr_attr != 'object')
-            {
-                tr_attr = [tr_attr];
-            }
-            var td_attr = params.__get('td_attr',false);
-            if (td_attr && typeof td_attr != 'object')
-            {
-                td_attr = [td_attr];
-            }
-            var trailpad = params.__get('trailpad','&nbsp;');
-            var hdir = params.__get('hdir','right');
-            var vdir = params.__get('vdir','down');
-
-            var s = '';
-            for (var row=0; row<rows; ++row)
-            {
-                s += '<tr' + (tr_attr ? ' '+tr_attr[row%tr_attr.length] : '') + '>\n';
-                for (var col=0; col<cols; ++col)
-                {
-                    var idx = (inner=='cols') ? ((vdir=='down'?row:rows-1-row) * cols + (hdir=='right'?col:cols-1-col)) : ((hdir=='right'?col:cols-1-col) * rows + (vdir=='down'?row:rows-1-row));
-
-                    s += '<td' + (td_attr ? ' '+td_attr[col%td_attr.length] : '') + '>' + (idx < loop.length ? loop[idx] : trailpad) + '</td>\n';
-                }
-                s += '</tr>\n';
-            }
-
-            var sHead = '';
-            if (colNames.length)
-            {
-                sHead = '\n<thead><tr>';
-                for (var i=0; i<colNames.length; ++i)
-                {
-                    sHead += '\n<th' + (th_attr ? ' '+th_attr[i%th_attr.length] : '') + '>' + colNames[hdir=='right'?i:colNames.length-1-i] + '</th>';
-                }
-                sHead += '\n</tr></thead>';
-            }
-
-            return '<table ' + table_attr + '>' + (caption?'\n<caption>'+caption+'</caption>':'') + sHead + '\n<tbody>\n' + s + '</tbody>\n</table>\n';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'include',
-        function(params, data)
-        {
-            var file = params.__get('file',null,0);
-            var incData = obMerge({},data,params);
-            incData.smarty.template = file;
-            var s = process(getTemplate(file,[],findInArray(params,'nocache')>=0), incData);
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'include_javascript',
-        function(params, data)
-        {
-            var file = params.__get('file',null,0);
-            if (params.__get('once',true) && file in scripts)
-            {
-                return '';
-            }
-            scripts[file] = true;
-            var s = execute(jSmart.prototype.getJavascript(file), {'$this':data});
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'include_php',
-        function(params, data)
-        {
-            return plugins['include_javascript'].process(params,data);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'insert',
-        function(params, data)
-        {
-            var fparams = {};
-            for (var nm in params)
-            {
-                if (params.hasOwnProperty(nm) && isNaN(nm) && params[nm] && typeof params[nm] == 'string' && nm != 'name' && nm != 'assign' && nm != 'script')
-                {
-                    fparams[nm] = params[nm];
-                }
-            }
-            var prefix = 'insert_';
-            if ('script' in params)
-            {
-                eval(jSmart.prototype.getJavascript(params.script));
-                prefix = 'smarty_insert_';
-            }
-            var func = eval(prefix+params.__get('name',null,0));
-            var s = func(fparams, data);
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'block',
-        'javascript',
-        function(params, content, data, repeat)
-        {
-            data['$this'] = data;
-            execute(content,data);
-            delete data['$this'];
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'config_load',
-        function(params, data)
-        {
-            jSmart.prototype.configLoad(jSmart.prototype.getConfig(params.__get('file',null,0)), params.__get('section','',1), data);
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'mailto',
-        function(params, data)
-        {
-            var address = params.__get('address',null);
-            var encode = params.__get('encode','none');
-            var text = params.__get('text',address);
-            var cc = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('cc','')).replace('%40','@');
-            var bcc = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('bcc','')).replace('%40','@');
-            var followupto = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('followupto','')).replace('%40','@');
-            var subject = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode( params.__get('subject','') );
-            var newsgroups = jSmart.prototype.PHPJS('rawurlencode','mailto').rawurlencode(params.__get('newsgroups',''));
-            var extra = params.__get('extra','');
-
-            address += (cc?'?cc='+cc:'');
-            address += (bcc?(cc?'&':'?')+'bcc='+bcc:'');
-            address += (subject ? ((cc||bcc)?'&':'?') + 'subject='+subject : '');
-            address += (newsgroups ? ((cc||bcc||subject)?'&':'?') + 'newsgroups='+newsgroups : '');
-            address += (followupto ? ((cc||bcc||subject||newsgroups)?'&':'?') + 'followupto='+followupto : '');
-
-            s = '<a href="mailto:' + address + '" ' + extra + '>' + text + '</a>';
-
-            if (encode == 'javascript')
-            {
-                s = "document.write('" + s + "');";
-                var sEncoded = '';
-                for (var i=0; i<s.length; ++i)
-                {
-                    sEncoded += '%' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(s.substr(i,1));
-                }
-                return '<script type="text/javascript">eval(unescape(\'' + sEncoded + "'))</script>";
-            }
-            else if (encode == 'javascript_charcode')
-            {
-                var codes = [];
-                for (var i=0; i<s.length; ++i)
-                {
-                    codes.push(jSmart.prototype.PHPJS('ord','mailto').ord(s.substr(i,1)));
-                }
-                return '<script type="text/javascript" language="javascript">\n<!--\n{document.write(String.fromCharCode('
-                    + codes.join(',') + '))}\n//-->\n</script>\n';
-            }
-            else if (encode == 'hex')
-            {
-                if (address.match(/^.+\?.+$/))
-                {
-                    throw new Error('mailto: hex encoding does not work with extra attributes. Try javascript.');
-                }
-                var aEncoded = '';
-                for (var i=0; i<address.length; ++i)
-                {
-                    if (address.substr(i,1).match(/\w/))
-                    {
-                        aEncoded += '%' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(address.substr(i,1));
-                    }
-                    else
-                    {
-                        aEncoded += address.substr(i,1);
-                    }
-                }
-                aEncoded = aEncoded.toLowerCase();
-                var tEncoded = '';
-                for (var i=0; i<text.length; ++i)
-                {
-                    tEncoded += '&#x' + jSmart.prototype.PHPJS('bin2hex','mailto').bin2hex(text.substr(i,1)) + ';';
-                }
-                tEncoded = tEncoded.toLowerCase();
-                return '<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;' + aEncoded + '" ' + extra + '>' + tEncoded + '</a>';
-            }
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'function',
-        'math',
-        function(params, data)
-        {
-            with (Math)
-            {
-                with (params)
-                {
-                    var res = eval(params.__get('equation',null).replace(/pi\(\s*\)/g,'PI'));
-                }
-            }
-
-            if ('format' in params)
-            {
-                res = jSmart.prototype.PHPJS('sprintf','math').sprintf(params.format,res);
-            }
-
-            if ('assign' in params)
-            {
-                assignVar(params.assign, res, data);
-                return '';
-            }
-            return res;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'block',
-        'nocache',
-        function(params, content, data, repeat)
-        {
-            return content;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'block',
-        'textformat',
-        function(params, content, data, repeat)
-        {
-            if (!content) {
-                return '';
-            }
-
-            content = new String(content);
-
-            var wrap = params.__get('wrap',80);
-            var wrap_char = params.__get('wrap_char','\n');
-            var wrap_cut = params.__get('wrap_cut',false);
-            var indent_char = params.__get('indent_char',' ');
-            var indent = params.__get('indent',0);
-            var indentStr = (new Array(indent+1)).join(indent_char);
-            var indent_first = params.__get('indent_first',0);
-            var indentFirstStr = (new Array(indent_first+1)).join(indent_char);
-
-            var style = params.__get('style','');
-
-            if (style == 'email') {
-                wrap = 72;
-            }
-
-            var paragraphs = content.split(/[\r\n]{2}/);
-            for (var i=0; i<paragraphs.length; ++i) {
-                var p = paragraphs[i];
-                if (!p) {
-                    continue;
-                }
-                p = p.replace(/^\s+|\s+$/,'').replace(/\s+/g,' ');
-                if (indent_first> 0 ) {
-                    p = indentFirstStr + p;
-                }
-                p = modifiers.wordwrap(p, wrap-indent, wrap_char, wrap_cut);
-                if (indent > 0) {
-                    p = p.replace(/^/mg, indentStr);
-                }
-                paragraphs[i] = p;
-            }
-            var s = paragraphs.join(wrap_char+wrap_char);
-            if ('assign' in params)
-            {
-                assignVar(params.assign, s, data);
-                return '';
-            }
-            return s;
-        }
-    );
-
-
-    /**
-       register modifiers
-    */
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'capitalize',
-        function(s, upDigits, lcRest) {
-            if (typeof s != 'string') {
-                return s;
-            }
-            var re = new RegExp(upDigits ? '[^a-zA-Z_\u00E0-\u00FC]+' : '[^a-zA-Z0-9_\u00E0-\u00FC]');
-            var found = null;
-            var res = '';
-            if (lcRest) {
-                s = s.toLowerCase();
-            }
-            for (found=s.match(re); found; found=s.match(re))
-            {
-                    var word = s.slice(0,found.index);
-                if (word.match(/\d/))
-                {
-                    res += word;
-                }
-                else
-                {
-                        res += word.charAt(0).toUpperCase() + word.slice(1);
-                }
-                res += s.slice(found.index, found.index+found[0].length);
-                    s = s.slice(found.index+found[0].length);
-            }
-            if (s.match(/\d/))
-            {
-                return res + s;
-            }
-            return res + s.charAt(0).toUpperCase() + s.slice(1);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'cat',
-        function(s, value)
-        {
-            value = value ? value : '';
-            return new String(s) + value;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'count',
-        function(v, recursive)
-        {
-            if (v === null || typeof v === 'undefined') {
-                return 0;
-            } else if (v.constructor !== Array && v.constructor !== Object) {
-                return 1;
-            }
-
-            recursive = Boolean(recursive);
-            var k, cnt = 0;
-            for (k in v)
-            {
-                if (v.hasOwnProperty(k))
-                {
-                    cnt++;
-                    if (recursive && v[k] && (v[k].constructor === Array || v[k].constructor === Object)) {
-                        cnt += modifiers.count(v[k], true);
-                    }
-                }
-            }
-            return cnt;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'count_characters',
-        function(s, includeWhitespaces)
-        {
-            s = new String(s);
-            return includeWhitespaces ? s.length : s.replace(/\s/g,'').length;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'count_paragraphs',
-        function(s)
-        {
-            var found = (new String(s)).match(/\n+/g);
-            if (found)
-            {
-                    return found.length+1;
-            }
-            return 1;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'count_sentences',
-        function(s)
-        {
-            if (typeof s == 'string')
-            {
-                var found = s.match(/[^\s]\.(?!\w)/g);
-                if (found)
-                {
-                        return found.length;
-                }
-            }
-            return 0;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'count_words',
-        function(s)
-        {
-            if (typeof s == 'string')
-            {
-                var found = s.match(/\w+/g);
-                if (found)
-                {
-                        return found.length;
-                }
-            }
-            return 0;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'date_format',
-        function(s, fmt, defaultDate)
-        {
-            return jSmart.prototype.PHPJS('strftime','date_format').strftime(fmt?fmt:'%b %e, %Y', jSmart.prototype.makeTimeStamp(s?s:defaultDate));
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'defaultValue',
-        function(s, value)
-        {
-            return (s && s!='null' && s!='undefined') ? s : (value ? value : '');
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'unescape',
-        function(s, esc_type, char_set)
-        {
-            s = new String(s);
-            esc_type = esc_type || 'html';
-            char_set = char_set || 'UTF-8';
-
-            switch (esc_type)
-            {
-            case 'html':
-                return s.replace(/&lt;/g, '<').replace(/&gt;/g,'>').replace(/&#039;/g,"'").replace(/&quot;/g,'"');
-            case 'entity':
-            case 'htmlall':
-                return jSmart.prototype.PHPJS('html_entity_decode','unescape').html_entity_decode(s, 1);
-            case 'url':
-                return jSmart.prototype.PHPJS('rawurldecode','unescape').rawurldecode(s);
-            };
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'escape',
-        function(s, esc_type, char_set, double_encode)
-        {
-            s = new String(s);
-            esc_type = esc_type || 'html';
-            char_set = char_set || 'UTF-8';
-            double_encode = (typeof double_encode != 'undefined') ? Boolean(double_encode) : true;
-
-            switch (esc_type)
-            {
-            case 'html':
-                if (double_encode) {
-                                  s = s.replace(/&/g, '&amp;');
-                         }
-                return s.replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/'/g,'&#039;').replace(/"/g,'&quot;');
-            case 'htmlall':
-                return jSmart.prototype.PHPJS('htmlentities','escape').htmlentities(s, 3, char_set);
-            case 'url':
-                return jSmart.prototype.PHPJS('rawurlencode','escape').rawurlencode(s);
-            case 'urlpathinfo':
-                return jSmart.prototype.PHPJS('rawurlencode','escape').rawurlencode(s).replace(/%2F/g, '/');
-            case 'quotes':
-                return s.replace(/(^|[^\\])'/g, "$1\\'");
-            case 'hex':
-                var res = '';
-                for (var i=0; i<s.length; ++i)
-                {
-                    res += '%' + jSmart.prototype.PHPJS('bin2hex','escape').bin2hex(s.substr(i,1)).toLowerCase();
-                }
-                return res;
-            case 'hexentity':
-                var res = '';
-                for (var i=0; i<s.length; ++i) {
-                    res += '&#x' + jSmart.prototype.PHPJS('bin2hex','escape').bin2hex(s.substr(i,1)) + ';';
-                }
-                return res;
-            case 'decentity':
-                var res = '';
-                for (var i=0; i<s.length; ++i) {
-                    res += '&#' + jSmart.prototype.PHPJS('ord','escape').ord(s.substr(i,1)) + ';';
-                }
-                return res;
-            case 'mail':
-                return s.replace(/@/g,' [AT] ').replace(/[.]/g,' [DOT] ');
-            case 'nonstd':
-                var res = '';
-                for (var i=0; i<s.length; ++i)
-                {
-                    var _ord = jSmart.prototype.PHPJS('ord','escape').ord(s.substr(i,1));
-                    if (_ord >= 126) {
-                        res += '&#' + _ord + ';';
-                    } else {
-                        res += s.substr(i, 1);
-                    }
-
-                }
-                return res;
-            case 'javascript':
-                return s.replace(/\\/g,'\\\\').replace(/'/g,"\\'").replace(/"/g,'\\"').replace(/\r/g,'\\r').replace(/\n/g,'\\n').replace(/<\//g,'<\/');
-            };
-            return s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'indent',
-        function(s, repeat, indentWith)
-        {
-            s = new String(s);
-            repeat = repeat ? repeat : 4;
-            indentWith = indentWith ? indentWith : ' ';
-
-            var indentStr = '';
-            while (repeat--)
-            {
-                indentStr += indentWith;
-            }
-
-            var tail = s.match(/\n+$/);
-            return indentStr + s.replace(/\n+$/,'').replace(/\n/g,'\n'+indentStr) + (tail ? tail[0] : '');
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'lower',
-        function(s)
-        {
-            return new String(s).toLowerCase();
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'nl2br',
-        function(s)
-        {
-            return new String(s).replace(/\n/g,'<br />\n');
-        }
-    );
-
-    /**
-        only modifiers (flags) 'i' and 'm' are supported
-        backslashes should be escaped e.g. \\s
-    */
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'regex_replace',
-        function(s, re, replaceWith)
-        {
-            var pattern = re.match(/^ *\/(.*)\/(.*) *$/);
-            return (new String(s)).replace(new RegExp(pattern[1],'g'+(pattern.length>1?pattern[2]:'')), replaceWith);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'replace',
-        function(s, search, replaceWith)
-        {
-            if (!search)
-            {
-                return s;
-            }
-            s = new String(s);
-            search = new String(search);
-            replaceWith = new String(replaceWith);
-            var res = '';
-            var pos = -1;
-            for (pos=s.indexOf(search); pos>=0; pos=s.indexOf(search))
-            {
-                res += s.slice(0,pos) + replaceWith;
-                pos += search.length;
-                s = s.slice(pos);
-            }
-            return res + s;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'spacify',
-        function(s, space)
-        {
-            if (!space)
-            {
-                space = ' ';
-            }
-            return (new String(s)).replace(/(\n|.)(?!$)/g,'$1'+space);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'noprint',
-        function(s)
-        {
-            return '';
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'string_format',
-        function(s, fmt)
-        {
-            return jSmart.prototype.PHPJS('sprintf','string_format').sprintf(fmt,s);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'strip',
-        function(s, replaceWith)
-        {
-            replaceWith = replaceWith ? replaceWith : ' ';
-            return (new String(s)).replace(/[\s]+/g, replaceWith);
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'strip_tags',
-        function(s, addSpace)
-        {
-            addSpace = (addSpace==null) ? true : addSpace;
-            return (new String(s)).replace(/<[^>]*?>/g, addSpace ? ' ' : '');
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'truncate',
-        function(s, length, etc, breakWords, middle)
-        {
-            s = new String(s);
-            length = length ? length : 80;
-            etc = (etc!=null) ? etc : '...';
-
-            if (s.length <= length)
-            {
-                return s;
-            }
-
-            length -= Math.min(length,etc.length);
-            if (middle)
-            {
-                //one of floor()'s should be replaced with ceil() but it so in Smarty
-                return s.slice(0,Math.floor(length/2)) + etc + s.slice(s.length-Math.floor(length/2));
-            }
-
-            if (!breakWords)
-            {
-                s = s.slice(0,length+1).replace(/\s+?(\S+)?$/,'');
-            }
-
-            return s.slice(0,length) + etc;
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'upper',
-        function(s)
-        {
-            return (new String(s)).toUpperCase();
-        }
-    );
-
-    jSmart.prototype.registerPlugin(
-        'modifier',
-        'wordwrap',
-        function(s, width, wrapWith, breakWords)
-        {
-               width = width || 80;
-               wrapWith = wrapWith || '\n';
-
-               var lines = (new String(s)).split('\n');
-               for (var i=0; i<lines.length; ++i)
-               {
-                       var line = lines[i];
-                var parts = ''
-                       while (line.length > width)
-                       {
-                    var pos = 0;
-                    var found = line.slice(pos).match(/\s+/);
-                    for (;found && (pos+found.index)<=width; found=line.slice(pos).match(/\s+/))
-                    {
-                        pos += found.index + found[0].length;
-                    }
-                    pos = pos || (breakWords ? width : (found ? found.index+found[0].length : line.length));
-                    parts += line.slice(0,pos).replace(/\s+$/,'');// + wrapWith;
-                    if (pos < line.length)
-                    {
-                        parts += wrapWith;
-                    }
-                    line = line.slice(pos);
-                }
-                       lines[i] = parts + line;
-               }
-               return lines.join('\n');
-        }
-    );
-
-
-    String.prototype.fetch = function(data)
-    {
-        var tpl = new jSmart(this);
-        return tpl.fetch(data);
-    };
-
-    if (typeof module === "object" && module && typeof module.exports === "object") {
-        module.exports = jSmart;
-    } else {
-        if (typeof global !== "undefined") {
-            global.jSmart = jSmart;
-        }
-
-        if (typeof define === "function" && define.amd) {
-            define("jSmart", [], function () { return jSmart; });
-        }
-    }
-})();
diff --git a/view/theme/frio/frameworks/jsmart/jsmart.min.js b/view/theme/frio/frameworks/jsmart/jsmart.min.js
deleted file mode 100644 (file)
index 51764df..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/*!
- * jSmart Javascript template engine (v2.15.0)
- * https://github.com/umakantp/jsmart
- * http://opensource.org/licenses/LGPL-3.0
- *
- * Copyright 2011-2015, Max Miroshnikov <miroshnikov at gmail dot com>
- *                      Umakant Patil <me @ umakantpatil dot com>
- */
-!function(){function obMerge(a){for(var b=1;b<arguments.length;++b)for(var c in arguments[b])a[c]=arguments[b][c];return a}function countProperties(a){var b=0;for(var c in a)a.hasOwnProperty(c)&&b++;return b}function findInArray(a,b){if(Array.prototype.indexOf)return a.indexOf(b);for(var c=0;c<a.length;++c)if(a[c]===b)return c;return-1}function evalString(a){return a.replace(/\\t/,"      ").replace(/\\n/,"\n").replace(/\\(['"\\])/g,"$1")}function trimQuotes(a){return evalString(a.replace(/^['"](.*)['"]$/,"$1")).replace(/^\s+|\s+$/g,"")}function findTag(a,b){for(var c=0,d=0,e=jSmart.prototype.left_delimiter,f=jSmart.prototype.right_delimiter,g=jSmart.prototype.auto_literal,h=/^\s*(.+)\s*$/i,i=a?new RegExp("^\\s*("+a+")\\s*$","i"):h,j=0;j<b.length;++j)if(b.substr(j,e.length)==e){if(g&&j+1<b.length&&b.substr(j+1,1).match(/\s/))continue;c||(b=b.slice(j),d+=parseInt(j),j=0),++c}else if(b.substr(j,f.length)==f){if(g&&j-1>=0&&b.substr(j-1,1).match(/\s/))continue;if(!--c){var k=b.slice(e.length,j).replace(/[\r\n]/g," "),l=k.match(i);if(l)return l.index=d,l[0]=b.slice(0,j+f.length),l}0>c&&(c=0)}return null}function findCloseTag(a,b,c){var d="",e=null,f=null,g=0;do{if(e&&(g+=e[0].length),e=findTag(a,c),!e)throw new Error("Unclosed {"+b+"}");d+=c.slice(0,e.index),g+=e.index,c=c.slice(e.index+e[0].length),f=findTag(b,d),f&&(d=d.slice(f.index+f[0].length))}while(f);return e.index=g,e}function findElseTag(a,b,c,d){for(var e=0,f=findTag(c,d);f;f=findTag(c,d)){var g=findTag(a,d);if(!g||g.index>f.index)return f.index+=e,f;d=d.slice(g.index+g[0].length),e+=g.index+g[0].length;var h=findCloseTag(b,a,d);d=d.slice(h.index+h[0].length),e+=h.index+h[0].length}return null}function execute(code,data){if("string"==typeof code)with({__code:code})with(modifiers)with(data)try{return eval(__code)}catch(e){throw new Error(e.message+" in \n"+code)}return code}function executeByFuncObject(a,b){try{return a.apply(this,b)}catch(c){throw new Error(c.message)}}function assignVar(a,b,c){a.match(/\[\]$/)?c[a.replace(/\[\]$/,"")].push(b):c[a]=b}function parse(a,b){for(var c=findTag("",a);c;c=findTag("",a)){c.index&&parseText(a.slice(0,c.index),b),a=a.slice(c.index+c[0].length);var d=c[1].match(/^\s*(\w+)(.*)$/);if(d){var e=d[1],f=d.length>2?d[2].replace(/^\s+|\s+$/g,""):"";if(e in buildInFunctions){var g=buildInFunctions[e],h=("parseParams"in g?g.parseParams:parseParams)(f);if("block"==g.type){a=a.replace(/^\n/,"");var i=findCloseTag("/"+e,e+" +[^}]*",a);g.parse(h,b,a.slice(0,i.index)),a=a.slice(i.index+i[0].length)}else g.parse(h,b),"extends"==e&&(b=[]);a=a.replace(/^\n/,"")}else if(e in plugins){var j=plugins[e];if("block"==j.type){var i=findCloseTag("/"+e,e+" +[^}]*",a);parsePluginBlock(e,parseParams(f),b,a.slice(0,i.index)),a=a.slice(i.index+i[0].length)}else"function"==j.type&&parsePluginFunc(e,parseParams(f),b);("append"==e||"assign"==e||"capture"==e||"eval"==e||"include"==e)&&(a=a.replace(/^\n/,""))}else buildInFunctions.expression.parse(c[1],b)}else{var k=buildInFunctions.expression.parse(c[1],b);"build-in"==k.type&&"operator"==k.name&&"="==k.op&&(a=a.replace(/^\n/,""))}}return a&&parseText(a,b),b}function parseText(a,b){if(parseText.parseEmbeddedVars)for(var c=/([$][\w@]+)|`([^`]*)`/,d=c.exec(a);d;d=c.exec(a))b.push({type:"text",data:a.slice(0,d.index)}),b.push(parseExpression(d[1]?d[1]:d[2]).tree),a=a.slice(d.index+d[0].length);return b.push({type:"text",data:a}),b}function parseFunc(a,b,c){return b.__parsed.name=parseText(a,[])[0],c.push({type:"plugin",name:"__func",params:b}),c}function parseOperator(a,b,c,d){d.push({type:"build-in",name:"operator",op:a,optype:b,precedence:c,params:{}})}function parseVar(a,b,c){for(var d=b.token,e=[{type:"text",data:c.replace(/^(\w+)@(key|index|iteration|first|last|show|total)/gi,"$1__$2")}],f=/^(?:\.|\s*->\s*|\[\s*)/,g=a.match(f);g;g=a.match(f)){b.token+=g[0],a=a.slice(g[0].length);var h={value:"",tree:[]};if(g[0].match(/\[/)){h=parseExpression(a),h&&(b.token+=h.value,e.push(h.tree),a=a.slice(h.value.length));var i=a.match(/\s*\]/);i&&(b.token+=i[0],a=a.slice(i[0].length))}else{var j=parseModifiers.stop;if(parseModifiers.stop=!0,lookUp(a,h)){b.token+=h.value;var k=h.tree[0];"plugin"==k.type&&"__func"==k.name&&(k.hasOwner=!0),e.push(k),a=a.slice(h.value.length)}else h=!1;parseModifiers.stop=j}h||e.push({type:"text",data:""})}return b.tree.push({type:"var",parts:e}),b.value+=b.token.substr(d.length),onParseVar(b.token),a}function onParseVar(){}function parseModifiers(a,b){if(!parseModifiers.stop){var c=a.match(/^\|(\w+)/);if(c){b.value+=c[0];var d="default"==c[1]?"defaultValue":c[1];a=a.slice(c[0].length).replace(/^\s+/,""),parseModifiers.stop=!0;for(var e=[],f=a.match(/^\s*:\s*/);f;f=a.match(/^\s*:\s*/)){b.value+=a.slice(0,f[0].length),a=a.slice(f[0].length);var g={value:"",tree:[]};lookUp(a,g)?(b.value+=g.value,e.push(g.tree[0]),a=a.slice(g.value.length)):parseText("",e)}parseModifiers.stop=!1,e.unshift(b.tree.pop()),b.tree.push(parseFunc(d,{__parsed:e},[])[0]),parseModifiers(a,b)}}}function lookUp(a,b){if(!a)return!1;if(a.substr(0,jSmart.prototype.left_delimiter.length)==jSmart.prototype.left_delimiter){var c=findTag("",a);if(c)return b.token=c[0],b.value+=c[0],parse(c[0],b.tree),parseModifiers(a.slice(b.value.length),b),!0}for(var d=0;d<tokens.length;++d)if(a.match(tokens[d].re))return b.token=RegExp.lastMatch,b.value+=RegExp.lastMatch,tokens[d].parse(b,a.slice(b.token.length)),!0;return!1}function bundleOp(a,b,c){var d=b[a];if("operator"==d.name&&d.precedence==c&&!d.params.__parsed){if("binary"==d.optype)return d.params.__parsed=[b[a-1],b[a+1]],b.splice(a-1,3,d),!0;if("post-unary"==d.optype)return d.params.__parsed=[b[a-1]],b.splice(a-1,2,d),!0;d.params.__parsed=[b[a+1]],b.splice(a,2,d)}return!1}function composeExpression(a){var b=0;for(b=0;b<a.length;++b)a[b]instanceof Array&&(a[b]=composeExpression(a[b]));for(var c=1;14>c;++c)if(2==c||10==c)for(b=a.length;b>0;--b)b-=bundleOp(b-1,a,c);else for(b=0;b<a.length;++b)b-=bundleOp(b,a,c);return a[0]}function parseExpression(a){for(var b={value:"",tree:[]};lookUp(a.slice(b.value.length),b););return b.tree.length?(b.tree=composeExpression(b.tree),b):!1}function parseParams(a,b,c){var d=a.replace(/\n/g," ").replace(/^\s+|\s+$/g,""),e=[];e.__parsed=[];var a="";if(!d)return e;for(b||(b=/^\s+/,c=/^(\w+)\s*=\s*/);d;){var f=null;if(c){var g=d.match(c);g&&(f=trimQuotes(g[1]),a+=d.slice(0,g[0].length),d=d.slice(g[0].length))}var h=parseExpression(d);if(!h)break;f?(e[f]=h.value,e.__parsed[f]=h.tree):(e.push(h.value),e.__parsed.push(h.tree)),a+=d.slice(0,h.value.length),d=d.slice(h.value.length);var i=d.match(b);if(!i)break;a+=d.slice(0,i[0].length),d=d.slice(i[0].length)}return e.toString=function(){return a},e}function parsePluginBlock(a,b,c,d){c.push({type:"plugin",name:a,params:b,subTree:parse(d,[])})}function parsePluginFunc(a,b,c){c.push({type:"plugin",name:a,params:b})}function getActualParamValues(a,b){var c=[];for(var d in a.__parsed)if(a.__parsed.hasOwnProperty(d)){var e=process([a.__parsed[d]],b);c[d]=e}return c.__get=function(a,b,d){if(a in c&&"undefined"!=typeof c[a])return c[a];if("undefined"!=typeof d&&"undefined"!=typeof c[d])return c[d];if(null===b)throw new Error("The required attribute '"+a+"' is missing");return b},c}function isEmptyObject(a){for(var b in a)if(a.hasOwnProperty(b))return!1;return!0}function getVarValue(a,b,c){for(var d=b,e="",f=0;f<a.parts.length;++f){var g=a.parts[f];if("plugin"==g.type&&"__func"==g.name&&g.hasOwner)b.__owner=d,d=process([a.parts[f]],b),delete b.__owner;else if(e=process([g],b),e in b.smarty.section&&"text"==g.type&&"smarty"!=process([a.parts[0]],b)&&(e=b.smarty.section[e].index),!e&&"undefined"!=typeof c&&d instanceof Array&&(e=d.length),"undefined"!=typeof c&&f==a.parts.length-1&&(d[e]=c),"object"==typeof d&&null!==d&&e in d)d=d[e];else{if("undefined"==typeof c)return c;d[e]={},d=d[e]}}return d}function process(a,b){for(var c="",d=0;d<a.length;++d){var e="",f=a[d];if("text"==f.type)e=f.data;else if("var"==f.type)e=getVarValue(f,b);else if("build-in"==f.type)e=buildInFunctions[f.name].process(f,b);else if("plugin"==f.type){var g=plugins[f.name];if("block"==g.type){var h={value:!0};for(g.process(getActualParamValues(f.params,b),"",b,h);h.value;)h.value=!1,e+=g.process(getActualParamValues(f.params,b),process(f.subTree,b),b,h)}else"function"==g.type&&(e=g.process(getActualParamValues(f.params,b),b))}if("boolean"==typeof e&&(e=e?"1":""),1==a.length)return e;if(c+=e,b.smarty["continue"]||b.smarty["break"])return c}return c}function getTemplate(a,b,c){if(!c&&a in files)b=files[a];else{var d=jSmart.prototype.getTemplate(a);if("string"!=typeof d)throw new Error("No template for "+a);parse(applyFilters(jSmart.prototype.filters_global.pre,stripComments(d.replace(/\r\n/g,"\n"))),b),files[a]=b}return b}function stripComments(a){for(var b="",c=a.match(/{\*/);c;c=a.match(/{\*/)){b+=a.slice(0,c.index),a=a.slice(c.index+c[0].length);var d=a.match(/\*}/);if(!d)throw new Error("Unclosed {*");a=a.slice(d.index+d[0].length)}return b+a}function applyFilters(a,b){for(var c=0;c<a.length;++c)b=a[c](b);return b}var buildInFunctions={expression:{parse:function(a,b){var c=parseExpression(a);return b.push({type:"build-in",name:"expression",expression:c.tree,params:parseParams(a.slice(c.value.length).replace(/^\s+|\s+$/g,""))}),c.tree},process:function(a,b){var c=getActualParamValues(a.params,b),d=process([a.expression],b);if(findInArray(c,"nofilter")<0){for(var e=0;e<default_modifiers.length;++e){var f=default_modifiers[e];f.params.__parsed[0]={type:"text",data:d},d=process([f],b)}escape_html&&(d=modifiers.escape(d)),d=applyFilters(varFilters,d),tpl_modifiers.length&&(__t=function(){return d},d=process(tpl_modifiers,b))}return d}},operator:{process:function(a,b){var c=getActualParamValues(a.params,b),d=c[0];if("binary"!=a.optype){if("!"==a.op)return!d;var e="var"==a.params.__parsed[0].type;e&&(d=getVarValue(a.params.__parsed[0],b));var f=d;if("pre-unary"==a.optype){switch(a.op){case"-":f=-d;break;case"++":f=++d;break;case"--":f=--d}e&&getVarValue(a.params.__parsed[0],b,d)}else{switch(a.op){case"++":d++;break;case"--":d--}getVarValue(a.params.__parsed[0],b,d)}return f}var g=c[1];if("="==a.op)return getVarValue(a.params.__parsed[0],b,g),"";if(a.op.match(/(\+=|-=|\*=|\/=|%=)/)){switch(d=getVarValue(a.params.__parsed[0],b),a.op){case"+=":d+=g;break;case"-=":d-=g;break;case"*=":d*=g;break;case"/=":d/=g;break;case"%=":d%=g}return getVarValue(a.params.__parsed[0],b,d)}if(a.op.match(/div/))return"div"!=a.op^d%g==0;if(a.op.match(/even/))return"even"!=a.op^d/g%2==0;if(a.op.match(/xor/))return(d||g)&&!(d&&g);switch(a.op){case"==":return d==g;case"!=":return d!=g;case"+":return Number(d)+Number(g);case"-":return Number(d)-Number(g);case"*":return Number(d)*Number(g);case"/":return Number(d)/Number(g);case"%":return Number(d)%Number(g);case"&&":return d&&g;case"||":return d||g;case"<":return g>d;case"<=":return g>=d;case">":return d>g;case">=":return d>=g;case"===":return d===g;case"!==":return d!==g}}},section:{type:"block",parse:function(a,b,c){var d=[],e=[];b.push({type:"build-in",name:"section",params:a,subTree:d,subTreeElse:e});var f=findElseTag("section [^}]+","/section","sectionelse",c);f?(parse(c.slice(0,f.index),d),parse(c.slice(f.index+f[0].length).replace(/^[\r\n]/,""),e)):parse(c,d)},process:function(a,b){var c=getActualParamValues(a.params,b),d={};b.smarty.section[c.__get("name",null,0)]=d;var e=c.__get("show",!0);if(d.show=e,!e)return process(a.subTreeElse,b);var f=parseInt(c.__get("start",0)),g=c.loop instanceof Object?countProperties(c.loop):isNaN(c.loop)?0:parseInt(c.loop),h=parseInt(c.__get("step",1)),i=parseInt(c.__get("max"));isNaN(i)&&(i=Number.MAX_VALUE),0>f?(f+=g,0>f&&(f=0)):f>=g&&(f=g?g-1:0);for(var j=0,k=0,l=f;l>=0&&g>l&&i>j;l+=h,++j)k=l;d.total=j,d.loop=j,j=0;var m="";for(l=f;l>=0&&g>l&&i>j&&!b.smarty["break"];l+=h,++j)d.first=l==f,d.last=0>l+h||l+h>=g,d.index=l,d.index_prev=l-h,d.index_next=l+h,d.iteration=d.rownum=j+1,m+=process(a.subTree,b),b.smarty["continue"]=!1;return b.smarty["break"]=!1,j?m:process(a.subTreeElse,b)}},setfilter:{type:"block",parseParams:function(a){return[parseExpression("__t()|"+a).tree]},parse:function(a,b,c){b.push({type:"build-in",name:"setfilter",params:a,subTree:parse(c,[])})},process:function(a,b){tpl_modifiers=a.params;var c=process(a.subTree,b);return tpl_modifiers=[],c}},"for":{type:"block",parseParams:function(a){var b=a.match(/^\s*\$(\w+)\s*=\s*([^\s]+)\s*to\s*([^\s]+)\s*(?:step\s*([^\s]+))?\s*(.*)$/);if(!b)throw new Error("Invalid {for} parameters: "+a);return parseParams("varName='"+b[1]+"' from="+b[2]+" to="+b[3]+" step="+(b[4]?b[4]:"1")+" "+b[5])},parse:function(a,b,c){var d=[],e=[];b.push({type:"build-in",name:"for",params:a,subTree:d,subTreeElse:e});var f=findElseTag("for\\s[^}]+","/for","forelse",c);f?(parse(c.slice(0,f.index),d),parse(c.slice(f.index+f[0].length),e)):parse(c,d)},process:function(a,b){var c=getActualParamValues(a.params,b),d=parseInt(c.__get("from")),e=parseInt(c.__get("to")),f=parseInt(c.__get("step"));isNaN(f)&&(f=1);var g=parseInt(c.__get("max"));isNaN(g)&&(g=Number.MAX_VALUE);for(var h=0,i="",j=Math.min(Math.ceil(((f>0?e-d:d-e)+1)/Math.abs(f)),g),k=parseInt(c.from);j>h&&!b.smarty["break"];k+=f,++h)b[c.varName]=k,i+=process(a.subTree,b),b.smarty["continue"]=!1;return b.smarty["break"]=!1,h||(i=process(a.subTreeElse,b)),i}},"if":{type:"block",parse:function(a,b,c){var d=[],e=[];b.push({type:"build-in",name:"if",params:a,subTreeIf:d,subTreeElse:e});var f=findElseTag("if\\s+[^}]+","/if","else[^}]*",c);if(f){parse(c.slice(0,f.index),d),c=c.slice(f.index+f[0].length);var g=f[1].match(/^else\s*if(.*)/);g?buildInFunctions["if"].parse(parseParams(g[1]),e,c.replace(/^\n/,"")):parse(c.replace(/^\n/,""),e)}else parse(c,d)},process:function(a,b){var c=getActualParamValues(a.params,b)[0];return c&&!(c instanceof Array&&0==c.length||"object"==typeof c&&isEmptyObject(c))?process(a.subTreeIf,b):process(a.subTreeElse,b)}},foreach:{type:"block",parseParams:function(a){var b=a.match(/^\s*([$].+)\s*as\s*[$](\w+)\s*(=>\s*[$](\w+))?\s*$/i);return b&&(a="from="+b[1]+" item="+(b[4]||b[2]),b[4]&&(a+=" key="+b[2])),parseParams(a)},parse:function(a,b,c){var d=[],e=[];b.push({type:"build-in",name:"foreach",params:a,subTree:d,subTreeElse:e});var f=findElseTag("foreach\\s[^}]+","/foreach","foreachelse",c);f?(parse(c.slice(0,f.index),d),parse(c.slice(f.index+f[0].length).replace(/^[\r\n]/,""),e)):parse(c,d)},process:function(a,b){var c=getActualParamValues(a.params,b),d=c.from;d instanceof Object||(d=[d]);var e=countProperties(d);b[c.item+"__total"]=e,"name"in c&&(b.smarty.foreach[c.name]={},b.smarty.foreach[c.name].total=e);var f="",g=0;for(var h in d)if(d.hasOwnProperty(h)){if(b.smarty["break"])break;b[c.item+"__key"]=isNaN(h)?h:parseInt(h),"key"in c&&(b[c.key]=b[c.item+"__key"]),b[c.item]=d[h],b[c.item+"__index"]=parseInt(g),b[c.item+"__iteration"]=parseInt(g+1),b[c.item+"__first"]=0===g,b[c.item+"__last"]=g==e-1,"name"in c&&(b.smarty.foreach[c.name].index=parseInt(g),b.smarty.foreach[c.name].iteration=parseInt(g+1),b.smarty.foreach[c.name].first=0===g?1:"",b.smarty.foreach[c.name].last=g==e-1?1:""),++g,f+=process(a.subTree,b),b.smarty["continue"]=!1}return b.smarty["break"]=!1,b[c.item+"__show"]=g>0,c.name&&(b.smarty.foreach[c.name].show=g>0?1:""),g>0?f:process(a.subTreeElse,b)}},"function":{type:"block",parse:function(a,b,c){var d=[];plugins[trimQuotes(a.name?a.name:a[0])]={type:"function",subTree:d,defautParams:a,process:function(a,b){var c=getActualParamValues(this.defautParams,b);return delete c.name,process(this.subTree,obMerge({},b,c,a))}},parse(c,d)}},php:{type:"block",parse:function(){}},"extends":{type:"function",parse:function(a,b){b.splice(0,b.length),getTemplate(trimQuotes(a.file?a.file:a[0]),b)}},block:{type:"block",parse:function(a,b,c){b.push({type:"build-in",name:"block",params:a}),a.append=findInArray(a,"append")>=0,a.prepend=findInArray(a,"prepend")>=0,a.hide=findInArray(a,"hide")>=0,a.hasChild=a.hasParent=!1,onParseVar=function(b){b.match(/^\s*[$]smarty.block.child\s*$/)&&(a.hasChild=!0),b.match(/^\s*[$]smarty.block.parent\s*$/)&&(a.hasParent=!0)};var b=parse(c,[]);onParseVar=function(){};var d=trimQuotes(a.name?a.name:a[0]);d in blocks||(blocks[d]=[]),blocks[d].push({tree:b,params:a})},process:function(a,b){b.smarty.block.parent=b.smarty.block.child="";var c=trimQuotes(a.params.name?a.params.name:a.params[0]);return this.processBlocks(blocks[c],blocks[c].length-1,b),b.smarty.block.child},processBlocks:function(a,b,c){if(!b&&a[b].params.hide)return void(c.smarty.block.child="");for(var d=!0,e=!1;b>=0;--b){if(a[b].params.hasParent){var f=c.smarty.block.child;c.smarty.block.child="",this.processBlocks(a,b-1,c),c.smarty.block.parent=c.smarty.block.child,c.smarty.block.child=f}var f=c.smarty.block.child,g=process(a[b].tree,c);c.smarty.block.child=f,a[b].params.hasChild?c.smarty.block.child=g:d?c.smarty.block.child=g+c.smarty.block.child:e&&(c.smarty.block.child+=g),d=a[b].params.append,e=a[b].params.prepend}}},strip:{type:"block",parse:function(a,b,c){parse(c.replace(/[ \t]*[\r\n]+[ \t]*/g,""),b)}},literal:{type:"block",parse:function(a,b,c){parseText(c,b)}},ldelim:{type:"function",parse:function(a,b){parseText(jSmart.prototype.left_delimiter,b)}},rdelim:{type:"function",parse:function(a,b){parseText(jSmart.prototype.right_delimiter,b)}},"while":{type:"block",parse:function(a,b,c){b.push({type:"build-in",name:"while",params:a,subTree:parse(c,[])})},process:function(a,b){for(var c="";getActualParamValues(a.params,b)[0]&&!b.smarty["break"];)c+=process(a.subTree,b),b.smarty["continue"]=!1;return b.smarty["break"]=!1,c}}},plugins={},modifiers={},files={},blocks=null,scripts=null,tpl_modifiers=[],tokens=[{re:/^\$([\w@]+)/,parse:function(a,b){parseModifiers(parseVar(b,a,RegExp.$1),a)}},{re:/^(true|false)/i,parse:function(a){parseText(a.token.match(/true/i)?"1":"",a.tree)}},{re:/^'([^'\\]*(?:\\.[^'\\]*)*)'/,parse:function(a,b){parseText(evalString(RegExp.$1),a.tree),parseModifiers(b,a)}},{re:/^"([^"\\]*(?:\\.[^"\\]*)*)"/,parse:function(a,b){var c=evalString(RegExp.$1),d=c.match(tokens[0].re);if(d){var e={token:d[0],tree:[]};if(parseVar(c,e,d[1]),e.token.length==c.length)return void a.tree.push(e.tree[0])}parseText.parseEmbeddedVars=!0,a.tree.push({type:"plugin",name:"__quoted",params:{__parsed:parse(c,[])}}),parseText.parseEmbeddedVars=!1,parseModifiers(b,a)}},{re:/^(\w+)\s*[(]([)]?)/,parse:function(a,b){var c=RegExp.$1,d=RegExp.$2,e=parseParams(d?"":b,/^\s*,\s*/);parseFunc(c,e,a.tree),a.value+=e.toString(),parseModifiers(b.slice(e.toString().length),a)}},{re:/^\s*\(\s*/,parse:function(a){var b=[];a.tree.push(b),b.parent=a.tree,a.tree=b}},{re:/^\s*\)\s*/,parse:function(a){a.tree.parent&&(a.tree=a.tree.parent)}},{re:/^\s*(\+\+|--)\s*/,parse:function(a){a.tree.length&&"var"==a.tree[a.tree.length-1].type?parseOperator(RegExp.$1,"post-unary",1,a.tree):parseOperator(RegExp.$1,"pre-unary",1,a.tree)}},{re:/^\s*(===|!==|==|!=)\s*/,parse:function(a){parseOperator(RegExp.$1,"binary",6,a.tree)}},{re:/^\s+(eq|ne|neq)\s+/i,parse:function(a){var b=RegExp.$1.replace(/ne(q)?/,"!=").replace(/eq/,"==");parseOperator(b,"binary",6,a.tree)}},{re:/^\s*!\s*/,parse:function(a){parseOperator("!","pre-unary",2,a.tree)}},{re:/^\s+not\s+/i,parse:function(a){parseOperator("!","pre-unary",2,a.tree)}},{re:/^\s*(=|\+=|-=|\*=|\/=|%=)\s*/,parse:function(a){parseOperator(RegExp.$1,"binary",10,a.tree)}},{re:/^\s*(\*|\/|%)\s*/,parse:function(a){parseOperator(RegExp.$1,"binary",3,a.tree)}},{re:/^\s+mod\s+/i,parse:function(a){parseOperator("%","binary",3,a.tree)}},{re:/^\s*(\+|-)\s*/,parse:function(a){a.tree.length&&"operator"!=a.tree[a.tree.length-1].name?parseOperator(RegExp.$1,"binary",4,a.tree):parseOperator(RegExp.$1,"pre-unary",4,a.tree)}},{re:/^\s*(<=|>=|<>|<|>)\s*/,parse:function(a){parseOperator(RegExp.$1.replace(/<>/,"!="),"binary",5,a.tree)}},{re:/^\s+(lt|lte|le|gt|gte|ge)\s+/i,parse:function(a){var b=RegExp.$1.replace(/lt/,"<").replace(/l(t)?e/,"<=").replace(/gt/,">").replace(/g(t)?e/,">=");parseOperator(b,"binary",5,a.tree)}},{re:/^\s+(is\s+(not\s+)?div\s+by)\s+/i,parse:function(a){parseOperator(RegExp.$2?"div_not":"div","binary",7,a.tree)}},{re:/^\s+is\s+(not\s+)?(even|odd)(\s+by\s+)?\s*/i,parse:function(a){var b=RegExp.$1?"odd"==RegExp.$2?"even":"even_not":"odd"==RegExp.$2?"even_not":"even";parseOperator(b,"binary",7,a.tree),RegExp.$3||parseText("1",a.tree)}},{re:/^\s*(&&)\s*/,parse:function(a){parseOperator(RegExp.$1,"binary",8,a.tree)}},{re:/^\s*(\|\|)\s*/,parse:function(a){parseOperator(RegExp.$1,"binary",9,a.tree)}},{re:/^\s+and\s+/i,parse:function(a){parseOperator("&&","binary",11,a.tree)}},{re:/^\s+xor\s+/i,parse:function(a){parseOperator("xor","binary",12,a.tree)}},{re:/^\s+or\s+/i,parse:function(a){parseOperator("||","binary",13,a.tree)}},{re:/^#(\w+)#/,parse:function(a,b){var c={token:"$smarty",tree:[]};parseVar(".config."+RegExp.$1,c,"smarty"),a.tree.push(c.tree[0]),parseModifiers(b,a)}},{re:/^\s*\[\s*/,parse:function(a,b){var c=parseParams(b,/^\s*,\s*/,/^('[^'\\]*(?:\\.[^'\\]*)*'|"[^"\\]*(?:\\.[^"\\]*)*"|\w+)\s*=>\s*/);parsePluginFunc("__array",c,a.tree),a.value+=c.toString();var d=b.slice(c.toString().length).match(/\s*\]/);d&&(a.value+=d[0])}},{re:/^[\d.]+/,parse:function(a,b){a.token=a.token.indexOf(".")>-1?parseFloat(a.token):parseInt(a.token,10),parseText(a.token,a.tree),parseModifiers(b,a)}},{re:/^\w+/,parse:function(a,b){parseText(a.token,a.tree),parseModifiers(b,a)}}];jSmart=function(a){this.tree=[],this.tree.blocks={},this.scripts={},this.default_modifiers=[],this.filters={variable:[],post:[]},this.smarty={smarty:{block:{},"break":!1,capture:{},"continue":!1,counter:{},cycle:{},foreach:{},section:{},now:Math.floor((new Date).getTime()/1e3),"const":{},config:{},current_dir:"/",template:"",ldelim:jSmart.prototype.left_delimiter,rdelim:jSmart.prototype.right_delimiter,version:"2.15.0"}},blocks=this.tree.blocks,parse(applyFilters(jSmart.prototype.filters_global.pre,stripComments(new String(a?a:"").replace(/\r\n/g,"\n"))),this.tree)},jSmart.prototype.fetch=function(a){blocks=this.tree.blocks,scripts=this.scripts,escape_html=this.escape_html,default_modifiers=jSmart.prototype.default_modifiers_global.concat(this.default_modifiers),this.data=obMerge("object"==typeof a?a:{},this.smarty),varFilters=jSmart.prototype.filters_global.variable.concat(this.filters.variable);var b=process(this.tree,this.data);return jSmart.prototype.debugging&&plugins.debug.process([],this.data),applyFilters(jSmart.prototype.filters_global.post.concat(this.filters.post),b)},jSmart.prototype.escape_html=!1,jSmart.prototype.registerPlugin=function(a,b,c){"modifier"==a?modifiers[b]=c:plugins[b]={type:a,process:c}},jSmart.prototype.registerFilter=function(a,b){(this.tree?this.filters:jSmart.prototype.filters_global)["output"==a?"post":a].push(b)},jSmart.prototype.filters_global={pre:[],variable:[],post:[]},jSmart.prototype.configLoad=function(a,b,c){c=c?c:this.data;for(var d=a.replace(/\r\n/g,"\n").replace(/^\s+|\s+$/g,""),e=/^\s*(?:\[([^\]]+)\]|(?:(\w+)[ \t]*=[ \t]*("""|'[^'\\\n]*(?:\\.[^'\\\n]*)*'|"[^"\\\n]*(?:\\.[^"\\\n]*)*"|[^\n]*)))/m,f="",g=d.match(e);g;g=d.match(e)){if(d=d.slice(g.index+g[0].length),g[1])f=g[1];else if((!f||f==b)&&"."!=f.substr(0,1))if('"""'==g[3]){var h=d.match(/"""/);h&&(c.smarty.config[g[2]]=d.slice(0,h.index),d=d.slice(h.index+h[0].length))}else c.smarty.config[g[2]]=trimQuotes(g[3]);var i=d.match(/\n+/);if(!i)break;d=d.slice(i.index+i[0].length)}},jSmart.prototype.clearConfig=function(a){a?delete this.data.smarty.config[a]:this.data.smarty.config={}},jSmart.prototype.addDefaultModifier=function(a){a instanceof Array||(a=[a]);for(var b=0;b<a.length;++b){var c={value:"",tree:[0]};parseModifiers("|"+a[b],c),(this.tree?this.default_modifiers:this.default_modifiers_global).push(c.tree[0])}},jSmart.prototype.default_modifiers_global=[],jSmart.prototype.getTemplate=function(a){throw new Error("No template for "+a)},jSmart.prototype.getFile=function(a){throw new Error("No file for "+a)},jSmart.prototype.getJavascript=function(a){throw new Error("No Javascript for "+a)},jSmart.prototype.getConfig=function(a){throw new Error("No config for "+a)},jSmart.prototype.auto_literal=!0,jSmart.prototype.left_delimiter="{",jSmart.prototype.right_delimiter="}",jSmart.prototype.debugging=!1,jSmart.prototype.PHPJS=function(fnm,modifier){if("function"==eval("typeof "+fnm))return"object"==typeof window?window:global;if("function"==typeof PHP_JS)return new PHP_JS;throw new Error("Modifier '"+modifier+"' uses JavaScript port of PHP function '"+fnm+"'. You can find one at http://phpjs.org")},jSmart.prototype.makeTimeStamp=function(a){if(!a)return Math.floor((new Date).getTime()/1e3);if(isNaN(a)){var b=jSmart.prototype.PHPJS("strtotime","date_format").strtotime(a);return-1==b||b===!1?Math.floor((new Date).getTime()/1e3):b}return a=new String(a),14==a.length?Math.floor(new Date(a.substr(0,4),a.substr(4,2)-1,a.substr(6,2),a.substr(8,2),a.substr(10,2)).getTime()/1e3):parseInt(a)},jSmart.prototype.registerPlugin("function","__array",function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&a[c]&&"function"!=typeof a[c]&&(b[c]=a[c]);return b}),jSmart.prototype.registerPlugin("function","__func",function(a,b){for(var c=[],d={},e=[],f=0;f<a.length;++f)c.push(a.name+"__p"+f),e.push(a[f]),d[a.name+"__p"+f]=a[f];var g,h=obMerge({},b,d);return"__owner"in b&&a.name in b.__owner?(g="__owner."+a.name,execute(g+"("+c.join(",")+")",h)):modifiers.hasOwnProperty(a.name)?(g=modifiers[a.name],executeByFuncObject(g,e,h)):(g=a.name,execute(g+"("+c.join(",")+")",h))}),jSmart.prototype.registerPlugin("function","__quoted",function(a){return a.join("")}),jSmart.prototype.registerPlugin("function","append",function(a,b){var c=a.__get("var",null,0);c in b&&b[c]instanceof Array||(b[c]=[]);var d=a.__get("index",!1),e=a.__get("value",null,1);return d===!1?b[c].push(e):b[c][d]=e,""}),jSmart.prototype.registerPlugin("function","assign",function(a,b){return assignVar(a.__get("var",null,0),a.__get("value",null,1),b),""}),jSmart.prototype.registerPlugin("function","break",function(a,b){return b.smarty["break"]=!0,""}),jSmart.prototype.registerPlugin("function","call",function(a,b){var c=a.__get("name",null,0);delete a.name;var d=a.__get("assign",!1);delete a.assign;var e=plugins[c].process(a,b);return d?(assignVar(d,e,b),""):e}),jSmart.prototype.registerPlugin("block","capture",function(a,b,c){if(b){b=b.replace(/^\n/,""),c.smarty.capture[a.__get("name","default",0)]=b,"assign"in a&&assignVar(a.assign,b,c);var d=a.__get("append",!1);d&&(d in c?c[d]instanceof Array&&c[d].push(b):c[d]=[b])}return""}),jSmart.prototype.registerPlugin("function","continue",function(a,b){return b.smarty["continue"]=!0,""}),jSmart.prototype.registerPlugin("function","counter",function(a,b){var c=a.__get("name","default");if(c in b.smarty.counter){var d=b.smarty.counter[c];"start"in a?d.value=parseInt(a.start):(d.value=parseInt(d.value),d.skip=parseInt(d.skip),"down"==d.direction?d.value-=d.skip:d.value+=d.skip),d.skip=a.__get("skip",d.skip),d.direction=a.__get("direction",d.direction),d.assign=a.__get("assign",d.assign)}else b.smarty.counter[c]={value:parseInt(a.__get("start",1)),skip:parseInt(a.__get("skip",1)),direction:a.__get("direction","up"),assign:a.__get("assign",!1)};return b.smarty.counter[c].assign?(b[b.smarty.counter[c].assign]=b.smarty.counter[c].value,""):a.__get("print",!0)?b.smarty.counter[c].value:""}),jSmart.prototype.registerPlugin("function","cycle",function(a,b){var c=a.__get("name","default"),d=a.__get("reset",!1);c in b.smarty.cycle||(b.smarty.cycle[c]={arr:[""],delimiter:a.__get("delimiter",","),index:0},d=!0),a.__get("delimiter",!1)&&(b.smarty.cycle[c].delimiter=a.delimiter);var e=a.__get("values",!1);if(e){var f=[];if(e instanceof Object)for(nm in e)f.push(e[nm]);else f=e.split(b.smarty.cycle[c].delimiter);(f.length!=b.smarty.cycle[c].arr.length||f[0]!=b.smarty.cycle[c].arr[0])&&(b.smarty.cycle[c].arr=f,b.smarty.cycle[c].index=0,d=!0)}return a.__get("advance","true")&&(b.smarty.cycle[c].index+=1),(b.smarty.cycle[c].index>=b.smarty.cycle[c].arr.length||d)&&(b.smarty.cycle[c].index=0),a.__get("assign",!1)?(assignVar(a.assign,b.smarty.cycle[c].arr[b.smarty.cycle[c].index],b),""):a.__get("print",!0)?b.smarty.cycle[c].arr[b.smarty.cycle[c].index]:""}),jSmart.prototype.print_r=function(a,b){if(a instanceof Object){var c=(a instanceof Array?"Array["+a.length+"]":"Object")+"<br>";for(var d in a)a.hasOwnProperty(d)&&(c+=b+"&nbsp;&nbsp;<strong>"+d+"</strong> : "+jSmart.prototype.print_r(a[d],b+"&nbsp;&nbsp;&nbsp;")+"<br>");return c}return a},jSmart.prototype.registerPlugin("function","debug",function(a,b){"undefined"!=typeof dbgWnd&&dbgWnd.close(),dbgWnd=window.open("","","width=680,height=600,resizable,scrollbars=yes");var c="",d=0;for(var e in b)c+="<tr class="+(++d%2?"odd":"even")+"><td><strong>"+e+"</strong></td><td>"+jSmart.prototype.print_r(b[e],"")+"</td></tr>";return dbgWnd.document.write("                <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en'>                <head>                       <title>jSmart Debug Console</title>                   <style type='text/css'>                      table {width: 100%;}                      td {vertical-align:top;width: 50%;}                      .even td {background-color: #fafafa;}                   </style>                </head>                <body>                   <h1>jSmart Debug Console</h1>                   <h2>assigned template variables</h2>                   <table>"+c+"</table>                </body>                </html>             "),""}),jSmart.prototype.registerPlugin("function","eval",function(a,b){var c=[];parse(a.__get("var","",0),c);var d=process(c,b);return"assign"in a?(assignVar(a.assign,d,b),""):d}),jSmart.prototype.registerPlugin("function","fetch",function(a,b){var c=jSmart.prototype.getFile(a.__get("file",null,0));return"assign"in a?(assignVar(a.assign,c,b),""):c}),jSmart.prototype.registerPlugin("function","html_checkboxes",function(a,b){var c,d,e,f=a.__get("type","checkbox"),g=a.__get("name",f),h=a.__get("name",f),i=a.__get("values",a.options),j=a.__get("options",[]),k="options"in a,l=a.__get("selected",!1),m=a.__get("separator",""),n=Boolean(a.__get("labels",!0)),o=Boolean(a.__get("label_ids",!1)),p=[],q=0,r="";if("checkbox"==f&&(g+="[]"),!k)for(c in a.output)j.push(a.output[c]);for(c in i)i.hasOwnProperty(c)&&(d=k?c:i[c],e=h+"_"+d,r=n?o?'<label for="'+e+'">':"<label>":"",r+='<input type="'+f+'" name="'+g+'" value="'+d+'" ',o&&(r+='id="'+e+'" '),l==(k?c:i[c])&&(r+='checked="checked" '),r+="/>"+j[k?c:q++],r+=n?"</label>":"",r+=m,p.push(r));return"assign"in a?(assignVar(a.assign,p,b),""):p.join("\n")}),jSmart.prototype.registerPlugin("function","html_image",function(a){var b,c=a.__get("file",null),d=a.__get("width",!1),e=a.__get("height",!1),f=a.__get("alt",""),g=a.__get("href",a.__get("link",!1)),h=a.__get("path_prefix",""),i={file:1,width:1,height:1,alt:1,href:1,basedir:1,path_prefix:1,link:1},j='<img src="'+h+c+'" alt="'+f+'"'+(d?' width="'+d+'"':"")+(e?' height="'+e+'"':"");for(b in a)a.hasOwnProperty(b)&&"string"==typeof a[b]&&(b in i||(j+=" "+b+'="'+a[b]+'"'));return j+=" />",g?'<a href="'+g+'">'+j+"</a>":j}),jSmart.prototype.registerPlugin("function","html_options",function(a){var b,c=a.__get("values",a.options),d=a.__get("options",[]),e="options"in a;if(!e)for(b in a.output)d.push(a.output[b]);var f=a.__get("selected",!1),g=[],h="",i=0;for(b in c)c.hasOwnProperty(b)&&(h='<option value="'+(e?b:c[b])+'"',f==(e?b:c[b])&&(h+=' selected="selected"'),h+=">"+d[e?b:i++]+"</option>",g.push(h));var j=a.__get("name",!1);return(j?'<select name="'+j+'">\n'+g.join("\n")+"\n</select>":g.join("\n"))+"\n"}),jSmart.prototype.registerPlugin("function","html_radios",function(a,b){return a.type="radio",plugins.html_checkboxes.process(a,b)}),jSmart.prototype.registerPlugin("function","html_select_date",function(a){var b=a.__get("prefix","Date_"),c=["January","February","March","April","May","June","July","August","September","October","November","December"],d="";d+='<select name="'+b+'Month">\n';
-var e=0;for(e=0;e<c.length;++e)d+='<option value="'+e+'">'+c[e]+"</option>\n";for(d+="</select>\n",d+='<select name="'+b+'Day">\n',e=0;31>e;++e)d+='<option value="'+e+'">'+e+"</option>\n";return d+="</select>\n"}),jSmart.prototype.registerPlugin("function","html_table",function(a){var b,c=[];if(a.loop instanceof Array)c=a.loop;else for(b in a.loop)a.loop.hasOwnProperty(b)&&c.push(a.loop[b]);var d=a.__get("rows",!1),e=a.__get("cols",!1);e||(e=d?Math.ceil(c.length/d):3);var f=[];if(isNaN(e)){if("object"==typeof e)for(b in e)e.hasOwnProperty(b)&&f.push(e[b]);else f=e.split(/\s*,\s*/);e=f.length}d=d?d:Math.ceil(c.length/e);var g=a.__get("inner","cols"),h=a.__get("caption",""),i=a.__get("table_attr",'border="1"'),j=a.__get("th_attr",!1);j&&"object"!=typeof j&&(j=[j]);var k=a.__get("tr_attr",!1);k&&"object"!=typeof k&&(k=[k]);var l=a.__get("td_attr",!1);l&&"object"!=typeof l&&(l=[l]);for(var m=a.__get("trailpad","&nbsp;"),n=a.__get("hdir","right"),o=a.__get("vdir","down"),p="",q=0;d>q;++q){p+="<tr"+(k?" "+k[q%k.length]:"")+">\n";for(var r=0;e>r;++r){var s="cols"==g?("down"==o?q:d-1-q)*e+("right"==n?r:e-1-r):("right"==n?r:e-1-r)*d+("down"==o?q:d-1-q);p+="<td"+(l?" "+l[r%l.length]:"")+">"+(s<c.length?c[s]:m)+"</td>\n"}p+="</tr>\n"}var t="";if(f.length){t="\n<thead><tr>";for(var u=0;u<f.length;++u)t+="\n<th"+(j?" "+j[u%j.length]:"")+">"+f["right"==n?u:f.length-1-u]+"</th>";t+="\n</tr></thead>"}return"<table "+i+">"+(h?"\n<caption>"+h+"</caption>":"")+t+"\n<tbody>\n"+p+"</tbody>\n</table>\n"}),jSmart.prototype.registerPlugin("function","include",function(a,b){var c=a.__get("file",null,0),d=obMerge({},b,a);d.smarty.template=c;var e=process(getTemplate(c,[],findInArray(a,"nocache")>=0),d);return"assign"in a?(assignVar(a.assign,e,b),""):e}),jSmart.prototype.registerPlugin("function","include_javascript",function(a,b){var c=a.__get("file",null,0);if(a.__get("once",!0)&&c in scripts)return"";scripts[c]=!0;var d=execute(jSmart.prototype.getJavascript(c),{$this:b});return"assign"in a?(assignVar(a.assign,d,b),""):d}),jSmart.prototype.registerPlugin("function","include_php",function(a,b){return plugins.include_javascript.process(a,b)}),jSmart.prototype.registerPlugin("function","insert",function(params,data){var fparams={};for(var nm in params)params.hasOwnProperty(nm)&&isNaN(nm)&&params[nm]&&"string"==typeof params[nm]&&"name"!=nm&&"assign"!=nm&&"script"!=nm&&(fparams[nm]=params[nm]);var prefix="insert_";"script"in params&&(eval(jSmart.prototype.getJavascript(params.script)),prefix="smarty_insert_");var func=eval(prefix+params.__get("name",null,0)),s=func(fparams,data);return"assign"in params?(assignVar(params.assign,s,data),""):s}),jSmart.prototype.registerPlugin("block","javascript",function(a,b,c){return c.$this=c,execute(b,c),delete c.$this,""}),jSmart.prototype.registerPlugin("function","config_load",function(a,b){return jSmart.prototype.configLoad(jSmart.prototype.getConfig(a.__get("file",null,0)),a.__get("section","",1),b),""}),jSmart.prototype.registerPlugin("function","mailto",function(a){var b=a.__get("address",null),c=a.__get("encode","none"),d=a.__get("text",b),e=jSmart.prototype.PHPJS("rawurlencode","mailto").rawurlencode(a.__get("cc","")).replace("%40","@"),f=jSmart.prototype.PHPJS("rawurlencode","mailto").rawurlencode(a.__get("bcc","")).replace("%40","@"),g=jSmart.prototype.PHPJS("rawurlencode","mailto").rawurlencode(a.__get("followupto","")).replace("%40","@"),h=jSmart.prototype.PHPJS("rawurlencode","mailto").rawurlencode(a.__get("subject","")),i=jSmart.prototype.PHPJS("rawurlencode","mailto").rawurlencode(a.__get("newsgroups","")),j=a.__get("extra","");if(b+=e?"?cc="+e:"",b+=f?(e?"&":"?")+"bcc="+f:"",b+=h?(e||f?"&":"?")+"subject="+h:"",b+=i?(e||f||h?"&":"?")+"newsgroups="+i:"",b+=g?(e||f||h||i?"&":"?")+"followupto="+g:"",s='<a href="mailto:'+b+'" '+j+">"+d+"</a>","javascript"==c){s="document.write('"+s+"');";for(var k="",l=0;l<s.length;++l)k+="%"+jSmart.prototype.PHPJS("bin2hex","mailto").bin2hex(s.substr(l,1));return'<script type="text/javascript">eval(unescape(\''+k+"'))</script>"}if("javascript_charcode"==c){for(var m=[],l=0;l<s.length;++l)m.push(jSmart.prototype.PHPJS("ord","mailto").ord(s.substr(l,1)));return'<script type="text/javascript" language="javascript">\n<!--\n{document.write(String.fromCharCode('+m.join(",")+"))}\n//-->\n</script>\n"}if("hex"==c){if(b.match(/^.+\?.+$/))throw new Error("mailto: hex encoding does not work with extra attributes. Try javascript.");for(var n="",l=0;l<b.length;++l)n+=b.substr(l,1).match(/\w/)?"%"+jSmart.prototype.PHPJS("bin2hex","mailto").bin2hex(b.substr(l,1)):b.substr(l,1);for(var o="",l=0;l<d.length;++l)o+="&#x"+jSmart.prototype.PHPJS("bin2hex","mailto").bin2hex(d.substr(l,1))+";";return'<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;'+n+'" '+j+">"+o+"</a>"}return s}),jSmart.prototype.registerPlugin("function","math",function(params,data){with(Math)with(params)var res=eval(params.__get("equation",null).replace(/pi\(\s*\)/g,"PI"));return"format"in params&&(res=jSmart.prototype.PHPJS("sprintf","math").sprintf(params.format,res)),"assign"in params?(assignVar(params.assign,res,data),""):res}),jSmart.prototype.registerPlugin("block","nocache",function(a,b){return b}),jSmart.prototype.registerPlugin("block","textformat",function(a,b,c){if(!b)return"";var d=a.__get("wrap",80),e=a.__get("wrap_char","\n"),f=a.__get("wrap_cut",!1),g=a.__get("indent_char"," "),h=a.__get("indent",0),i=new Array(h+1).join(g),j=a.__get("indent_first",0),k=new Array(j+1).join(g),l=a.__get("style","");"email"==l&&(d=72);for(var m=b.split(/[\r\n]{2}/),n=0;n<m.length;++n){var o=m[n];o&&(o=o.replace(/^\s+|\s+$/,"").replace(/\s+/g," "),j>0&&(o=k+o),o=modifiers.wordwrap(o,d-h,e,f),h>0&&(o=o.replace(/^/gm,i)),m[n]=o)}var p=m.join(e+e);return"assign"in a?(assignVar(a.assign,p,c),""):p}),jSmart.prototype.registerPlugin("modifier","capitalize",function(a,b,c){var d=new RegExp(b?"[^a-zA-Z_à-ü]+":"[^a-zA-Z0-9_à-ü]"),e=null,f="";for(c&&(a=a.toLowerCase()),e=a.match(d);e;e=a.match(d)){var g=a.slice(0,e.index);f+=g.match(/\d/)?g:g.charAt(0).toUpperCase()+g.slice(1),f+=a.slice(e.index,e.index+e[0].length),a=a.slice(e.index+e[0].length)}return a.match(/\d/)?f+a:f+a.charAt(0).toUpperCase()+a.slice(1)}),jSmart.prototype.registerPlugin("modifier","cat",function(a,b){return b=b?b:"",a+b}),jSmart.prototype.registerPlugin("modifier","count",function(a,b){if(null===a||"undefined"==typeof a)return 0;if(a.constructor!==Array&&a.constructor!==Object)return 1;b=Boolean(b);var c,d=0;for(c in a)a.hasOwnProperty(c)&&(d++,b&&a[c]&&(a[c].constructor===Array||a[c].constructor===Object)&&(d+=modifiers.count(a[c],!0)));return d}),jSmart.prototype.registerPlugin("modifier","count_characters",function(a,b){return b?a.length:a.replace(/\s/g,"").length}),jSmart.prototype.registerPlugin("modifier","count_paragraphs",function(a){var b=a.match(/\n+/g);return b?b.length+1:1}),jSmart.prototype.registerPlugin("modifier","count_sentences",function(a){var b=a.match(/[^\s]\.(?!\w)/g);return b?b.length:0}),jSmart.prototype.registerPlugin("modifier","count_words",function(a){var b=a.match(/\w+/g);return b?b.length:0}),jSmart.prototype.registerPlugin("modifier","date_format",function(a,b,c){return jSmart.prototype.PHPJS("strftime","date_format").strftime(b?b:"%b %e, %Y",jSmart.prototype.makeTimeStamp(a?a:c))}),jSmart.prototype.registerPlugin("modifier","defaultValue",function(a,b){return a&&"null"!=a&&"undefined"!=a?a:b?b:""}),jSmart.prototype.registerPlugin("modifier","unescape",function(a,b,c){switch(a=new String(a),b=b||"html",c=c||"UTF-8",b){case"html":return a.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&#039;/g,"'").replace(/&quot;/g,'"');case"entity":case"htmlall":return jSmart.prototype.PHPJS("html_entity_decode","unescape").html_entity_decode(a,0);case"url":return jSmart.prototype.PHPJS("rawurldecode","unescape").rawurldecode(a)}return a}),jSmart.prototype.registerPlugin("modifier","escape",function(a,b,c,d){switch(a=new String(a),b=b||"html",c=c||"UTF-8",d="undefined"!=typeof d?Boolean(d):!0,b){case"html":return d&&(a=a.replace(/&/g,"&amp;")),a.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#039;").replace(/"/g,"&quot;");case"htmlall":return jSmart.prototype.PHPJS("htmlentities","escape").htmlentities(a,3,c);case"url":return jSmart.prototype.PHPJS("rawurlencode","escape").rawurlencode(a);case"urlpathinfo":return jSmart.prototype.PHPJS("rawurlencode","escape").rawurlencode(a).replace(/%2F/g,"/");case"quotes":return a.replace(/(^|[^\\])'/g,"$1\\'");case"hex":for(var e="",f=0;f<a.length;++f)e+="%"+jSmart.prototype.PHPJS("bin2hex","escape").bin2hex(a.substr(f,1));return e;case"hexentity":for(var e="",f=0;f<a.length;++f)e+="&#x"+jSmart.prototype.PHPJS("bin2hex","escape").bin2hex(a.substr(f,1)).toLowerCase()+";";return e;case"decentity":for(var e="",f=0;f<a.length;++f)e+="&#"+jSmart.prototype.PHPJS("ord","escape").ord(a.substr(f,1))+";";return e;case"mail":return a.replace(/@/g," [AT] ").replace(/[.]/g," [DOT] ");case"nonstd":for(var e="",f=0;f<a.length;++f){var g=jSmart.prototype.PHPJS("ord","escape").ord(a.substr(f,1));e+=g>=126?"&#"+g+";":a.substr(f,1)}return e;case"javascript":return a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(/"/g,'\\"').replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/<\//g,"</")}return a}),jSmart.prototype.registerPlugin("modifier","indent",function(a,b,c){b=b?b:4,c=c?c:" ";for(var d="";b--;)d+=c;var e=a.match(/\n+$/);return d+a.replace(/\n+$/,"").replace(/\n/g,"\n"+d)+(e?e[0]:"")}),jSmart.prototype.registerPlugin("modifier","lower",function(a){return a.toLowerCase()}),jSmart.prototype.registerPlugin("modifier","nl2br",function(a){return a.replace(/\n/g,"<br />\n")}),jSmart.prototype.registerPlugin("modifier","regex_replace",function(a,b,c){var d=b.match(/^ *\/(.*)\/(.*) *$/);return new String(a).replace(new RegExp(d[1],"g"+(d.length>1?d[2]:"")),c)}),jSmart.prototype.registerPlugin("modifier","replace",function(a,b,c){if(!b)return a;a=new String(a),b=new String(b),c=new String(c);var d="",e=-1;for(e=a.indexOf(b);e>=0;e=a.indexOf(b))d+=a.slice(0,e)+c,e+=b.length,a=a.slice(e);return d+a}),jSmart.prototype.registerPlugin("modifier","spacify",function(a,b){return b||(b=" "),a.replace(/(\n|.)(?!$)/g,"$1"+b)}),jSmart.prototype.registerPlugin("modifier","noprint",function(){return""}),jSmart.prototype.registerPlugin("modifier","string_format",function(a,b){return jSmart.prototype.PHPJS("sprintf","string_format").sprintf(b,a)}),jSmart.prototype.registerPlugin("modifier","strip",function(a,b){return b=b?b:" ",new String(a).replace(/[\s]+/g,b)}),jSmart.prototype.registerPlugin("modifier","strip_tags",function(a,b){return b=null==b?!0:b,new String(a).replace(/<[^>]*?>/g,b?" ":"")}),jSmart.prototype.registerPlugin("modifier","truncate",function(a,b,c,d,e){return b=b?b:80,c=null!=c?c:"...",a.length<=b?a:(b-=Math.min(b,c.length),e?a.slice(0,Math.floor(b/2))+c+a.slice(a.length-Math.floor(b/2)):(d||(a=a.slice(0,b+1).replace(/\s+?(\S+)?$/,"")),a.slice(0,b)+c))}),jSmart.prototype.registerPlugin("modifier","upper",function(a){return a.toUpperCase()}),jSmart.prototype.registerPlugin("modifier","wordwrap",function(a,b,c,d){b=b||80,c=c||"\n";for(var e=a.split("\n"),f=0;f<e.length;++f){for(var g=e[f],h="";g.length>b;){for(var i=0,j=g.slice(i).match(/\s+/);j&&i+j.index<=b;j=g.slice(i).match(/\s+/))i+=j.index+j[0].length;i=i||(d?b:j?j.index+j[0].length:g.length),h+=g.slice(0,i).replace(/\s+$/,""),i<g.length&&(h+=c),g=g.slice(i)}e[f]=h+g}return e.join("\n")}),String.prototype.fetch=function(a){var b=new jSmart(this);return b.fetch(a)},"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=jSmart:("undefined"!=typeof global&&(global.jSmart=jSmart),"function"==typeof define&&define.amd&&define("jSmart",[],function(){return jSmart}))}();
\ No newline at end of file
index 287e696cb2a3fc5144c7624a99b57f93970fcfa6..f944c80ae9ad0aaf234371ae2c7d706ad52efe25 100644 (file)
@@ -75,7 +75,6 @@
 <script type="text/javascript" src="view/theme/frio/frameworks/justifiedGallery/jquery.justifiedGallery.min.js"></script>
 <script type="text/javascript" src="view/theme/frio/frameworks/bootstrap-colorpicker/js/bootstrap-colorpicker.min.js"></script>
 <script type="text/javascript" src="view/theme/frio/frameworks/flexMenu/flexmenu.custom.js"></script>
-<script type="text/javascript" src="view/theme/frio/frameworks/jsmart/jsmart.custom.js"></script>
 <script type="text/javascript" src="view/theme/frio/frameworks/jquery-scrollspy/jquery-scrollspy.js"></script>
 <script type="text/javascript" src="view/theme/frio/frameworks/autosize/autosize.min.js"></script>
 <script type="text/javascript" src="view/theme/frio/frameworks/sticky-kit/jquery.sticky-kit.min.js"></script>