{"version":3,"sources":["jsdelivr-header.js","/npm/metaphorjs@0.3.13/dist/metaphorjs.npm.js"],"names":[],"mappings":"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","file":"/npm/metaphorjs@0.3.13/dist/metaphorjs.npm.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.37.0.\n * Original file: /npm/metaphorjs@0.3.13/dist/metaphorjs.npm.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","var Observable = require('metaphorjs-observable');\nvar Promise = require('metaphorjs-promise');\nvar ajax = require('metaphorjs-ajax');\nvar animate = require('metaphorjs-animate');\nvar Input = require('metaphorjs-input');\nvar Class = require('metaphorjs-class');\nvar Namespace = require('metaphorjs-namespace');\nvar model = require('metaphorjs-model');\nvar select = require('metaphorjs-select');\nvar Validator = require('metaphorjs-validator');\nvar Watchable = require('metaphorjs-watchable');\nvar Dialog = require('metaphorjs-dialog');\nvar history = require('metaphorjs-history');\n\nvar MetaphorJs = {\n\n};\n\n\n\n\nvar ns  = new Namespace(MetaphorJs, \"MetaphorJs\");\n\n\n\nvar cs = new Class(ns);\n\n\n\n\n\nvar defineClass = cs.define;\n\n\nfunction emptyFn(){};\n\n\nvar slice = Array.prototype.slice;\n\nfunction getAttr(el, name) {\n    return el.getAttribute ? el.getAttribute(name) : null;\n};\n\nvar toString = Object.prototype.toString;\n\nvar undf = undefined;\n\n\n\n\nvar varType = function(){\n\n    var types = {\n        '[object String]': 0,\n        '[object Number]': 1,\n        '[object Boolean]': 2,\n        '[object Object]': 3,\n        '[object Function]': 4,\n        '[object Array]': 5,\n        '[object RegExp]': 9,\n        '[object Date]': 10\n    };\n\n\n    /**\n        'string': 0,\n        'number': 1,\n        'boolean': 2,\n        'object': 3,\n        'function': 4,\n        'array': 5,\n        'null': 6,\n        'undefined': 7,\n        'NaN': 8,\n        'regexp': 9,\n        'date': 10\n    */\n\n    return function varType(val) {\n\n        if (!val) {\n            if (val === null) {\n                return 6;\n            }\n            if (val === undf) {\n                return 7;\n            }\n        }\n\n        var num = types[toString.call(val)];\n\n        if (num === undf) {\n            return -1;\n        }\n\n        if (num == 1 && isNaN(val)) {\n            return 8;\n        }\n\n        return num;\n    };\n\n}();\n\n\n\nfunction isPlainObject(value) {\n    // IE < 9 returns [object Object] from toString(htmlElement)\n    return typeof value == \"object\" &&\n           varType(value) === 3 &&\n            !value.nodeType &&\n            value.constructor === Object;\n\n};\n\nfunction isBool(value) {\n    return value === true || value === false;\n};\n\n\n\n/**\n * @param {Object} dst\n * @param {Object} src\n * @param {Object} src2 ... srcN\n * @param {boolean} override = false\n * @param {boolean} deep = false\n * @returns {*}\n */\nvar extend = function(){\n\n    var extend = function extend() {\n\n\n        var override    = false,\n            deep        = false,\n            args        = slice.call(arguments),\n            dst         = args.shift(),\n            src,\n            k,\n            value;\n\n        if (isBool(args[args.length - 1])) {\n            override    = args.pop();\n        }\n        if (isBool(args[args.length - 1])) {\n            deep        = override;\n            override    = args.pop();\n        }\n\n        while (args.length) {\n            if (src = args.shift()) {\n                for (k in src) {\n\n                    if (src.hasOwnProperty(k) && (value = src[k]) !== undf) {\n\n                        if (deep) {\n                            if (dst[k] && isPlainObject(dst[k]) && isPlainObject(value)) {\n                                extend(dst[k], value, override, deep);\n                            }\n                            else {\n                                if (override === true || dst[k] == undf) { // == checks for null and undefined\n                                    if (isPlainObject(value)) {\n                                        dst[k] = {};\n                                        extend(dst[k], value, override, true);\n                                    }\n                                    else {\n                                        dst[k] = value;\n                                    }\n                                }\n                            }\n                        }\n                        else {\n                            if (override === true || dst[k] == undf) {\n                                dst[k] = value;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        return dst;\n    };\n\n    return extend;\n}();\n\n\n\nvar Scope = function(cfg) {\n    var self    = this;\n\n    self.$$observable    = new Observable;\n    self.$$historyWatchers  = {};\n    extend(self, cfg, true, false);\n\n    if (self.$parent) {\n        self.$parent.$on(\"check\", self.$$onParentCheck, self);\n        self.$parent.$on(\"destroy\", self.$$onParentDestroy, self);\n    }\n    else {\n        self.$root  = self;\n        self.$isRoot= true;\n    }\n};\n\nextend(Scope.prototype, {\n\n    $app: null,\n    $parent: null,\n    $root: null,\n    $isRoot: false,\n    $$observable: null,\n    $$watchers: null,\n    $$historyWatchers: null,\n    $$checking: false,\n    $$destroyed: false,\n\n    $new: function() {\n        var self = this;\n        return new Scope({\n            $parent: self,\n            $root: self.$root,\n            $app: self.$app\n        });\n    },\n\n    $newIsolated: function() {\n        return new Scope({\n            $app: this.$app\n        });\n    },\n\n    $on: function(event, fn, fnScope) {\n        return this.$$observable.on(event, fn, fnScope);\n    },\n\n    $un: function(event, fn, fnScope) {\n        return this.$$observable.un(event, fn, fnScope);\n    },\n\n    $watch: function(expr, fn, fnScope) {\n        return Watchable.create(this, expr, fn, fnScope, null);\n    },\n\n    $unwatch: function(expr, fn, fnScope) {\n        return Watchable.unsubscribeAndDestroy(this, expr, fn, fnScope);\n    },\n\n    $watchHistory: function(prop, param) {\n        var self = this;\n        if (!self.$$historyWatchers[param]) {\n            self.$$historyWatchers[param] = prop;\n            MetaphorJs.history.on(\"change-\" + param, self.$$onHistoryChange, self);\n        }\n    },\n\n    $unwatchHistory: function(param) {\n        var self = this;\n        if (!self.$$historyWatchers[param]) {\n            delete self.$$historyWatchers[param];\n            MetaphorJs.history.un(\"change-\" + param, self.$$onHistoryChange, self);\n        }\n    },\n\n    $get: function(key) {\n\n        var s       = this;\n\n        while (s) {\n            if (s[key] !== undf) {\n                return s[key];\n            }\n            s       = s.$parent;\n        }\n\n        return undf;\n    },\n\n    $$onParentDestroy: function() {\n        this.$destroy();\n    },\n\n    $$onParentCheck: function() {\n        this.$check();\n    },\n\n    $$onHistoryChange: function(val, prev, name) {\n        var self = this,\n            prop;\n        if (self.$$historyWatchers[name]) {\n            prop = self.$$historyWatchers[name];\n            self[prop] = val;\n            self.$check();\n        }\n    },\n\n    $check: function() {\n        var self = this,\n            changes;\n\n        if (self.$$checking) {\n            return;\n        }\n        self.$$checking = true;\n\n        if (self.$$watchers) {\n            changes = self.$$watchers.$checkAll();\n        }\n\n        self.$$checking = false;\n\n        if (!self.$$destroyed) {\n            self.$$observable.trigger(\"check\", changes);\n        }\n\n        if (changes > 0) {\n            self.$check();\n        }\n    },\n\n    $destroy: function() {\n\n        var self    = this,\n            param, i;\n\n        self.$$observable.trigger(\"destroy\");\n        self.$$observable.destroy();\n\n        if (self.$$watchers) {\n            self.$$watchers.$destroyAll();\n        }\n\n        for (param in self.$$historyWatchers) {\n            self.$unwatchHistory(param);\n        }\n\n        for (i in self) {\n            if (self.hasOwnProperty(i)) {\n                self[i] = null;\n            }\n        }\n\n        self.$$destroyed = true;\n    }\n\n}, true, false);\n\n\n\n\n\n/**\n * @returns {String}\n */\nvar nextUid = function(){\n    var uid = ['0', '0', '0'];\n\n    // from AngularJs\n    return function nextUid() {\n        var index = uid.length;\n        var digit;\n\n        while(index) {\n            index--;\n            digit = uid[index].charCodeAt(0);\n            if (digit == 57 /*'9'*/) {\n                uid[index] = 'A';\n                return uid.join('');\n            }\n            if (digit == 90  /*'Z'*/) {\n                uid[index] = '0';\n            } else {\n                uid[index] = String.fromCharCode(digit + 1);\n                return uid.join('');\n            }\n        }\n        uid.unshift('0');\n        return uid.join('');\n    };\n}();\n\n\n\n\n/**\n * @param {*} value\n * @returns {boolean}\n */\nfunction isArray(value) {\n    return typeof value == \"object\" && varType(value) === 5;\n};\n\n\n\n/**\n * @param {*} list\n * @returns {[]}\n */\nfunction toArray(list) {\n    if (list && !list.length != undf && list !== \"\"+list) {\n        for(var a = [], i =- 1, l = list.length>>>0; ++i !== l; a[i] = list[i]){}\n        return a;\n    }\n    else if (list) {\n        return [list];\n    }\n    else {\n        return [];\n    }\n};\n\nfunction isFunction(value) {\n    return typeof value == 'function';\n};\n\n\n\n/**\n * Returns 'then' function or false\n * @param {*} any\n * @returns {Function|boolean}\n */\nfunction isThenable(any) {\n    if (!any || !any.then) {\n        return false;\n    }\n    var then, t;\n    //if (!any || (!isObject(any) && !isFunction(any))) {\n    if (((t = typeof any) != \"object\" && t != \"function\")) {\n        return false;\n    }\n    return isFunction((then = any.then)) ?\n           then : false;\n};\n\n\n\nvar nsGet = ns.get;\n\n\n\nfunction isString(value) {\n    return typeof value == \"string\" || value === \"\"+value;\n    //return typeof value == \"string\" || varType(value) === 0;\n};\n\n\n\nvar nodeTextProp = function(){\n    var node    = document.createTextNode(\"\");\n    return isString(node.textContent) ? \"textContent\" : \"nodeValue\";\n}();\n\n\n\n/**\n * @param {String} value\n */\nvar trim = function() {\n    // native trim is way faster: http://jsperf.com/angular-trim-test\n    // but IE doesn't have it... :-(\n    if (!String.prototype.trim) {\n        return function(value) {\n            return isString(value) ? value.replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '') : value;\n        };\n    }\n    return function(value) {\n        return isString(value) ? value.trim() : value;\n    };\n}();\n\n\n\n\nvar createWatchable = Watchable.create;\n\n\n\nvar nsAdd = ns.add;\n\n\n\n\n\nvar Directive = function(){\n\n    var attributes          = [],\n        tags                = [],\n        attributesSorted    = false,\n\n        compare             = function(a, b) {\n            //if (a is less than b by some ordering criterion)\n            if (a.priority < b.priority) {\n                return -1;\n            }\n\n            //if (a is greater than b by the ordering criterion)\n            if (a.priority > b.priority) {\n                return 1;\n            }\n\n            // a must be equal to b\n            return 0;\n        };\n\n    return defineClass({\n\n        $class: \"Directive\",\n\n        watcher: null,\n        scope: null,\n        node: null,\n        expr: null,\n\n        autoOnChange: true,\n\n        $init: function(scope, node, expr) {\n\n            var self        = this,\n                val;\n\n            expr            = trim(expr);\n\n            self.node       = node;\n            self.expr       = expr;\n            self.scope      = scope;\n            self.watcher    = createWatchable(scope, expr, self.onChange, self, null, ns);\n\n            if (self.autoOnChange && (val = self.watcher.getLastResult()) != undf) {\n                self.onChange(val, undf);\n            }\n\n            scope.$on(\"destroy\", self.onScopeDestroy, self);\n        },\n\n        onScopeDestroy: function() {\n            this.$destroy();\n        },\n\n        onChange: function() {},\n\n        destroy: function() {\n            var self    = this;\n\n            if (self.watcher) {\n                self.watcher.unsubscribeAndDestroy(self.onChange, self);\n            }\n\n            self.$super();\n        }\n    }, {\n\n\n        registerAttribute: function registerAttribute(name, priority, handler) {\n            if (!nsGet(\"attr.\" + name, true)) {\n                attributes.push({\n                    priority: priority,\n                    name: name,\n                    handler: nsAdd(\"attr.\" + name, handler)\n                });\n                attributesSorted = false;\n            }\n        },\n\n        getAttributes: function getAttributes() {\n            if (!attributesSorted) {\n                attributes.sort(compare);\n                attributesSorted = true;\n            }\n            return attributes;\n        },\n\n        registerTag: function registerTag(name, handler) {\n            if (!nsGet(\"tag.\" + name, true)) {\n                nsAdd(\"tag.\" + name, handler)\n            }\n        }\n\n    });\n\n}();\n\n\n\n\n/**\n * @param {Function} fn\n * @param {*} context\n */\nvar bind = Function.prototype.bind ?\n              function(fn, context){\n                  return fn.bind(context);\n              } :\n              function(fn, context) {\n                  return function() {\n                      return fn.apply(context, arguments);\n                  };\n              };\n\n\n\nfunction isNull(value) {\n    return value === null;\n};\n\n\n\n\n\nvar TextRenderer = function(){\n\n    var startSymbol             = '{{',\n        endSymbol               = '}}',\n        startSymbolLength       = 2,\n        endSymbolLength         = 2,\n\n        langStartSymbol         = '{[',\n        langEndSymbol           = ']}',\n        langStartLength         = 2,\n        langEndLength           = 2,\n\n        rReplaceEscape          = /\\\\{/g,\n\n        observer                = new Observable,\n\n        factory                 = function(scope, origin, parent, userData, recursive) {\n\n            if (!origin || !origin.indexOf ||\n                (origin.indexOf(startSymbol) == -1 &&\n                 origin.indexOf(langStartSymbol) == -1)) {\n                return null;\n            }\n\n            return new TextRenderer(scope, origin, parent, userData, recursive);\n        };\n\n    var TextRenderer = defineClass({\n\n        $class: \"TextRenderer\",\n\n        id: null,\n        parent: null,\n        isRoot: null,\n        scope: null,\n        origin: \"\",\n        processed: null,\n        text: null,\n        watchers: null,\n        children: null,\n        data: null,\n        recursive: false,\n        dataChangeDelegate: null,\n        changeTmt: null,\n        lang: null,\n\n        $init: function(scope, origin, parent, userData, recursive) {\n\n            var self        = this;\n\n            self.id         = nextUid();\n            self.origin     = origin;\n            self.scope      = scope;\n            self.parent     = parent;\n            self.isRoot     = !parent;\n            self.data       = userData;\n            self.lang       = scope.$app ? scope.$app.lang : null;\n\n            if (recursive === true || recursive === false) {\n                self.recursive = recursive;\n            }\n\n            self.watchers   = [];\n            self.children   = [];\n\n            self.dataChangeDelegate = bind(self.doDataChange, self);\n            self.processed  = self.processText(origin);\n            self.render();\n        },\n\n        subscribe: function(fn, context) {\n            return observer.on(this.id, fn, context);\n        },\n\n        unsubscribe: function(fn, context) {\n            return observer.un(this.id, fn, context);\n        },\n\n        getString: function() {\n            var self = this;\n\n            if (isNull(self.text)) {\n                self.render();\n            }\n\n            var text = self.text;\n\n            if (text.indexOf('\\\\{') != -1) {\n                return text.replace(rReplaceEscape, '{');\n            }\n\n            return text;\n        },\n\n\n        render: function() {\n\n            var self    = this,\n                text    = self.processed,\n                i, l,\n                ch;\n\n            if (!self.children.length) {\n                self.createChildren();\n            }\n\n            ch = self.children;\n\n            for (i = -1, l = ch.length; ++i < l;\n                 text = text.replace(\n                     '---' + i + '---',\n                     ch[i] instanceof TextRenderer ? ch[i].getString() : ch[i]\n                 )) {}\n\n            self.text = text;\n\n            return text;\n        },\n\n\n\n        processText: function(text) {\n\n            /*\n             arguably, str += \"\" is faster than separators.push() + separators.join()\n             well, at least in my Firefox it is so.\n             */\n\n            var self        = this,\n                index       = 0,\n                textLength  = text.length,\n                startIndex,\n                endIndex,\n                result      = \"\";\n            //separators  = [];\n\n            // regular keys\n            while(index < textLength) {\n                if (((startIndex = text.indexOf(startSymbol, index)) != -1) &&\n                    ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1) &&\n                    text.substr(startIndex - 1, 1) != '\\\\') {\n\n                    result += text.substring(index, startIndex);\n\n                    if (endIndex != startIndex + startSymbolLength) {\n                        result += self.watcherMatch(\n                            text.substring(startIndex + startSymbolLength, endIndex)\n                        );\n                    }\n\n                    index = endIndex + endSymbolLength;\n\n                } else {\n                    // we did not find an interpolation\n                    if (index !== textLength) {\n                        result += text.substring(index);\n                    }\n                    break;\n                }\n            }\n\n            index       = 0;\n            text        = result;\n            textLength  = text.length;\n            result      = \"\";\n            //separators  = [];\n\n            // lang keys\n            while(index < textLength) {\n\n                if (((startIndex = text.indexOf(langStartSymbol, index)) != -1) &&\n                    ((endIndex = text.indexOf(langEndSymbol, startIndex + langStartLength)) != -1) &&\n                    text.substr(startIndex - 1, 1) != '\\\\') {\n\n                    result += text.substring(index, startIndex);\n\n                    if (endIndex != startIndex + langStartLength) {\n                        result += self.watcherMatch(\n                            text.substring(startIndex + langStartLength, endIndex),\n                            true\n                        );\n                    }\n\n                    index = endIndex + langEndLength;\n\n                } else {\n                    // we did not find an interpolation\n                    if (index !== textLength) {\n                        result += text.substring(index);\n                    }\n                    break;\n                }\n            }\n\n            return result;\n        },\n\n        watcherMatch: function(expr, isLang) {\n\n            var self    = this,\n                ws      = self.watchers;\n\n            if (isLang) {\n                expr        = trim(expr);\n                var tmp     = expr.split(\"|\"),\n                    key     = trim(tmp[0]);\n                if (key.substr(0, 1) != \".\") {\n                    tmp[0]  = \"'\" + key + \"'\";\n                }\n                if (tmp.length == 1) {\n                    tmp.push(\"l\");\n                }\n                expr        = tmp.join(\" | \");\n            }\n\n            ws.push(createWatchable(\n                self.scope,\n                expr,\n                self.onDataChange,\n                self,\n                null,\n                ns\n            ));\n\n            return '---'+ (ws.length-1) +'---';\n        },\n\n        onDataChange: function() {\n\n            var self    = this;\n\n            if (!self.changeTmt) {\n                self.changeTmt = setTimeout(self.dataChangeDelegate, 0);\n            }\n        },\n\n        doDataChange: function() {\n            var self = this;\n            self.destroyChildren();\n            self.triggerChange();\n            self.changeTmt = null;\n        },\n\n        triggerChange: function() {\n\n            var self    = this;\n            self.text   = null;\n\n            if (self.isRoot) {\n                observer.trigger(self.id, self, self.data);\n            }\n            else {\n                self.parent.triggerChange();\n            }\n        },\n\n\n        createChildren: function() {\n\n            var self    = this,\n                ws      = self.watchers,\n                ch      = self.children,\n                scope   = self.scope,\n                rec     = self.recursive,\n                i, l,\n                val;\n\n            for (i = -1, l = ws.length; ++i < l; ){\n                val     = ws[i].getLastResult();\n                ch.push((rec && factory(scope, val, self, null, true)) || val);\n            }\n        },\n\n        destroyChildren: function() {\n\n            var self    = this,\n                ch      = self.children,\n                i, l;\n\n            for (i = -1, l = ch.length; ++i < l; ){\n                if (ch[i] instanceof TextRenderer) {\n                    ch[i].$destroy();\n                }\n            }\n\n            self.children = [];\n        },\n\n        destroyWatchers: function() {\n\n            var self    = this,\n                ws      = self.watchers,\n                i, l;\n\n            for (i = -1, l = ws.length; ++i < l;\n                 ws[i].unsubscribeAndDestroy(self.onDataChange, self)){}\n\n            self.watchers = [];\n        },\n\n        destroy: function() {\n\n            var self = this;\n\n            self.destroyChildren();\n            self.destroyWatchers();\n\n            observer.destroyEvent(self.id);\n\n            if (self.changeTmt) {\n                clearTimeout(self.changeTmt);\n            }\n        }\n\n    }, {\n        create: factory\n    });\n\n    return TextRenderer;\n}();\n\n\n\n\n\nfunction setAttr(el, name, value) {\n    return el.setAttribute(name, value);\n};\n\nfunction removeAttr(el, name) {\n    return el.removeAttribute(name);\n};\n\nfunction getAttrMap(node) {\n    var map = {},\n        i, l, a,\n        attrs = node.attributes;\n\n    for (i = 0, l = attrs.length; i < l; i++) {\n        a = attrs[i];\n        map[a.name] = a.value;\n    }\n\n    return map;\n};\n\nvar aIndexOf    = Array.prototype.indexOf;\n\nif (!aIndexOf) {\n    aIndexOf = Array.prototype.indexOf = function (searchElement, fromIndex) {\n\n        var k;\n\n        // 1. Let O be the result of calling ToObject passing\n        //    the this value as the argument.\n        if (this == null) {\n            throw new TypeError('\"this\" is null or not defined');\n        }\n\n        var O = Object(this);\n\n        // 2. Let lenValue be the result of calling the Get\n        //    internal method of O with the argument \"length\".\n        // 3. Let len be ToUint32(lenValue).\n        var len = O.length >>> 0;\n\n        // 4. If len is 0, return -1.\n        if (len === 0) {\n            return -1;\n        }\n\n        // 5. If argument fromIndex was passed let n be\n        //    ToInteger(fromIndex); else let n be 0.\n        var n = +fromIndex || 0;\n\n        if (Math.abs(n) === Infinity) {\n            n = 0;\n        }\n\n        // 6. If n >= len, return -1.\n        if (n >= len) {\n            return -1;\n        }\n\n        // 7. If n >= 0, then Let k be n.\n        // 8. Else, n<0, Let k be len - abs(n).\n        //    If k is less than 0, then let k be 0.\n        k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);\n\n        // 9. Repeat, while k < len\n        while (k < len) {\n            var kValue;\n            // a. Let Pk be ToString(k).\n            //   This is implicit for LHS operands of the in operator\n            // b. Let kPresent be the result of calling the\n            //    HasProperty internal method of O with argument Pk.\n            //   This step can be combined with c\n            // c. If kPresent is true, then\n            //    i.  Let elementK be the result of calling the Get\n            //        internal method of O with the argument ToString(k).\n            //   ii.  Let same be the result of applying the\n            //        Strict Equality Comparison Algorithm to\n            //        searchElement and elementK.\n            //  iii.  If same is true, return k.\n            if (k in O && O[k] === searchElement) {\n                return k;\n            }\n            k++;\n        }\n        return -1;\n    };\n}\n\n\n\n\n\n\n\n\nvar Renderer = function(){\n\n    var handlers                = null,\n        createText              = TextRenderer.create,\n\n        nodeChildren = function(res, el, fn, fnScope, finish, cnt) {\n\n            var children = [],\n                i, len;\n\n            if (res && res !== true) {\n                if (res.nodeType) {\n                    cnt.countdown += 1;\n                    eachNode(res, fn, fnScope, finish, cnt);\n                    return;\n                }\n                else {\n                    children = slice.call(res);\n                }\n            }\n\n            if (!children.length) {\n                children    = toArray(el.childNodes);\n            }\n\n            len = children.length;\n\n            cnt.countdown += len;\n\n            for(i = -1;\n                ++i < len;\n                eachNode(children[i], fn, fnScope, finish, cnt)){}\n        },\n\n\n        collectNodes    = function(coll, add) {\n\n            if (add) {\n                if (add.nodeType) {\n                    coll.push(add);\n                }\n                else if (isArray(add)) {\n                    for (var i = -1, l = add.length; ++i < l; collectNodes(coll, add[i])){}\n                }\n            }\n        },\n\n        //rSkipTag = /^(script|template|mjs-template|style)$/i,\n\n        skipMap = {\n            \"script\": true,\n            \"template\": true,\n            \"mjs-template\": true,\n            \"style\": true\n        },\n\n        eachNode = function(el, fn, fnScope, finish, cnt) {\n\n            if (!el) {\n                return;\n            }\n\n            var res,\n                tag = el.nodeName;\n\n            if (!cnt) {\n                cnt = {countdown: 1};\n            }\n\n            if (tag && skipMap[tag.toLowerCase()]) { //tag.match(rSkipTag)) {\n                --cnt.countdown == 0 && finish && finish.call(fnScope);\n                return;\n            }\n\n\n            //if (el.nodeType) {\n                res = fn.call(fnScope, el);\n            //}\n\n\n            if (res !== false) {\n\n                if (isThenable(res)) {\n\n                    res.done(function(response){\n\n                        if (response !== false) {\n                            nodeChildren(response, el, fn, fnScope, finish, cnt);\n                        }\n\n                        --cnt.countdown == 0 && finish && finish.call(fnScope);\n                    });\n                    return; // prevent countdown\n                }\n                else {\n                    nodeChildren(res, el, fn, fnScope, finish, cnt);\n                }\n            }\n\n            --cnt.countdown == 0 && finish && finish.call(fnScope);\n        },\n\n        observer = new Observable;\n\n    return defineClass({\n\n        $class: \"Renderer\",\n\n        id: null,\n        el: null,\n        scope: null,\n        texts: null,\n        parent: null,\n\n        $init: function(el, scope, parent) {\n            var self            = this;\n\n            self.id             = nextUid();\n            self.el             = el;\n            self.scope          = scope;\n            self.texts          = [];\n            self.parent         = parent;\n\n            if (scope instanceof Scope) {\n                scope.$on(\"destroy\", self.$destroy, self);\n            }\n\n            if (parent) {\n                parent.on(\"destroy\", self.$destroy, self);\n            }\n        },\n\n        on: function(event, fn, context) {\n            return observer.on(event + '-' + this.id, fn, context);\n        },\n\n        once: function(event, fn, context) {\n            return observer.once(event + '-' + this.id, fn, context);\n        },\n\n        un: function(event, fn, context) {\n            return observer.un(event + '-' + this.id, fn, context);\n        },\n\n        createChild: function(node) {\n            return new Renderer(node, this.scope, this);\n        },\n\n        getEl: function() {\n            return this.el;\n        },\n\n        runHandler: function(f, parentScope, node, value) {\n\n            var self    = this,\n                scope   = f.$isolateScope ?\n                          parentScope.$newIsolated() :\n                          (f.$breakScope  ?\n                           parentScope.$new() :\n                           parentScope),\n                app     = parentScope.$app,\n                inject  = {\n                    $scope: scope,\n                    $node: node,\n                    $attrValue: value,\n                    $renderer: self\n                },\n                args    = [scope, node, value, self],\n                inst    = app.inject(f, null, inject, args);\n\n            if (app && f.$registerBy && inst) {\n                if (isThenable(inst)) {\n                    inst.done(function(cmp){\n                        app.registerCmp(cmp, parentScope, f.$registerBy);\n                    });\n                }\n                else {\n                    app.registerCmp(inst, parentScope, f.$registerBy);\n                }\n            }\n\n            return f.$stopRenderer ? false : inst;\n        },\n\n        processNode: function(node) {\n\n            var self        = this,\n                nodeType    = node.nodeType,\n                texts       = self.texts,\n                scope       = self.scope,\n                textRenderer,\n                recursive,\n                n;\n\n            // text node\n            if (nodeType == 3) {\n\n                recursive       = getAttr(node.parentNode, \"mjs-recursive\") !== null;\n                textRenderer    = createText(scope, node[nodeTextProp], null, texts.length, recursive);\n\n                if (textRenderer) {\n                    textRenderer.subscribe(self.onTextChange, self);\n                    texts.push({\n                        node: node,\n                        tr: textRenderer\n                    });\n                    self.renderText(texts.length - 1);\n                }\n\n            }\n\n            // element node\n            else if (nodeType == 1) {\n\n                if (!handlers) {\n                    handlers = Directive.getAttributes();\n                }\n\n                var tag     = node.tagName.toLowerCase(),\n                    defers  = [],\n                    nodes   = [],\n                    i, f, len,\n                    map,\n                    attrValue,\n                    name,\n                    res;\n\n                n = \"tag.\" + tag;\n                if (f = nsGet(n, true)) {\n\n                    res = self.runHandler(f, scope, node);\n\n                    if (res === false) {\n                        return false;\n                    }\n                    if (isThenable(res)) {\n                        defers.push(res);\n                    }\n                    else {\n                        collectNodes(nodes, res);\n                    }\n                }\n\n                map = getAttrMap(node);\n\n                for (i = 0, len = handlers.length; i < len; i++) {\n                    name    = handlers[i].name;\n\n                    if ((attrValue = map[name]) !== undf) {\n\n                        removeAttr(node, name);\n\n                        res     = self.runHandler(handlers[i].handler, scope, node, attrValue);\n\n                        map[name] = null;\n\n                        if (res === false) {\n                            return false;\n                        }\n                        if (isThenable(res)) {\n                            defers.push(res);\n                        }\n                        else {\n                            collectNodes(nodes, res);\n                        }\n                    }\n                }\n\n                if (defers.length) {\n                    var deferred = new Promise;\n                    Promise.all(defers).done(function(values){\n                        collectNodes(nodes, values);\n                        deferred.resolve(nodes);\n                    });\n                    return deferred;\n                }\n\n                recursive = map[\"mjs-recursive\"] !== undf;\n                delete map[\"mjs-recursive\"];\n\n                //var attrs   = toArray(node.attributes);\n\n                for (i in map) {\n\n                    if (map[i] !== null) {\n\n                        textRenderer = createText(scope, map[i], null, texts.length, recursive);\n\n                        if (textRenderer) {\n                            removeAttr(node, i);\n                            textRenderer.subscribe(self.onTextChange, self);\n                            texts.push({\n                                node: node,\n                                attr: i,\n                                tr:   textRenderer\n                            });\n                            self.renderText(texts.length - 1);\n                        }\n                    }\n                }\n\n                return nodes.length ? nodes : true;\n            }\n\n            return true;\n        },\n\n        process: function() {\n            var self    = this;\n            eachNode(self.el, self.processNode, self, self.onProcessingFinished, {countdown: 1});\n        },\n\n        onProcessingFinished: function() {\n            observer.trigger(\"rendered-\" + this.id, this);\n        },\n\n\n        onTextChange: function(textRenderer, inx) {\n            this.renderText(inx);\n        },\n\n        renderText: function(inx) {\n\n            var self        = this,\n                text        = self.texts[inx],\n                res         = text.tr.getString(),\n                attrName    = text.attr;\n\n\n            if (attrName) {\n\n                if (attrName == \"value\") {\n                    text.node.value = res;\n                }\n                else if (attrName == \"class\") {\n                    text.node.className = res;\n                }\n                else if (attrName == \"src\") {\n                    text.node.src = res;\n                }\n\n                setAttr(text.node, attrName, res);\n            }\n            else {\n                text.node[nodeTextProp] = res;\n            }\n        },\n\n\n        destroy: function() {\n\n            var self    = this,\n                texts   = self.texts,\n                i, len;\n\n            for (i = -1, len = texts.length; ++i < len; texts[i].tr.$destroy()) {}\n\n            if (self.parent) {\n                self.parent.un(\"destroy\", self.$destroy, self);\n            }\n\n            observer.trigger(\"destroy-\" + self.id);\n        }\n\n    });\n\n}();\n\n\n\n\n\n\nvar Text = function(){\n\n    var pluralDef       = function($number, $locale) {\n\n            if ($locale == \"pt_BR\") {\n                // temporary set a locale for brasilian\n                $locale = \"xbr\";\n            }\n\n            if ($locale.length > 3) {\n                $locale = $locale.substr(0, -$locale.lastIndexOf('_'));\n            }\n\n            switch($locale) {\n                case 'bo':\n                case 'dz':\n                case 'id':\n                case 'ja':\n                case 'jv':\n                case 'ka':\n                case 'km':\n                case 'kn':\n                case 'ko':\n                case 'ms':\n                case 'th':\n                case 'tr':\n                case 'vi':\n                case 'zh':\n                    return 0;\n                    break;\n\n                case 'af':\n                case 'az':\n                case 'bn':\n                case 'bg':\n                case 'ca':\n                case 'da':\n                case 'de':\n                case 'el':\n                case 'en':\n                case 'eo':\n                case 'es':\n                case 'et':\n                case 'eu':\n                case 'fa':\n                case 'fi':\n                case 'fo':\n                case 'fur':\n                case 'fy':\n                case 'gl':\n                case 'gu':\n                case 'ha':\n                case 'he':\n                case 'hu':\n                case 'is':\n                case 'it':\n                case 'ku':\n                case 'lb':\n                case 'ml':\n                case 'mn':\n                case 'mr':\n                case 'nah':\n                case 'nb':\n                case 'ne':\n                case 'nl':\n                case 'nn':\n                case 'no':\n                case 'om':\n                case 'or':\n                case 'pa':\n                case 'pap':\n                case 'ps':\n                case 'pt':\n                case 'so':\n                case 'sq':\n                case 'sv':\n                case 'sw':\n                case 'ta':\n                case 'te':\n                case 'tk':\n                case 'ur':\n                case 'zu':\n                    return ($number == 1) ? 0 : 1;\n\n                case 'am':\n                case 'bh':\n                case 'fil':\n                case 'fr':\n                case 'gun':\n                case 'hi':\n                case 'ln':\n                case 'mg':\n                case 'nso':\n                case 'xbr':\n                case 'ti':\n                case 'wa':\n                    return (($number == 0) || ($number == 1)) ? 0 : 1;\n\n                case 'be':\n                case 'bs':\n                case 'hr':\n                case 'ru':\n                case 'sr':\n                case 'uk':\n                    return (($number % 10 == 1) && ($number % 100 != 11)) ?\n                           0 :\n                           ((($number % 10 >= 2) && ($number % 10 <= 4) &&\n                             (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);\n\n                case 'cs':\n                case 'sk':\n                    return ($number == 1) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2);\n\n                case 'ga':\n                    return ($number == 1) ? 0 : (($number == 2) ? 1 : 2);\n\n                case 'lt':\n                    return (($number % 10 == 1) && ($number % 100 != 11)) ?\n                           0 :\n                           ((($number % 10 >= 2) &&\n                             (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);\n\n                case 'sl':\n                    return ($number % 100 == 1) ?\n                           0 :\n                           (($number % 100 == 2) ?\n                                1 :\n                                ((($number % 100 == 3) || ($number % 100 == 4)) ? 2 : 3));\n\n                case 'mk':\n                    return ($number % 10 == 1) ? 0 : 1;\n\n                case 'mt':\n                    return ($number == 1) ?\n                           0 :\n                           ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ?\n                                1 :\n                                ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3));\n\n                case 'lv':\n                    return ($number == 0) ? 0 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2);\n\n                case 'pl':\n                    return ($number == 1) ?\n                           0 :\n                           ((($number % 10 >= 2) && ($number % 10 <= 4) &&\n                             (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2);\n\n                case 'cy':\n                    return ($number == 1) ? 0 : (($number == 2) ? 1 : ((($number == 8) || ($number == 11)) ? 2 : 3));\n\n                case 'ro':\n                    return ($number == 1) ?\n                           0 :\n                           ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2);\n\n                case 'ar':\n                    return ($number == 0) ?\n                           0 :\n                           (($number == 1) ?\n                                1 :\n                                (($number == 2) ?\n                                    2 :\n                                    ((($number >= 3) && ($number <= 10)) ?\n                                        3 :\n                                        ((($number >= 11) && ($number <= 99)) ? 4 : 5))));\n\n                default:\n                    return 0;\n            }\n        };\n\n\n    var Text = function(locale) {\n\n        var self    = this;\n        self.store  = {};\n        if (locale) {\n            self.locale = locale;\n        }\n    };\n\n    extend(Text.prototype, {\n\n        store: null,\n        locale: \"en\",\n\n        setLocale: function(locale) {\n            this.locale = locale;\n        },\n\n        set: function(key, value) {\n            var store = this.store;\n            if (store[key] === undf) {\n                store[key] = value;\n            }\n        },\n\n        load: function(keys) {\n            extend(this.store, keys, false, false);\n        },\n\n        get: function(key) {\n            var self    = this;\n            return self.store[key] ||\n                   (self === globalText ? '-- ' + key + ' --' : globalText.get(key));\n        },\n\n        plural: function(key, number) {\n            var self    = this,\n                strings = self.get(key),\n                def     = pluralDef(number, self.locale);\n\n            if (!isArray(strings)) {\n                if (isPlainObject(strings)) {\n                    if (strings[number]) {\n                        return strings[number];\n                    }\n                    if (number == 1 && strings.one != undf) {\n                        return strings.one;\n                    }\n                    else if (number < 0 && strings.negative != undf) {\n                        return strings.negative;\n                    }\n                    else {\n                        return strings.other;\n                    }\n                }\n                return strings;\n            }\n            else {\n                return strings[def];\n            }\n        },\n\n        destroy: function() {\n\n            this.store = null;\n\n        }\n\n    }, true, false);\n\n\n    var globalText  = new Text;\n\n    Text.global     = function() {\n        return globalText;\n    };\n\n    return Text;\n}();\n\n\n\n\n/**\n * @mixin ObservableMixin\n */\nvar ObservableMixin = ns.add(\"mixin.Observable\", {\n\n    /**\n     * @type {Observable}\n     */\n    $$observable: null,\n\n    $beforeInit: function(cfg) {\n\n        var self = this;\n\n        self.$$observable = new Observable;\n\n        if (cfg && cfg.callback) {\n            var ls = cfg.callback,\n                context = ls.context,\n                i;\n\n            ls.context = null;\n\n            for (i in ls) {\n                if (ls[i]) {\n                    self.$$observable.on(i, ls[i], context || self);\n                }\n            }\n\n            cfg.callback = null;\n        }\n    },\n\n    on: function() {\n        var o = this.$$observable;\n        return o.on.apply(o, arguments);\n    },\n\n    un: function() {\n        var o = this.$$observable;\n        return o.un.apply(o, arguments);\n    },\n\n    once: function() {\n        var o = this.$$observable;\n        return o.once.apply(o, arguments);\n    },\n\n    trigger: function() {\n        var o = this.$$observable;\n        return o.trigger.apply(o, arguments);\n    },\n\n    $beforeDestroy: function() {\n        this.$$observable.trigger(\"beforedestroy\", this);\n    },\n\n    $afterDestroy: function() {\n        var self = this;\n        self.$$observable.trigger(\"destroy\", self);\n        self.$$observable.destroy();\n        self.$$observable = null;\n    }\n});\n\n\n\nfunction isObject(value) {\n    if (value === null || typeof value != \"object\") {\n        return false;\n    }\n    var vt = varType(value);\n    return vt > 2 || vt == -1;\n};\n\n\n\nvar instantiate = function(fn, args) {\n\n    var Temp = function(){},\n        inst, ret;\n\n    Temp.prototype  = fn.prototype;\n    inst            = new Temp;\n    ret             = fn.apply(inst, args);\n\n    // If an object has been returned then return it otherwise\n    // return the original instance.\n    // (consistent with behaviour of the new operator)\n    return isObject(ret) || ret === false ? ret : inst;\n\n};\n\n\n\n\n\nvar Provider = function(){\n\n    var VALUE       = 1,\n        CONSTANT    = 2,\n        FACTORY     = 3,\n        SERVICE     = 4,\n        PROVIDER    = 5,\n        globalProvider;\n\n    var Provider = function() {\n        this.store  = {};\n    };\n\n    extend(Provider.prototype, {\n\n        store: null,\n\n        instantiate: function(fn, context, args, isClass) {\n\n            if (fn.$instantiate) {\n                return fn.$instantiate.apply(fn, args);\n            }\n            else if (isClass) {\n                return instantiate(fn, args);\n            }\n            else {\n                return fn.apply(context, args);\n            }\n        },\n\n        inject: function(injectable, context, currentValues, callArgs, isClass) {\n\n            currentValues   = currentValues || {};\n            callArgs        = callArgs || [];\n\n            var self = this;\n\n            if (isFunction(injectable)) {\n\n                if (injectable.inject) {\n                    var tmp = slice.call(injectable.inject);\n                    tmp.push(injectable);\n                    injectable = tmp;\n                }\n                else {\n                    return self.instantiate(injectable, context, callArgs, isClass);\n                }\n            }\n\n            injectable  = slice.call(injectable);\n\n            var values  = [],\n                fn      = injectable.pop(),\n                i, l;\n\n            for (i = -1, l = injectable.length; ++i < l;\n                 values.push(self.resolve(injectable[i], currentValues))) {}\n\n            return Promise.all(values).then(function(values){\n                return self.instantiate(fn, context, values, isClass);\n            });\n        },\n\n        value: function(name, value) {\n            this.store[name] = {\n                type: VALUE,\n                value: value\n            };\n        },\n\n        constant: function(name, value) {\n            var store = this.store;\n            if (!store[name]) {\n                store[name] = {\n                    type: CONSTANT,\n                    value: value\n                };\n            }\n        },\n\n        factory: function(name, fn, context, singleton) {\n\n            if (isBool(context)) {\n                singleton = context;\n                context = null;\n            }\n\n            this.store[name] = {\n                type: FACTORY,\n                singleton: singleton,\n                fn: fn,\n                context: context\n            };\n        },\n\n        service: function(name, constr, singleton) {\n            this.store[name] = {\n                type: SERVICE,\n                singleton: singleton,\n                fn: constr\n            };\n        },\n\n        provider: function(name, constr) {\n\n            this.store[name + \"Provider\"] = {\n                name: name,\n                type: PROVIDER,\n                fn: constr,\n                instance: null\n            };\n        },\n\n\n        resolve: function(name, currentValues) {\n\n            var self    = this,\n                store   = self.store,\n                type,\n                item,\n                res;\n\n            if (currentValues[name] !== undf) {\n                return currentValues[name];\n            }\n\n            if (item = store[name]) {\n\n                type    = item.type;\n\n                if (type == VALUE || type == CONSTANT) {\n                    return item.value;\n                }\n                else if (type == FACTORY) {\n                    res = self.inject(item.fn, item.context, currentValues);\n                }\n                else if (type == SERVICE) {\n                    res = self.inject(item.fn, null, currentValues, null, true);\n                }\n                else if (type == PROVIDER) {\n\n                    if (!item.instance) {\n\n                        item.instance = Promise.resolve(\n                                self.inject(item.fn, null, currentValues)\n                            )\n                            .done(function(instance){\n                                item.instance = instance;\n                                store[item.name] = {\n                                    type: FACTORY,\n                                    fn: instance.$get,\n                                    context: instance\n                                };\n                            });\n                    }\n\n                    return item.instance;\n                }\n\n                if (item.singleton) {\n                    item.type = VALUE;\n                    item.value = res;\n\n                    if (type == FACTORY && isThenable(res)) {\n                        res.done(function(value){\n                            item.value = value;\n                        });\n                    }\n                }\n\n                return currentValues[name] = res;\n            }\n            else {\n\n                if (store[name + \"Provider\"]) {\n                    self.resolve(name + \"Provider\", currentValues);\n                    return self.resolve(name, currentValues);\n                }\n\n                if (self === globalProvider) {\n                    throw \"Could not provide value for \" + name;\n                }\n                else {\n                    return globalProvider.resolve(name);\n                }\n            }\n        },\n\n        destroy: function() {\n            this.store = null;\n            this.scope = null;\n        }\n\n    }, true, false);\n\n    Provider.global = function() {\n        return globalProvider;\n    };\n\n    globalProvider = new Provider;\n\n    return Provider;\n}();\n\n\n\n\n\nvar ProviderMixin = {\n\n    /**\n     * @type {Provider}\n     */\n    $$provider: null,\n\n    $beforeInit: function() {\n\n        this.$$provider = new Provider;\n\n    },\n\n    value: function() {\n        var p = this.$$provider;\n        return p.value.apply(p, arguments);\n    },\n\n    constant: function() {\n        var p = this.$$provider;\n        return p.constant.apply(p, arguments);\n    },\n\n    factory: function() {\n        var p = this.$$provider;\n        return p.factory.apply(p, arguments);\n    },\n\n    service: function() {\n        var p = this.$$provider;\n        return p.service.apply(p, arguments);\n    },\n\n    provider: function() {\n        var p = this.$$provider;\n        return p.provider.apply(p, arguments);\n    },\n\n    resolve: function() {\n        var p = this.$$provider;\n        return p.resolve.apply(p, arguments);\n    },\n\n    inject: function() {\n        var p = this.$$provider;\n        return p.inject.apply(p, arguments);\n    },\n\n    $afterDestroy: function() {\n\n        this.$$provider.destroy();\n        this.$$provider = null;\n\n    }\n\n};\n\n\n\n\n\n\ndefineClass({\n\n    $class: \"App\",\n    $mixins: [ObservableMixin, ProviderMixin],\n\n    lang: null,\n    scope: null,\n    renderer: null,\n    cmpListeners: null,\n    components: null,\n\n    $init: function(node, data) {\n\n        var self        = this,\n            scope       = data instanceof Scope ? data : new Scope(data),\n            args;\n\n        removeAttr(node, \"mjs-app\");\n\n        scope.$app      = self;\n        self.$super();\n\n        self.lang       = new Text;\n\n        self.scope          = scope;\n        self.cmpListeners   = {};\n        self.components     = {};\n\n        self.factory('$parentCmp', ['$node', self.getParentCmp], self);\n        self.value('$app', self);\n        self.value('$rootScope', scope.$root);\n        self.value('$lang', self.lang);\n\n        self.renderer       = new Renderer(node, scope);\n\n        args = slice.call(arguments);\n        args[1] = scope;\n        self.initApp.apply(self, args);\n    },\n\n    initApp: emptyFn,\n\n    run: function() {\n        this.renderer.process();\n    },\n\n\n    getParentCmp: function(node) {\n\n        var self    = this,\n            parent  = node.parentNode,\n            id;\n\n        while (parent) {\n\n            if (id = getAttr(parent, \"cmp-id\")) {\n                return self.getCmp(id);\n            }\n\n            parent = parent.parentNode;\n        }\n\n        return null;\n    },\n\n    onAvailable: function(cmpId, fn, context) {\n\n        var self = this,\n            cmpListeners = self.cmpListeners,\n            components = self.components;\n\n        if (!cmpListeners[cmpId]) {\n            cmpListeners[cmpId] = new Promise;\n        }\n\n        if (fn) {\n            cmpListeners[cmpId].done(fn, context);\n        }\n\n        if (components[cmpId]) {\n            cmpListeners[cmpId].resolve(components[cmpId])\n        }\n\n        return cmpListeners[cmpId];\n    },\n\n    getCmp: function(id) {\n        return this.components[id] || null;\n    },\n\n    registerCmp: function(cmp, scope, byKey) {\n        var self = this,\n            id = cmp[byKey],\n            deregister = function() {\n                delete self.cmpListeners[id];\n                delete self.components[id];\n            };\n\n        self.components[id] = cmp;\n\n        if (self.cmpListeners[id]) {\n            self.cmpListeners[id].resolve(cmp);\n        }\n\n        if (cmp.on) {\n            cmp.on(\"destroy\", deregister);\n        }\n        scope.$on(\"$destroy\", deregister);\n    },\n\n    destroy: function() {\n\n        var self    = this;\n\n        self.renderer.$destroy();\n        self.scope.$destroy();\n        self.lang.destroy();\n\n        self.$super();\n    }\n\n});\n\n\n\n\nvar documentElement = document.documentElement;\n\n\n\nvar isAttached = function(){\n    var isAttached = function isAttached(node) {\n        if (node === window) {\n            return true;\n        }\n        if (node.nodeType == 3) {\n            if (node.parentElement) {\n                return isAttached(node.parentElement);\n            }\n            else {\n                return true;\n            }\n        }\n        return node === documentElement ? true : documentElement.contains(node);\n    };\n    return isAttached;\n}();\n\n\n\n\nvar data = function(){\n\n    var dataCache   = {},\n\n        getNodeId   = function(el) {\n            return el._mjsid || (el._mjsid = nextUid());\n        };\n\n    /**\n     * @param {Element} el\n     * @param {String} key\n     * @param {*} value optional\n     */\n    return function data(el, key, value) {\n        var id  = getNodeId(el),\n            obj = dataCache[id];\n\n        if (value !== undf) {\n            if (!obj) {\n                obj = dataCache[id] = {};\n            }\n            obj[key] = value;\n            return value;\n        }\n        else {\n            return obj ? obj[key] : undf;\n        }\n    };\n\n}();\n\n\n\nfunction toFragment(nodes) {\n\n    var fragment = document.createDocumentFragment();\n\n    if (isString(nodes)) {\n        var tmp = document.createElement('div');\n        tmp.innerHTML = nodes;\n        nodes = tmp.childNodes;\n    }\n\n    if (nodes.nodeType) {\n        fragment.appendChild(nodes);\n    }\n    else {\n        for(var i =- 1, l = nodes.length>>>0; ++i !== l; fragment.appendChild(nodes[0])){}\n    }\n\n    return fragment;\n};\n\n\n\n/**\n * @param {[]|Element} node\n * @returns {[]|Element}\n */\nvar clone = function clone(node) {\n\n    var i, len, cloned;\n\n    if (isArray(node)) {\n        cloned = [];\n        for (i = 0, len = node.length; i < len; i++) {\n            cloned.push(clone(node[i]));\n        }\n        return cloned;\n    }\n    else if (node) {\n        switch (node.nodeType) {\n            // element\n            case 1:\n                return node.cloneNode(true);\n            // text node\n            case 3:\n                return document.createTextNode(node.innerText || node.textContent);\n            // document fragment\n            case 11:\n                return node.cloneNode(true);\n\n            default:\n                return null;\n        }\n    }\n\n    return null;\n};\n\n\n\n\n\nvar shadowRootSupported = !!documentElement.createShadowRoot;\n\n\n\n\n\n\n\nvar Template = function(){\n\n    var observable      = new Observable,\n\n        tplCache        = {},\n\n        getTemplate     = function(tplId) {\n\n            if (!tplCache[tplId]) {\n                var tplNode     = document.getElementById(tplId),\n                    tag;\n\n                if (tplNode) {\n\n                    tag         = tplNode.tagName.toLowerCase();\n\n                    if (tag == \"script\") {\n                        var div = document.createElement(\"div\");\n                        div.innerHTML = tplNode.innerHTML;\n                        tplCache[tplId] = toFragment(div.childNodes);\n                    }\n                    else {\n                        if (\"content\" in tplNode) {\n                            tplCache[tplId] = tplNode.content;\n                        }\n                        else {\n                            tplCache[tplId] = toFragment(tplNode.childNodes);\n                        }\n                    }\n                }\n            }\n\n            return tplCache[tplId];\n        },\n\n        loadTemplate = function(tplUrl) {\n            if (!tplCache[tplUrl]) {\n                return tplCache[tplUrl] = ajax(tplUrl, {dataType: 'fragment'})\n                    .then(function(fragment){\n                        tplCache[tplUrl] = fragment;\n                        return fragment;\n                    });\n            }\n            return tplCache[tplUrl];\n        },\n\n        isExpression = function(str) {\n            if (str.substr(0,1) == '.') {\n                var second = str.substr(1,1);\n                return !(second == '.' || second == '/');\n            }\n            return false;\n        };\n\n\n    return defineClass({\n\n        $class:             \"Template\",\n\n        _watcher:           null,\n        _tpl:               null,\n        _renderer:          null,\n        _initial:           true,\n        _fragment:          null,\n        _id:                null,\n        _originalNode:      null,\n        _intendedShadow:    false,\n\n        scope:              null,\n        node:               null,\n        tpl:                null,\n        url:                null,\n        ownRenderer:        false,\n        initPromise:        null,\n        parentRenderer:     null,\n        deferRendering:     false,\n        replace:            false,\n        shadow:             false,\n\n        $init: function(cfg) {\n\n            var self    = this;\n\n            extend(self, cfg, true, false);\n\n            if (!shadowRootSupported) {\n                self._intendedShadow = self.shadow;\n                self.shadow = false;\n            }\n\n            self.id     = nextUid();\n\n            self.tpl && (self.tpl = trim(self.tpl));\n            self.url && (self.url = trim(self.url));\n\n            var node    = self.node,\n                tpl     = self.tpl || self.url;\n\n            node && removeAttr(node, \"mjs-include\");\n\n            if (self.shadow) {\n                self._originalNode = node;\n                self.node = node = node.createShadowRoot();\n            }\n\n            if (!node) {\n                self.deferRendering = true;\n            }\n\n            if (tpl) {\n\n                if (node && node.firstChild && !self.shadow) {\n                    data(node, \"mjs-transclude\", toFragment(node.childNodes));\n                }\n\n                if (isExpression(tpl) && !self.replace) {\n                    self.ownRenderer        = true;\n                    self._watcher           = createWatchable(self.scope, tpl, self.onChange, self, null, ns);\n                }\n                else if (self.shadow) {\n                    self.ownRenderer        = true;\n                }\n                else if (self.replace) {\n                    self.ownRenderer        = false;\n                }\n\n                self.initPromise = self.resolveTemplate();\n\n                if (!self.deferRendering || !self.ownRenderer) {\n                    self.initPromise.done(self.applyTemplate, self);\n                }\n\n                if (self.ownRenderer && self.parentRenderer) {\n                    self.parentRenderer.on(\"destroy\", self.onParentRendererDestroy, self);\n                }\n            }\n            else {\n                if (!self.deferRendering && self.ownRenderer) {\n                    self.doRender();\n                }\n            }\n\n            if (self.scope instanceof Scope) {\n                self.scope.$on(\"destroy\", self.onScopeDestroy, self);\n            }\n        },\n\n\n        doRender: function() {\n            var self = this;\n            if (!self._renderer) {\n                self._renderer   = new Renderer(self.node, self.scope);\n                self._renderer.on(\"rendered\", self.onRendered, self);\n                self._renderer.process();\n            }\n        },\n\n        onRendered: function() {\n            observable.trigger(\"rendered-\" + this.id, this);\n        },\n\n        on: function(event, fn, context) {\n            return observable.on(event + \"-\" + this.id, fn, context);\n        },\n\n        un: function(event, fn, context) {\n            return observable.un(event + \"-\" + this.id, fn, context);\n        },\n\n        startRendering: function() {\n\n            var self    = this,\n                tpl     = self.tpl || self.url;\n\n            if (self.deferRendering && self.node) {\n\n                self.deferRendering = false;\n                if (self.initPromise) {\n                    self.initPromise.done(tpl ? self.applyTemplate : self.doRender, self);\n                    return self.initPromise;\n                }\n                else {\n                    tpl ? self.applyTemplate() : self.doRender();\n                }\n            }\n\n            return null;\n        },\n\n        resolveTemplate: function() {\n\n            var self    = this,\n                url     = self.url,\n                tpl     = self._watcher ?\n                          self._watcher.getLastResult() :\n                          (self.tpl || url);\n\n            var returnPromise = new Promise;\n\n            new Promise(function(resolve){\n                if (url) {\n                    resolve(getTemplate(tpl) || loadTemplate(url));\n                }\n                else {\n                    resolve(getTemplate(tpl) || toFragment(tpl));\n                }\n            })\n                .done(function(fragment){\n                    self._fragment = fragment;\n                    returnPromise.resolve(!self.ownRenderer ? self.node : false);\n                })\n                .fail(returnPromise.reject, returnPromise);\n\n            return returnPromise;\n        },\n\n        onChange: function() {\n\n            var self    = this;\n\n            if (self._renderer) {\n                self._renderer.$destroy();\n                self._renderer = null;\n            }\n\n            self.resolveTemplate()\n                .done(self.applyTemplate, self);\n        },\n\n        doApplyTemplate: function() {\n\n            var self    = this,\n                el      = self.node;\n\n            while (el.firstChild) {\n                el.removeChild(el.firstChild);\n            }\n\n            if (self._intendedShadow) {\n                self.makeTranscludes();\n            }\n\n            if (self.replace) {\n                el.parentNode.replaceChild(clone(self._fragment), el);\n            }\n            else {\n                el.appendChild(clone(self._fragment));\n            }\n\n            if (self.ownRenderer) {\n                self.doRender();\n            }\n        },\n\n        applyTemplate: function() {\n\n            var self        = this,\n                el          = self.node,\n                deferred    = new Promise;\n\n            if (!self._initial) {\n                animate(el, \"leave\", null, true)\n                    .done(self.doApplyTemplate, self)\n                    .done(deferred.resolve, deferred);\n                animate(el, \"enter\", null, true);\n            }\n            else {\n                self.doApplyTemplate();\n                deferred.resolve();\n            }\n\n            self._initial = false;\n\n            return deferred;\n        },\n\n        makeTranscludes: function() {\n\n            var self    = this,\n                fr      = self._fragment,\n                cnts    = select(\"content\", fr),\n                el, next,\n                tr, sel,\n                i, l;\n\n            for (i = 0, l = cnts.length; i < l;  i++) {\n\n                tr      = document.createElement(\"mjs-transclude\");\n                el      = cnts[i];\n                next    = el.nextSibling;\n                sel     = getAttr(el, \"select\");\n\n                sel && setAttr(tr, \"select\", sel);\n\n                fr.removeChild(el);\n                fr.insertBefore(tr, next);\n            }\n        },\n\n        onParentRendererDestroy: function() {\n            this._renderer.$destroy();\n            this.$destroy();\n        },\n\n        onScopeDestroy: function() {\n            this.$destroy();\n        },\n\n        destroy: function() {\n\n            var self = this;\n\n            if (self.shadow) {\n                self._originalNode.createShadowRoot();\n            }\n\n            if (self._watcher) {\n                self._watcher.unsubscribeAndDestroy(self.onChange, self);\n            }\n        }\n\n    }, {\n        getTemplate: getTemplate,\n        loadTemplate: loadTemplate\n    });\n}();\n\n\n\n\n\n\n\n/**\n * @namespace MetaphorJs\n * @class Component\n */\nvar Component = defineClass({\n\n    $class: \"MetaphorJs.Component\",\n    $mixins: [ObservableMixin],\n\n    /**\n     * @access protected\n     * @var string\n     */\n    id:             null,\n\n    originalId:     false,\n\n    /**\n     * @var Element\n     * @access protected\n     */\n    node:           null,\n\n    /**\n     * @var string|Element\n     * @access protected\n     */\n    renderTo:       null,\n\n    /**\n     * @var {boolean}\n     */\n    autoRender:     true,\n\n    /**\n     * @var bool\n     * @access protected\n     */\n    rendered:       false,\n\n    /**\n     * @var bool\n     * @access protected\n     */\n    hidden:         false,\n\n    /**\n     * @var bool\n     * @access protected\n     */\n    destroyEl:      true,\n\n    destroyScope:   false,\n\n    /**\n     * @var {MetaphorJs.view.Scope}\n     */\n    scope:          null,\n\n    /**\n     * @var {MetaphorJs.view.Template}\n     */\n    template:       null,\n\n    templateUrl:    null,\n\n    /**\n     * @var string\n     */\n    tag:            null,\n\n\n    /**\n     * @constructor\n     * @param {object} cfg {\n     *      @type string id Element id\n     *      @type string|Element el\n     *      @type string|Element renderTo\n     *      @type bool hidden\n     *      @type bool destroyEl\n     * }\n     */\n    $init: function(cfg) {\n\n        var self    = this;\n\n        self.$super(cfg);\n\n        extend(self, cfg, true, false);\n\n        if (!self.scope) {\n            self.scope = new Scope;\n        }\n\n        if (cfg.as) {\n            self.scope[cfg.as] = self;\n        }\n\n        if (self.node) {\n            self.id = getAttr(self.node, \"id\");\n            if (self.id) {\n                self.originalId = true;\n            }\n        }\n\n        self.id = self.id || \"cmp-\" + nextUid();\n\n        if (!self.node) {\n            self._createNode();\n        }\n\n        self.initComponent.apply(self, arguments);\n\n        if (self.scope.$app){\n            self.scope.$app.registerCmp(self, self.scope, \"id\");\n        }\n\n        var tpl = self.template,\n            url = self.templateUrl;\n\n        if (!tpl || !(tpl instanceof Template)) {\n            self.template = tpl = new Template({\n                scope: self.scope,\n                node: self.node,\n                deferRendering: !tpl,\n                ownRenderer: true,\n                tpl: tpl,\n                url: url,\n                shadow: self.constructor.$shadow\n            });\n        }\n        else if (tpl instanceof Template) {\n            // it may have just been created\n            self.template.node = self.node;\n        }\n\n        if (self.parentRenderer) {\n            self.parentRenderer.on(\"destroy\", self.onParentRendererDestroy, self);\n        }\n\n        self._initElement();\n\n        if (self.autoRender) {\n\n            if (tpl.initPromise) {\n                tpl.initPromise.done(self.render, self);\n            }\n            else {\n                self.render();\n            }\n        }\n    },\n\n    _createNode: function() {\n\n        var self    = this;\n        self.node   = document.createElement(self.tag || 'div');\n    },\n\n    _initElement: function() {\n\n        var self    = this,\n            node    = self.node;\n\n        setAttr(node, \"id\", self.id);\n        setAttr(node, \"cmp-id\", self.id);\n\n        if (self.hidden) {\n            node.style.display = \"none\";\n        }\n    },\n\n    render: function() {\n\n        var self        = this;\n\n        if (self.rendered) {\n            return;\n        }\n\n        self.trigger('render', self);\n\n        self.template.on(\"rendered\", self.onRenderingFinished, self);\n        self.template.startRendering();\n    },\n\n    onRenderingFinished: function() {\n        var self = this;\n\n        if (self.renderTo) {\n            self.renderTo.appendChild(self.node);\n        }\n        else if (!isAttached(self.node)) {\n            document.body.appendChild(self.node);\n        }\n\n        self.rendered   = true;\n        self.afterRender();\n        self.trigger('afterrender', self);\n    },\n\n\n    /**\n     * @access public\n     * @method\n     */\n    show: function() {\n        var self    = this;\n        if (!self.hidden) {\n            return;\n        }\n        if (self.trigger('beforeshow', self) === false) {\n            return false;\n        }\n\n        self.node.style.display = \"block\";\n\n        self.hidden = false;\n        self.onShow();\n        self.trigger(\"show\", self);\n    },\n\n    /**\n     * @access public\n     * @method\n     */\n    hide: function() {\n        var self    = this;\n        if (self.hidden) {\n            return;\n        }\n        if (self.trigger('beforehide', self) === false) {\n            return false;\n        }\n\n        self.node.style.display = \"none\";\n\n        self.hidden = true;\n        self.onHide();\n        self.trigger(\"hide\", self);\n    },\n\n    /**\n     * @access public\n     * @return bool\n     */\n    isHidden: function() {\n        return this.hidden;\n    },\n\n    /**\n     * @access public\n     * @return bool\n     */\n    isRendered: function() {\n        return this.rendered;\n    },\n\n    /**\n     * @access public\n     * @return bool\n     */\n    isDestroyed: function() {\n        return this.destroyed;\n    },\n\n    /**\n     * @access public\n     * @return Element\n     */\n    getEl: function() {\n        return this.node;\n    },\n\n    /**\n     * @method\n     * @access protected\n     */\n    initComponent:  emptyFn,\n\n    /**\n     * @method\n     * @access protected\n     */\n    afterRender:    emptyFn,\n\n    /**\n     * @method\n     * @access protected\n     */\n    onShow:         emptyFn,\n\n    /**\n     * @method\n     * @access protected\n     */\n    onHide:         emptyFn,\n\n    onParentRendererDestroy: function() {\n        this.$destroy();\n    },\n\n    destroy:      function() {\n\n        var self    = this;\n\n        if (self.template) {\n            self.template.$destroy();\n        }\n\n        if (self.destroyEl) {\n            if (isAttached(self.node)) {\n                self.node.parentNode.removeChild(self.node);\n            }\n        }\n        else {\n            removeAttr(self.node, \"cmp-id\");\n            if (!self.originalId) {\n                removeAttr(self.node, \"id\");\n            }\n        }\n\n        if (self.destroyScope && self.scope) {\n            self.scope.$destroy();\n        }\n\n        self.$super();\n    }\n\n});\n\n/**\n * @md-end-class\n */\n\n\n/**\n * @param {String} expr\n */\nvar getRegExp = function(){\n\n    var cache = {};\n\n    return function getRegExp(expr) {\n        return cache[expr] || (cache[expr] = new RegExp(expr));\n    };\n}();\n\n\n\n/**\n * @param {String} cls\n * @returns {RegExp}\n */\nfunction getClsReg(cls) {\n    return getRegExp('(?:^|\\\\s)'+cls+'(?!\\\\S)');\n};\n\n\n\n/**\n * @param {Element} el\n * @param {String} cls\n */\nfunction removeClass(el, cls) {\n    if (cls) {\n        el.className = el.className.replace(getClsReg(cls), '');\n    }\n};\n\n\n\nvar stopAnimation = function(el) {\n\n    var queue = data(el, \"mjsAnimationQueue\"),\n        current,\n        position,\n        stages;\n\n    if (isArray(queue) && queue.length) {\n        current = queue[0];\n\n        if (current) {\n            if (current.stages) {\n                position = current.position;\n                stages = current.stages;\n                removeClass(el, stages[position]);\n                removeClass(el, stages[position] + \"-active\");\n            }\n            if (current.deferred) {\n                current.deferred.reject(current.el);\n            }\n        }\n    }\n    else if (isFunction(queue)) {\n        queue(el);\n    }\n    else if (queue == \"stop\") {\n        $(el).stop(true, true);\n    }\n\n    data(el, \"mjsAnimationQueue\", null);\n};\n\n/**\n * @param {Function} fn\n * @param {Object} context\n * @param {[]} args\n * @param {number} timeout\n */\nfunction async(fn, context, args, timeout) {\n    setTimeout(function(){\n        fn.apply(context, args || []);\n    }, timeout || 0);\n};\n\n\n\nfunction isNumber(value) {\n    return varType(value) === 1;\n};\n\nvar strUndef = \"undefined\";\n\n\n\nfunction error(e) {\n\n    var stack = e.stack || (new Error).stack;\n\n    if (typeof console != strUndef && console.log) {\n        async(function(){\n            console.log(e);\n            if (stack) {\n                console.log(stack);\n            }\n        });\n    }\n    else {\n        throw e;\n    }\n};\n\n\n\n\n\nvar Queue = function(cfg) {\n\n    var self = this;\n\n    cfg = cfg || {};\n\n    self._queue = [];\n    self._map = {};\n    self.id = \"$$\" + nextUid();\n\n    for (var i in cfg) {\n        self[i] = cfg[i];\n    }\n};\n\n\nQueue.REPLACE = 1;\nQueue.ONCE = 2;\nQueue.MULTIPLE = 3;\nQueue.ONCE_EVER = 3;\n\n\nextend(Queue.prototype, {\n\n    _queue: null,\n    _map: null,\n    _nextRequested: false,\n    _running: false,\n\n    length: 0,\n    id: null,\n    async: true,\n    auto: true,\n    thenable: false,\n    stack: false,\n    context: null,\n    mode: Queue.MULTIPLE,\n\n    add: function(fn, context, args, mode, prepend, async) {\n\n        var self    = this,\n            qid     = self.id,\n            id      = fn[qid] || nextUid(),\n            item    = {\n                id: id,\n                fn: fn,\n                context: context,\n                args: args,\n                async: async\n            };\n\n        mode = mode || self.mode;\n\n        if (mode == Queue.ONCE_EVER && fn[qid]) {\n            return fn[qid];\n        }\n\n        fn[qid] = id;\n\n        if (self._map[id]) {\n            if (mode == Queue.REPLACE) {\n                self.remove(id);\n            }\n            else if (mode == Queue.ONCE) {\n                return id;\n            }\n        }\n\n        self._queue[prepend ? \"unshift\" : \"push\"](item);\n        self._map[id] = item;\n\n        self.length = self._queue.length;\n\n        if (self.auto) {\n            self.next();\n        }\n\n        return id;\n    },\n\n    append: function(fn, context, args, mode, async) {\n        return this.add(fn, context, args, mode, false, async);\n    },\n\n    prepend: function(fn, context, args, mode, async) {\n        return this.add(fn, context, args, mode, true, async);\n    },\n\n    remove: function(id) {\n        var self = this,\n            queue = self._queue,\n            i, l;\n\n        for (i = 0, l = queue.length; i < l; i++) {\n            if (queue[i].id == id) {\n                queue.splice(i, 1);\n                break;\n            }\n        }\n        delete self._map[id];\n    },\n\n    next: function() {\n\n        var self    = this,\n            item;\n\n        if (self._running) {\n            self._nextRequested = true;\n            return;\n        }\n\n        self._nextRequested = false;\n\n        item = self._queue[self.stack ? \"pop\" : \"shift\"]();\n        self.length = self._queue.length;\n\n        if (!item) {\n            return;\n        }\n\n        self._running = true;\n\n        delete self._map[item.id];\n\n        if (!self.async && !item.async) {\n            try {\n                self._processResult(item.fn.apply(item.context || self.context, item.args || []));\n            }\n            catch (thrown) {\n                error(thrown);\n                self._finish();\n                throw thrown;\n            }\n        }\n        else {\n            var timeout = 0;\n            if (isNumber(item.async)) {\n                timeout = item.async;\n            }\n            else if (isNumber(self.async)) {\n                timeout = self.async;\n            }\n            async(function(){\n                try {\n                    self._processResult(item.fn.apply(item.context || self.context, item.args || []));\n                }\n                catch (thrown) {\n                    error(thrown);\n                    self._finish();\n                    throw thrown;\n                }\n            }, null, null, timeout);\n        }\n    },\n\n    _processResult: function(res) {\n        var self = this;\n        if (self.thenable && isThenable(res)) {\n            res.then(function(){self._finish()}, function(){self._finish()});\n        }\n        else {\n            self._finish();\n        }\n        return res;\n    },\n\n    _finish: function() {\n        var self = this;\n        self._running = false;\n        if (self.auto || self._nextRequested) {\n            self.next();\n        }\n    },\n\n    destroy: function() {\n\n        var self = this;\n\n        self._queue = null;\n        self._map = null;\n        self.context = null;\n        self._nextRequested = false;\n        self._running = false;\n        self.next = emptyFn;\n\n    }\n}, true, false);\n\n\n\n\n\n\nfunction isPrimitive(value) {\n    var vt = varType(value);\n    return vt < 3 && vt > -1;\n};\n\n\n\nvar raf = function() {\n\n    var raf,\n        cancel;\n\n    if (typeof window != strUndef) {\n        var w   = window;\n        raf     = w.requestAnimationFrame ||\n                    w.webkitRequestAnimationFrame ||\n                    w.mozRequestAnimationFrame;\n        cancel  = w.cancelAnimationFrame ||\n                    w.webkitCancelAnimationFrame ||\n                    w.mozCancelAnimationFrame ||\n                    w.webkitCancelRequestAnimationFrame;\n\n        if (raf) {\n            return function(fn) {\n                var id = raf(fn);\n                return function() {\n                    cancel(id);\n                };\n            };\n        }\n    }\n\n    return function(fn) {\n        var id = setTimeout(fn, 0);\n        return function() {\n            clearTimeout(id);\n        }\n    };\n}();\n\n\n\nvar functionFactory = function() {\n\n    var REG_REPLACE_EXPR    = /(^|[^a-z0-9_$])(\\.)([^0-9])/ig,\n\n        f               = Function,\n        fnBodyStart     = 'try {',\n        //getterBodyEnd   = ';} catch (thrownError) { return $$interceptor(thrownError, $$itself, ____); }',\n        //setterBodyEnd   = ';} catch (thrownError) { return $$interceptor(thrownError, $$itself, ____, $$$$); }',\n        getterBodyEnd   = ';} catch (thrownError) { return undefined; }',\n        setterBodyEnd   = ';} catch (thrownError) { return undefined; }',\n\n\n        /*interceptor     = function(thrownError, func, scope, value) {\n\n            while (scope && !scope.$isRoot) {\n\n                scope = scope.$parent;\n\n                if (scope) {\n\n                    try {\n                        if (arguments.length == 4) {\n                            return func.call(null, scope, value, emptyFn, func);\n                        }\n                        else {\n                            return func.call(null, scope, emptyFn, func);\n                        }\n                    }\n                    catch (newError) {}\n                }\n            }\n\n            if (thrownError !== null) {\n                error(thrownError);\n            }\n\n            return undf;\n        },*/\n\n        isFailed        = function(val) {\n            return val === undf || (typeof val == \"number\" && isNaN(val));\n        },\n\n        wrapFunc        = function(func, returnsValue) {\n            return function(scope) {\n                var args = slice.call(arguments),\n                    val;\n\n                //args.push(interceptor);\n                args.push(null);\n                args.push(func);\n\n                if (returnsValue) {\n                    val = func.apply(null, args);\n                    while (isFailed(val) && !scope.$isRoot) {\n                        scope = scope.$parent;\n                        args[0] = scope;\n                        val = func.apply(null, args);\n                    }\n                    return val;\n                }\n                else {\n                    return func.apply(null, args);\n                }\n\n                /*if (returnsValue && isFailed(val)) {//) {\n                    args = slice.call(arguments);\n                    args.unshift(func);\n                    args.unshift(null);\n                    return interceptor.apply(null, args);\n                }\n                else {\n                    return val;\n                }*/\n            };\n        },\n\n        getterCache     = {},\n        getterCacheCnt  = 0,\n\n        createGetter    = function createGetter(expr) {\n            try {\n                if (!getterCache[expr]) {\n                    getterCacheCnt++;\n                    return getterCache[expr] = wrapFunc(new f(\n                        '____',\n                        '$$interceptor',\n                        '$$itself',\n                        \"\".concat(fnBodyStart, 'return ', expr.replace(REG_REPLACE_EXPR, '$1____.$3'), getterBodyEnd)\n                    ), true);\n                }\n                return getterCache[expr];\n            }\n            catch (thrownError){\n                error(thrownError);\n                return emptyFn;\n            }\n        },\n\n        setterCache     = {},\n        setterCacheCnt  = 0,\n\n        createSetter    = function createSetter(expr) {\n            try {\n                if (!setterCache[expr]) {\n                    setterCacheCnt++;\n                    var code = expr.replace(REG_REPLACE_EXPR, '$1____.$3');\n                    return setterCache[expr] = wrapFunc(new f(\n                        '____',\n                        '$$$$',\n                        '$$interceptor',\n                        '$$itself',\n                        \"\".concat(fnBodyStart, code, ' = $$$$', setterBodyEnd)\n                    ));\n                }\n                return setterCache[expr];\n            }\n            catch (thrownError) {\n                error(thrownError);\n                return emptyFn;\n            }\n        },\n\n        funcCache       = {},\n        funcCacheCnt    = 0,\n\n        createFunc      = function createFunc(expr) {\n            try {\n                if (!funcCache[expr]) {\n                    funcCacheCnt++;\n                    return funcCache[expr] = wrapFunc(new f(\n                        '____',\n                        '$$interceptor',\n                        '$$itself',\n                        \"\".concat(fnBodyStart, expr.replace(REG_REPLACE_EXPR, '$1____.$3'), getterBodyEnd)\n                    ));\n                }\n                return funcCache[expr];\n            }\n            catch (thrownError) {\n                error(thrownError);\n                return emptyFn;\n            }\n        },\n\n        resetCache = function() {\n            getterCacheCnt >= 1000 && (getterCache = {});\n            setterCacheCnt >= 1000 && (setterCache = {});\n            funcCacheCnt >= 1000 && (funcCache = {});\n        };\n\n    return {\n        createGetter: createGetter,\n        createSetter: createSetter,\n        createFunc: createFunc,\n        resetCache: resetCache,\n        enableResetCacheInterval: function() {\n            setTimeout(resetCache, 10000);\n        }\n    };\n}();\n\n\n\nvar createGetter = functionFactory.createGetter;\n\nvar rToCamelCase = /-./g;\n\nfunction toCamelCase(str) {\n    return str.replace(rToCamelCase, function(match){\n        return match.charAt(1).toUpperCase();\n    });\n};\n\n\n\nvar getNodeData = function() {\n\n    var readDataSet = function(node) {\n        var attrs = node.attributes,\n            dataset = {},\n            i, l, name;\n\n        for (i = 0, l = attrs.length; i < l; i++) {\n            name = attrs[i].name;\n            if (name.indexOf(\"data-\") === 0) {\n                dataset[toCamelCase(name.substr(5))] = attrs[i].value;\n            }\n        }\n\n        return dataset;\n    };\n\n    if (document.documentElement.dataset) {\n        return function(node) {\n            return node.dataset;\n        };\n    }\n    else {\n        return function(node) {\n\n            var dataset;\n\n            if ((dataset = data(node, \"data\")) !== undf) {\n                return dataset;\n            }\n\n            dataset = readDataSet(node);\n            data(node, \"data\", dataset);\n            return dataset;\n        };\n    }\n\n}();\n\n\n\nfunction getNodeConfig(node, scope, expr) {\n\n    var cfg = data(node, \"config\"),\n        config, dataset, i, val;\n\n    if (cfg) {\n        return cfg;\n    }\n\n    cfg = {};\n\n    if (expr || (expr = getAttr(node, \"mjs-config\")) !== null) {\n        removeAttr(node, \"mjs-config\");\n        config = expr ? createGetter(expr)(scope || {}) : {};\n        for (i in config){\n            cfg[i] = config[i];\n        }\n    }\n\n    dataset = getNodeData(node);\n\n    for (i in dataset){\n        val = dataset[i];\n        cfg[i] = val === \"\" ? true : val;\n    }\n\n    data(node, \"config\", cfg);\n\n    return cfg;\n};\n\n\nvar ListRenderer = defineClass({\n\n    $class: \"ListRenderer\",\n\n    id: null,\n\n    model: null,\n    itemName: null,\n    tpl: null,\n    renderers: null,\n    parentEl: null,\n    prevEl: null,\n    nextEl: null,\n    trackBy: null,\n    trackByWatcher: null,\n    animateMove: false,\n    animate: false,\n    trackByFn: null,\n    griDelegate: null,\n\n    queue: null,\n\n    buffered: false,\n    bufferPlugin: null,\n\n    $constructor: function(scope, node, expr) {\n\n        var self    = this,\n            cfg     = getNodeConfig(node, scope);\n\n        self.animateMove    = !cfg.buffered && cfg.animateMove && animate.cssAnimations;\n        self.animate        = !cfg.buffered && (getAttr(node, \"mjs-animate\") !== null || cfg.animate);\n        self.id             = cfg.id || nextUid();\n\n        removeAttr(node, \"mjs-animate\");\n\n        if (self.animate && self.animateMove) {\n            self.$plugins.push(\"ListAnimatedMove\");\n        }\n        if (cfg.observable) {\n            self.$plugins.push(\"Observable\");\n        }\n\n        if (cfg.buffered) {\n            self.buffered = true;\n            self.$plugins.push(\"ListBuffered\");\n        }\n    },\n\n    $init: function(scope, node, expr) {\n\n        var self = this;\n\n        removeAttr(node, \"mjs-include\");\n\n        self.parseExpr(expr);\n\n        self.tpl        = node;\n        self.renderers  = [];\n        self.prevEl     = node.previousSibling;\n        self.nextEl     = node.nextSibling;\n        self.parentEl   = node.parentNode;\n        self.node       = node;\n        self.scope      = scope;\n\n        self.queue      = new Queue({\n            async: false, auto: true, thenable: true,\n            stack: false, context: self, mode: Queue.ONCE\n        });\n\n        self.parentEl.removeChild(node);\n\n        self.afterInit(scope, node);\n\n        self.queue.add(self.render, self, [toArray(self.watcher.getLastResult())]);\n    },\n\n    afterInit: function(scope, node) {\n\n        var self        = this,\n            cfg         = getNodeConfig(node, scope);\n\n        self.watcher    = createWatchable(scope, self.model, self.onChange, self, null, ns);\n        self.trackBy    = cfg.trackBy;\n        if (self.trackBy && self.trackBy != '$') {\n            self.trackByWatcher = createWatchable(scope, self.trackBy, self.onChangeTrackBy, self, null, ns);\n        }\n        else if (self.trackBy != '$' && !self.watcher.hasInputPipes()) {\n            self.trackBy    = '$$'+self.watcher.id;\n        }\n\n        self.griDelegate = bind(self.scopeGetRawIndex, self);\n    },\n\n    trigger: emptyFn,\n\n    /*\n     * <!-- render and re-render\n     */\n\n    render: function(list) {\n\n        var self        = this,\n            renderers   = self.renderers,\n            tpl         = self.tpl,\n            parent      = self.parentEl,\n            next        = self.nextEl,\n            buffered    = self.buffered,\n            fragment    = document.createDocumentFragment(),\n            el,\n            i, len;\n\n        for (i = 0, len = list.length; i < len; i++) {\n            el = tpl.cloneNode(true);\n            renderers.push(self.createItem(el, list, i));\n            if (!buffered) {\n                fragment.appendChild(el);\n                renderers[i].attached = true;\n            }\n        }\n\n        if (!buffered) {\n            self.doUpdate();\n            parent.insertBefore(fragment, next);\n        }\n        else {\n            self.bufferPlugin.getScrollOffset();\n            self.bufferPlugin.updateScrollBuffer();\n        }\n\n        self.trigger(\"render\", self);\n    },\n\n    doUpdate: function(start, end, action, renderOnly) {\n\n        var self        = this,\n            renderers   = self.renderers,\n            index       = start || 0,\n            cnt         = renderers.length,\n            x           = end || cnt - 1,\n            list        = self.watcher.getLastResult(),\n            trackByFn   = self.getTrackByFunction();\n\n        if (x > cnt - 1) {\n            x = cnt - 1;\n        }\n\n        for (; index <= x; index++) {\n\n            if (action && renderers[index].action != action) {\n                continue;\n            }\n\n            self.renderItem(index, renderers, list, trackByFn, renderOnly);\n        }\n    },\n\n    renderItem: function(index, rs, list, trackByFn, renderOnly) {\n\n        var self = this;\n\n        list = list || self.watcher.getLastResult();\n        rs = rs || self.renderers;\n        trackByFn = trackByFn || self.getTrackByFunction();\n\n        var item        = rs[index],\n            scope       = item.scope,\n            last        = rs.length - 1,\n            even        = !(index % 2);\n\n        if (renderOnly && item.rendered) {\n            return;\n        }\n\n        scope.$index    = index;\n        scope.$first    = index === 0;\n        scope.$last     = index === last;\n        scope.$even     = even;\n        scope.$odd      = !even;\n        scope.$trackId  = trackByFn(list[index]);\n        scope.$getRawIndex = self.griDelegate;\n\n        if (!item.renderer) {\n\n            item.renderer  = new Renderer(item.el, scope);\n            item.renderer.process();\n            item.rendered = true;\n        }\n        else {\n            scope.$check();\n        }\n    },\n\n\n    createItem: function(el, list, index) {\n\n        var self        = this,\n            iname       = self.itemName,\n            itemScope   = self.scope.$new();\n\n        itemScope[iname]    = self.getListItem(list, index);\n\n        return {\n            index: index,\n            action: \"enter\",\n            el: el,\n            scope: itemScope,\n            attached: false,\n            rendered: false\n        };\n    },\n\n    /*\n     * render and re-render -->\n     */\n\n    /*\n     * <!-- reflect changes\n     */\n\n    onChange: function(current, prev) {\n        var self = this;\n        self.queue.prepend(self.applyChanges, self, [prev], Queue.REPLACE);\n    },\n\n    applyChanges: function(prevList) {\n\n        var self        = this,\n            renderers   = self.renderers,\n            tpl         = self.tpl,\n            index       = 0,\n            list        = toArray(self.watcher.getLastResult()),\n            updateStart = null,\n            animateMove = self.animateMove,\n            animateAll  = self.animate,\n            newrs       = [],\n            iname       = self.itemName,\n            origrs      = renderers.slice(),\n            doesMove    = false,\n            prevr,\n            prevrInx,\n            i, len,\n            r,\n            action,\n            translates,\n            prs         = self.watcher.getMovePrescription(prevList, self.getTrackByFunction(), list);\n\n\n        // redefine renderers\n        for (i = 0, len = prs.length; i < len; i++) {\n\n            action = prs[i];\n\n            if (isNumber(action)) {\n                prevrInx    = action;\n                prevr       = renderers[prevrInx];\n\n                if (prevrInx != index && isNull(updateStart)) {\n                    updateStart = i;\n                }\n\n                prevr.action = \"move\";\n                prevr.scope[iname] = self.getListItem(list, i);\n                doesMove = animateMove;\n\n                newrs.push(prevr);\n                renderers[prevrInx] = null;\n                index++;\n            }\n            else {\n                if (isNull(updateStart)) {\n                    updateStart = i;\n                }\n                r = self.createItem(tpl.cloneNode(true), list, i);\n                newrs.push(r);\n                // add new elements to old renderers\n                // so that we could correctly determine positions\n            }\n        }\n\n        self.renderers  = newrs;\n\n\n        if (animateAll) {\n\n            self.doUpdate(updateStart, null, \"enter\");\n\n            if (doesMove) {\n                translates = self.calculateTranslates(newrs, origrs, renderers);\n            }\n\n            var animPromises    = [],\n                startAnimation  = new Promise,\n                applyFrom       = new Promise,\n                donePromise     = new Promise,\n                animReady       = Promise.counter(newrs.length),\n                startCallback   = function(){\n                    animReady.countdown();\n                    return startAnimation;\n                };\n\n            // destroy old renderers and remove old elements\n            for (i = 0, len = renderers.length; i < len; i++) {\n                r = renderers[i];\n                if (r) {\n                    r.scope.$destroy();\n\n                    stopAnimation(r.el);\n                    animPromises.push(animate(r.el, \"leave\", null, false, ns)\n                        .done(function(el){\n                            el.style.visibility = \"hidden\";\n                        }));\n                }\n            }\n\n            for (i = 0, len = newrs.length; i < len; i++) {\n                r = newrs[i];\n                stopAnimation(r.el);\n\n                r.action == \"enter\" ?\n                animPromises.push(animate(r.el, \"enter\", startCallback, false, ns)) :\n                animPromises.push(\n                    self.moveAnimation(\n                        r.el,\n                        doesMove ? translates[i][0] : null,\n                        doesMove ? translates[i][1] : null,\n                        startCallback,\n                        applyFrom\n                    )\n                );\n            }\n\n            animReady.done(function(){\n                raf(function(){\n                    applyFrom.resolve();\n                    self.applyDomPositions(renderers);\n                    if (!doesMove) {\n                        self.doUpdate(updateStart, null, \"move\");\n                    }\n                    raf(function(){\n                        startAnimation.resolve();\n                    });\n                    self.trigger(\"change\", self);\n                });\n            });\n\n            Promise.all(animPromises).always(function(){\n                raf(function(){\n                    self.doUpdate(updateStart || 0);\n                    self.removeOldElements(renderers);\n                    if (doesMove) {\n                        self.doUpdate(updateStart, null, \"move\");\n                        for (i = 0, len = newrs.length; i < len; i++) {\n                            r = newrs[i];\n                            r.el.style[animate.prefixes.transform] = null;\n                            r.el.style[animate.prefixes.transform] = \"\";\n                        }\n                    }\n                    donePromise.resolve();\n                });\n            });\n\n            return donePromise;\n        }\n        else {\n            if (!self.buffered) {\n                self.applyDomPositions();\n                self.doUpdate(updateStart || 0);\n                self.removeOldElements(renderers);\n            }\n            else {\n                self.bufferPlugin.getScrollOffset();\n                self.removeOldElements(renderers);\n                self.queue.append(self.bufferPlugin.updateScrollBuffer, self.bufferPlugin, [true]);\n            }\n            self.trigger(\"change\", self);\n        }\n    },\n\n\n    removeOldElements: function(rs) {\n        var i, len, r,\n            parent = this.parentEl;\n\n        for (i = 0, len = rs.length; i < len; i++) {\n            r = rs[i];\n            if (r && r.attached) {\n                r.attached = false;\n                parent.removeChild(r.el);\n            }\n        }\n    },\n\n\n    applyDomPositions: function(oldrs) {\n\n        var self        = this,\n            rs          = self.renderers,\n            parent      = self.parentEl,\n            prevEl      = self.prevEl,\n            fc          = prevEl ? prevEl.nextSibling : parent.firstChild,\n            next,\n            i, l, el, r;\n\n        for (i = 0, l = rs.length; i < l; i++) {\n            r = rs[i];\n            el = r.el;\n\n            if (oldrs && oldrs[i]) {\n                next = oldrs[i].el.nextSibling;\n            }\n            else {\n                next = i > 0 ? (rs[i-1].el.nextSibling || fc) : fc;\n            }\n\n            if (next && el.nextSibling !== next) {\n                parent.insertBefore(el, next);\n            }\n            else if (!next) {\n                parent.appendChild(el);\n            }\n            r.attached = true;\n\n        }\n    },\n\n    /*\n     * reflect changes -->\n     */\n\n\n    /*\n     * <!-- configurable item functions\n     */\n\n\n    getListItem: function(list, index) {\n        return list[index];\n    },\n\n    onChangeTrackBy: function(val) {\n        this.trackByFn = null;\n        this.trackBy = val;\n    },\n\n    getTrackByFunction: function() {\n\n        var self = this,\n            trackBy;\n\n        if (!self.trackByFn) {\n\n            trackBy = self.trackBy;\n\n            if (!trackBy || trackBy == '$') {\n                self.trackByFn = function(item) {\n                    return isPrimitive(item) ? item : undf;\n                };\n            }\n            else if (isFunction(trackBy)) {\n                self.trackByFn = trackBy;\n            }\n            else {\n                self.trackByFn = function(item){\n                    return item && !isPrimitive(item) ? item[trackBy] : undf;\n                };\n            }\n        }\n\n        return self.trackByFn;\n    },\n\n\n    scopeGetRawIndex: function(id) {\n\n        if (id === undf) {\n            return -1;\n        }\n\n        var self        = this,\n            list        = self.watcher.getUnfilteredValue(),\n            trackByFn   = self.getTrackByFunction(),\n            i, l;\n\n        for (i = 0, l = list.length; i < l; i++) {\n            if (trackByFn(list[i]) === id) {\n                return i;\n            }\n        }\n\n        return -1;\n    },\n\n    /*\n     * configurable item functions -->\n     */\n\n\n    /*\n     * <!-- move animation - plugin.ListAnimatedMove\n     */\n\n    getNodePositions: function(tmp, rs, oldrs) {\n        return {};\n    },\n\n    calculateTranslates: function(newRenderers, origRenderers, withDeletes) {\n        return [];\n    },\n\n    moveAnimation: function(el, to, from, startCallback, applyFrom) {\n        return animate(el, \"move\", startCallback, false, ns);\n    },\n\n    /*\n     * move animation -->\n     */\n\n\n    /*\n     * <!-- buffered list\n     */\n\n\n    scrollTo: function() {\n        // not implemented\n    },\n\n\n    /*\n     * buffered list -->\n     */\n\n\n    parseExpr: function(expr) {\n\n        var tmp = expr.split(\" \"),\n            i, len,\n            model, name,\n            row;\n\n        for (i = 0, len = tmp.length; i < len; i++) {\n\n            row = tmp[i];\n\n            if (row == \"\" || row == \"in\") {\n                continue;\n            }\n\n            if (!name) {\n                name = row;\n            }\n            else {\n                model = tmp.slice(i).join(\" \");\n                break;\n            }\n        }\n\n        this.model = model;\n        this.itemName = name || \"item\";\n    },\n\n\n    destroy: function() {\n\n        var self        = this,\n            renderers   = self.renderers,\n            i, len;\n\n        for (i = 0, len = renderers.length; i < len; i++) {\n            renderers[i].renderer.$destroy();\n        }\n\n        if (self.trackByWatcher) {\n            self.trackByWatcher.unsubscribeAndDestroy();\n        }\n\n        self.queue.destroy();\n        self.watcher.unsubscribeAndDestroy(self.onChange, self);\n    }\n\n}, {\n    $stopRenderer: true,\n    $registerBy: \"id\"\n});\n\n\n\n\n/**\n * @param {Element} el\n * @param {String} cls\n * @returns {boolean}\n */\nfunction hasClass(el, cls) {\n    return cls ? getClsReg(cls).test(el.className) : false;\n};\n\n\n\n/**\n * @param {Element} el\n * @param {String} cls\n */\nfunction addClass(el, cls) {\n    if (cls && !hasClass(el, cls)) {\n        el.className += \" \" + cls;\n    }\n};\n\n\n\n\nfunction resolveComponent(cmp, cfg, scope, node, args) {\n\n    var hasCfg  = cfg !== false;\n\n    cfg         = cfg || {};\n    args        = args || [];\n\n    scope       = scope || cfg.scope; // || new Scope;\n    node        = node || cfg.node;\n\n    cfg.scope   = cfg.scope || scope;\n    cfg.node    = cfg.node || node;\n\n    var constr      = isString(cmp) ? nsGet(cmp) : cmp;\n\n    if (!constr) {\n        throw \"Component \" + cmp + \" not found\";\n    }\n\n    if (scope && constr.$isolateScope) {\n        cfg.scope   = scope = scope.$newIsolated();\n    }\n\n    var i,\n        defers      = [],\n        tpl         = constr.template || cfg.template || null,\n        tplUrl      = constr.templateUrl || cfg.templateUrl || null,\n        app         = scope ? scope.$app : null,\n        gProvider   = Provider.global(),\n        injectFn    = app ? app.inject : gProvider.inject,\n        injectCt    = app ? app : gProvider,\n        cloak       = node ? getAttr(node, \"mjs-cloak\") : null,\n        inject      = {\n            $node: node || null,\n            $scope: scope || null,\n            $config: cfg || null,\n            $args: args || null\n        };\n\n    if (constr.resolve) {\n\n        for (i in constr.resolve) {\n            (function(name){\n                var d = new Promise,\n                    fn;\n\n                defers.push(d.done(function(value){\n                    inject[name] = value;\n                    cfg[name] = value;\n                    args.push(value);\n                }));\n\n                fn = constr.resolve[i];\n\n                if (isFunction(fn)) {\n                    d.resolve(fn(scope, node));\n                }\n                else if (isString(fn)) {\n                    d.resolve(injectFn.resolve(fn));\n                }\n                else {\n                    d.resolve(\n                        injectFn.call(\n                            injectCt, fn, null, extend({}, inject, cfg, false, false)\n                        )\n                    );\n                }\n\n            }(i));\n        }\n    }\n\n    if (hasCfg && (tpl || tplUrl)) {\n\n        cfg.template = new Template({\n            scope: scope,\n            node: node,\n            deferRendering: true,\n            ownRenderer: true,\n            shadow: constr.$shadow,\n            tpl: tpl,\n            url: tplUrl\n        });\n\n        defers.push(cfg.template.initPromise);\n\n        if (node && node.firstChild) {\n            data(node, \"mjs-transclude\", toFragment(node.childNodes));\n        }\n    }\n\n    hasCfg && args.unshift(cfg);\n\n    var p;\n\n    if (defers.length) {\n        p = new Promise;\n\n        Promise.all(defers).done(function(){\n            p.resolve(\n                injectFn.call(\n                    injectCt, constr, null, extend({}, inject, cfg, false, false), args\n                )\n            );\n        });\n    }\n    else {\n        p = Promise.resolve(\n            injectFn.call(\n                injectCt, constr, null, extend({}, inject, cfg, false, false), args\n            )\n        );\n    }\n\n    if (node && p.isPending() && cloak !== null) {\n        cloak ? addClass(node, cloak) : node.style.visibility = \"hidden\";\n        p.then(function() {\n            cloak ? removeClass(node, cloak) : node.style.visibility = \"\";\n        });\n    }\n\n    if (node) {\n        p.then(function(){\n            removeClass(node, \"mjs-cloak\");\n        });\n    }\n\n    return p;\n};\n\n\n\n\n\nvar currentUrl = history.currentUrl;\n\n\n\n\n\ndefineClass({\n\n    $class: \"View\",\n\n    /**\n     * [\n     *  {\n     *      reg: /.../,\n     *      cmp: 'Cmp.Name',\n     *      params: [name, name...], // param index in array is the same as reg match number - 1\n     *      template: '',\n     *      isolateScope: bool\n     *  }\n     * ]\n     */\n    route: null,\n    node: null,\n    scope: null,\n    cmp: null,\n    id: null,\n\n    currentComponent: null,\n    watchable: null,\n    defaultCmp: null,\n\n    $init: function(cfg)  {\n\n        var self    = this;\n\n        extend(self, cfg, true, false);\n\n        var node = self.node,\n            viewCfg = getNodeConfig(node, self.scope);\n\n        extend(self, viewCfg, true, false);\n\n        if (node && node.firstChild) {\n            data(node, \"mjs-transclude\", toFragment(node.childNodes));\n        }\n\n        if (!self.id) {\n            self.id = nextUid();\n        }\n\n        self.scope.$app.registerCmp(self, self.scope, \"id\");\n\n        if (self.route) {\n            history.initPushState();\n            history.on(\"locationChange\", self.onLocationChange, self);\n            self.onLocationChange();\n        }\n        else if (self.cmp) {\n            self.watchable = createWatchable(self.scope, self.cmp, self.onCmpChange, self, null, ns);\n            self.onCmpChange();\n        }\n    },\n\n    onCmpChange: function() {\n\n        var self    = this,\n            cmp     = self.watchable.getLastResult() || self.defaultCmp;\n\n        self.clearComponent();\n\n        if (cmp) {\n            self.setComponent(cmp);\n        }\n    },\n\n    onLocationChange: function() {\n\n        var self    = this,\n            url     = currentUrl(),\n            routes  = self.route,\n            def,\n            i, len,\n            r, matches;\n\n        for (i = 0, len = routes.length; i < len; i++) {\n            r = routes[i];\n\n            if (r.reg && (matches = url.match(r.reg))) {\n                self.changeRouteComponent(r, matches);\n                return;\n            }\n            if (r['default'] && !def) {\n                def = r;\n            }\n        }\n\n        self.clearComponent();\n\n        if (def) {\n            self.setRouteComponent(def, []);\n        }\n        else if (self.defaultCmp) {\n            self.setComponent(self.defaultCmp);\n        }\n    },\n\n    changeRouteComponent: function(route, matches) {\n        var self = this;\n        stopAnimation(self.node);\n        self.clearComponent();\n        self.setRouteComponent(route, matches);\n    },\n\n    clearComponent: function() {\n        var self    = this,\n            node    = self.node;\n\n        if (self.currentComponent) {\n\n            animate(node, \"leave\", null, true).done(function(){\n\n                self.currentComponent.destroy();\n                self.currentComponent = null;\n\n                while (node.firstChild) {\n                    node.removeChild(node.firstChild);\n                }\n            });\n        }\n\n    },\n\n    setRouteComponent: function(route, matches) {\n\n        var self    = this,\n            node    = self.node,\n            params  = route.params;\n\n        animate(node, \"enter\", function(){\n\n            var args    = matches || [],\n                cfg     = {\n                    destroyEl: false,\n                    node: node,\n                    scope: route.$isolateScope ?\n                           self.scope.$newIsolated() :\n                           self.scope.$new()\n                },\n                i, l;\n\n            if (route.as) {\n                cfg.as = route.as;\n            }\n            if (route.template) {\n                cfg.template = route.template;\n            }\n\n            args.shift();\n\n            if (params) {\n                for (i = -1, l = params.length; ++i < l; cfg[params[i]] = args[i]){}\n            }\n\n            return resolveComponent(\n                    route.cmp || \"MetaphorJs.Component\",\n                    cfg,\n                    cfg.scope,\n                    node,\n                    null,\n                    args\n                )\n                .done(function(newCmp){\n                    self.currentComponent = newCmp;\n                });\n\n        }, true);\n    },\n\n    setComponent: function(cmp) {\n\n        var self    = this,\n            node    = self.node;\n\n        animate(node, \"enter\", function(){\n\n            var cfg     = isObject(cmp) ? cmp : {},\n                cls     = (isString(cmp) ? cmp : null) || \"MetaphorJs.Component\",\n                scope   = cfg.scope || self.scope.$new();\n\n            cfg.destroyEl = false;\n\n            return resolveComponent(cls, cfg, scope, node).done(function(newCmp){\n                self.currentComponent = newCmp;\n            });\n\n        }, true);\n    },\n\n    destroy: function() {\n\n        var self    = this;\n\n        self.clearComponent();\n\n        if (self.route) {\n            history.un(\"locationchange\", self.onLocationChange, self);\n            self.route = null;\n        }\n\n        if (self.watchable) {\n            self.watchable.unsubscribeAndDestroy(self.onCmpChange, self);\n            self.watchable = null;\n        }\n\n        self.scope = null;\n        self.currentComponent = null;\n\n        self.$super();\n    }\n});\n\n\n\n\nfunction returnFalse() {\n    return false;\n};\n\n\n\n\n\nDirective.registerAttribute(\"mjs-app\", 100, returnFalse);\n\nfunction isField(el) {\n    var tag\t= el.nodeName.toLowerCase(),\n        type = el.type;\n    if (tag == 'input' || tag == 'textarea' || tag == 'select') {\n        if (type != \"submit\" && type != \"reset\" && type != \"button\") {\n            return true;\n        }\n    }\n    return false;\n};\n\n\nvar elemTextProp = function(){\n    var node    = document.createElement(\"div\");\n    return isString(node.textContent) ? \"textContent\" : \"innerText\";\n}();\n\n\n\n\n\nDirective.registerAttribute(\"mjs-bind\", 1000, defineClass({\n\n    $extends: Directive,\n\n    isInput: false,\n    input: null,\n    lockInput: null,\n    recursive: false,\n    textRenderer: null,\n\n    $init: function(scope, node, expr) {\n\n        var self    = this,\n            cfg     = getNodeConfig(node, scope);\n\n        self.isInput    = isField(node);\n        self.recursive  = cfg.recursive || getAttr(node, \"mjs-recursive\") !== null;\n        self.lockInput  = cfg.lockInput;\n\n        removeAttr(node, \"mjs-recursive\");\n\n        if (self.isInput) {\n            self.input  = new Input(node, self.onInputChange, self);\n        }\n\n        if (self.recursive) {\n            self.scope  = scope;\n            self.node   = node;\n            self.textRenderer = new TextRenderer(scope, '{{' + expr + '}}', null, null, true);\n            self.textRenderer.subscribe(self.onTextRendererChange, self);\n            self.onTextRendererChange();\n\n            if (scope instanceof Scope) {\n                scope.$on(\"destroy\", self.onScopeDestroy, self);\n            }\n        }\n        else {\n            self.$super(scope, node, expr);\n        }\n    },\n\n    onInputChange: function() {\n\n        var self = this;\n        if (self.lockInput) {\n            self.onChange();\n        }\n    },\n\n    onTextRendererChange: function() {\n\n        var self    = this;\n        self.updateElement(self.textRenderer.getString());\n    },\n\n    onChange: function() {\n        var self    = this,\n            val     = self.watcher.getLastResult();\n\n        self.updateElement(val);\n    },\n\n    updateElement: function(val) {\n\n        var self = this;\n\n        if (self.isInput) {\n            self.input.setValue(val);\n        }\n        else {\n            self.node[elemTextProp] = val;\n        }\n    },\n\n    destroy: function() {\n\n        var self    = this;\n\n        if (self.textRenderer) {\n            self.textRenderer.$destroy();\n            self.textRenderer = null;\n        }\n\n        if (self.input) {\n            self.input.destroy();\n            self.input = null;\n        }\n\n        self.$super();\n    }\n}));\n\n\n\n\n\n\nDirective.registerAttribute(\"mjs-bind-html\", 1000, defineClass({\n\n    $extends: \"attr.mjs-bind\",\n\n    updateElement: function(val) {\n        this.node.innerHTML = val;\n    }\n}));\n\n\n\n\n\n(function(){\n\n    var toggleClass = function(node, cls, toggle, doAnim) {\n\n        var has;\n\n        if (toggle !== null) {\n            if (toggle == hasClass(node, cls)) {\n                return;\n            }\n            has = !toggle;\n        }\n        else {\n            has = hasClass(node, cls);\n        }\n\n        if (has) {\n            if (doAnim) {\n                animate(node, [cls + \"-remove\"], null, true).done(function(){\n                    removeClass(node, cls);\n                });\n            }\n            else {\n                removeClass(node, cls);\n            }\n        }\n        else {\n            if (doAnim) {\n                animate(node, [cls + \"-add\"], null, true).done(function(){\n                    addClass(node, cls);\n                });\n            }\n            else {\n                addClass(node, cls);\n            }\n        }\n    };\n\n    Directive.registerAttribute(\"mjs-class\", 1000, defineClass({\n\n        $extends: Directive,\n\n        initial: true,\n\n        onChange: function() {\n\n            var self    = this,\n                node    = self.node,\n                clss    = self.watcher.getLastResult(),\n                prev    = self.watcher.getPrevValue(),\n                i;\n\n            stopAnimation(node);\n\n            if (isString(clss)) {\n                if (prev) {\n                    toggleClass(node, prev, false, false);\n                }\n                toggleClass(node, clss, null, !self.initial);\n            }\n            else if (isArray(clss)) {\n                var l;\n                for (i = -1, l = clss.length; ++i < l; toggleClass(node, clss[i], true, !self.initial)){}\n            }\n            else {\n                for (i in clss) {\n                    toggleClass(node, i, clss[i] ? true : false, !self.initial);\n                }\n            }\n\n            self.initial = false;\n        }\n    }));\n\n}());\n\n\n\n\nDirective.registerAttribute(\"mjs-cmp-prop\", 200,\n    ['$parentCmp', '$node', '$attrValue', function(parentCmp, node, expr){\n    if (parentCmp) {\n        parentCmp[expr] = node;\n    }\n}]);\n\n\n\n(function(){\n\n    var cmpAttr = function(scope, node, expr, parentRenderer){\n\n\n        var cmpName,\n            as,\n            tmp,\n            i, len,\n            part,\n            nodeCfg = getNodeConfig(node, scope);\n\n        tmp     = expr.split(' ');\n\n        for (i = 0, len = tmp.length; i < len; i++) {\n\n            part = tmp[i];\n\n            if (part == '' || part == 'as') {\n                continue;\n            }\n\n            if (!cmpName) {\n                cmpName = part;\n            }\n            else {\n                as      = part;\n            }\n        }\n\n\n        var cfg     = extend({\n            scope: scope,\n            node: node,\n            as: as,\n            parentRenderer: parentRenderer,\n            destroyScope: true\n        }, nodeCfg, false, false);\n\n        var constr = nsGet(cmpName, true);\n\n        resolveComponent(cmpName, cfg, scope, node);\n\n        return !!constr.$shadow;\n    };\n\n    cmpAttr.$breakScope = true;\n\n    Directive.registerAttribute(\"mjs-cmp\", 200, cmpAttr);\n\n}());\n\n\n\nDirective.registerAttribute(\"mjs-config\", 50, function(scope, node, expr){\n    getNodeConfig(node, scope, expr);\n});\n\n\n\n\n\n\nDirective.registerAttribute(\"mjs-each\", 100, ListRenderer);\n\n\n\n\nvar createFunc = functionFactory.createFunc;\n\n\nfunction returnTrue() {\n    return true;\n};\n\n\n\n// from jQuery\n\nvar DomEvent = function(src) {\n\n    if (src instanceof DomEvent) {\n        return src;\n    }\n\n    // Allow instantiation without the 'new' keyword\n    if (!(this instanceof DomEvent)) {\n        return new DomEvent(src);\n    }\n\n\n    var self    = this;\n\n    for (var i in src) {\n        if (!self[i]) {\n            try {\n                self[i] = src[i];\n            }\n            catch (thrownError){}\n        }\n    }\n\n\n    // Event object\n    self.originalEvent = src;\n    self.type = src.type;\n\n    if (!self.target && src.srcElement) {\n        self.target = src.srcElement;\n    }\n\n\n    var eventDoc, doc, body,\n        button = src.button;\n\n    // Calculate pageX/Y if missing and clientX/Y available\n    if (self.pageX === undf && !isNull(src.clientX)) {\n        eventDoc = self.target ? self.target.ownerDocument || document : document;\n        doc = eventDoc.documentElement;\n        body = eventDoc.body;\n\n        self.pageX = src.clientX +\n                      ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -\n                      ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n        self.pageY = src.clientY +\n                      ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -\n                      ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n    }\n\n    // Add which for click: 1 === left; 2 === middle; 3 === right\n    // Note: button is not normalized, so don't use it\n    if ( !self.which && button !== undf ) {\n        self.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n    }\n\n    // Events bubbling up the document may have been marked as prevented\n    // by a handler lower down the tree; reflect the correct value.\n    self.isDefaultPrevented = src.defaultPrevented ||\n                              src.defaultPrevented === undf &&\n                                  // Support: Android<4.0\n                              src.returnValue === false ?\n                              returnTrue :\n                              returnFalse;\n\n\n    // Create a timestamp if incoming event doesn't have one\n    self.timeStamp = src && src.timeStamp || (new Date).getTime();\n};\n\n// Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\nextend(DomEvent.prototype, {\n\n    isDefaultPrevented: returnFalse,\n    isPropagationStopped: returnFalse,\n    isImmediatePropagationStopped: returnFalse,\n\n    preventDefault: function() {\n        var e = this.originalEvent;\n\n        this.isDefaultPrevented = returnTrue;\n        e.returnValue = false;\n\n        if ( e && e.preventDefault ) {\n            e.preventDefault();\n        }\n    },\n    stopPropagation: function() {\n        var e = this.originalEvent;\n\n        this.isPropagationStopped = returnTrue;\n\n        if ( e && e.stopPropagation ) {\n            e.stopPropagation();\n        }\n    },\n    stopImmediatePropagation: function() {\n        var e = this.originalEvent;\n\n        this.isImmediatePropagationStopped = returnTrue;\n\n        if ( e && e.stopImmediatePropagation ) {\n            e.stopImmediatePropagation();\n        }\n\n        this.stopPropagation();\n    }\n}, true, false);\n\n\n\n\nfunction normalizeEvent(originalEvent) {\n    return new DomEvent(originalEvent);\n};\n\n\nfunction addListener(el, event, func) {\n    if (el.attachEvent) {\n        el.attachEvent('on' + event, func);\n    } else {\n        el.addEventListener(event, func, false);\n    }\n};\n\n\n\n(function(){\n\n    var events = ['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover',\n                  'mouseout', 'mousemove', 'keydown', 'keyup', 'keypress', 'submit',\n                  'focus', 'blur', 'copy', 'cut', 'paste', 'enter'],\n        i, len;\n\n    for (i = 0, len = events.length; i < len; i++) {\n\n        (function(name){\n\n            var eventName = name;\n\n            if (eventName == \"enter\") {\n                eventName = \"keyup\";\n            }\n\n            Directive.registerAttribute(\"mjs-\" + name, 1000, function(scope, node, expr){\n\n                var fn  = createFunc(expr);\n\n                addListener(node, eventName, function(e){\n\n                    e = normalizeEvent(e || window.event);\n\n                    if (name == \"enter\" && e.keyCode != 13) {\n                        return null;\n                    }\n\n                    scope.$event = e;\n\n                    fn(scope);\n\n                    scope.$event = null;\n\n                    scope.$root.$check();\n\n                    e.preventDefault();\n                    return false;\n                });\n            });\n        }(events[i]));\n    }\n\n}());\n\n\n\n\n\n\nDirective.registerAttribute(\"mjs-show\", 500, defineClass({\n\n    $extends: Directive,\n\n    initial: true,\n    display: \"\",\n\n    $init: function(scope, node, expr) {\n\n        var self    = this,\n            cfg = getNodeConfig(node, scope);\n\n        self.display = cfg.display || \"\";\n\n        self.$super(scope, node, expr);\n    },\n\n    runAnimation: function(show) {\n\n        var self    = this,\n            style   = self.node.style,\n            done    = function() {\n                if (!show) {\n                    style.display = \"none\";\n                }\n                else {\n                    style.display = self.display;\n                }\n            };\n\n        self.initial ? done() : animate(\n            self.node,\n            show ? \"show\" : \"hide\",\n            function() {\n                if (show) {\n                    style.display = self.display;\n                }\n            },\n            true)\n            .done(done);\n    },\n\n    onChange: function() {\n        var self    = this,\n            val     = self.watcher.getLastResult();\n\n        self.runAnimation(val);\n\n        self.initial = false;\n    }\n}));\n\n\n\n\n\n\n\nDirective.registerAttribute(\"mjs-hide\", 500, defineClass({\n\n    $extends: \"attr.mjs-show\",\n\n    onChange: function() {\n        var self    = this,\n            val     = self.watcher.getLastResult();\n\n        self.runAnimation(!val);\n        self.initial = false;\n    }\n}));\n\n\n\n\n\n\nDirective.registerAttribute(\"mjs-if\", 500, defineClass({\n\n    $extends: Directive,\n\n    parentEl: null,\n    prevEl: null,\n    el: null,\n    initial: true,\n\n    $init: function(scope, node, expr) {\n\n        var self    = this;\n\n        self.parentEl   = node.parentNode;\n        self.prevEl     = node.previousSibling;\n\n        self.$super(scope, node, expr);\n    },\n\n    onScopeDestroy: function() {\n\n        var self    = this;\n\n        self.prevEl = null;\n        self.parentEl = null;\n\n        self.$super();\n    },\n\n    onChange: function() {\n        var self    = this,\n            val     = self.watcher.getLastResult(),\n            parent  = self.parentEl,\n            node    = self.node;\n\n        var show    = function(){\n            if (self.prevEl) {\n                parent.insertBefore(node, self.prevEl ? self.prevEl.nextSibling : null);\n            }\n            else {\n                parent.appendChild(node);\n            }\n        };\n\n        var hide    = function() {\n            parent.removeChild(node);\n        };\n\n        if (val) {\n            if (!isAttached(node)) {\n                self.initial ? show() : animate(node, \"enter\", show, true);\n            }\n        }\n        else {\n            if (isAttached(node)) {\n                self.initial ? hide() : animate(node, \"leave\", null, true).done(hide);\n            }\n        }\n\n        self.initial = false;\n    }\n}));\n\n\n\n\n\nDirective.registerAttribute(\"mjs-ignore\", 0, returnFalse);\n\n\n\n\n\nDirective.registerAttribute(\"mjs-include\", 900, function(scope, node, tplExpr, parentRenderer){\n\n    var tpl = new Template({\n        scope: scope,\n        node: node,\n        url: tplExpr,\n        parentRenderer: parentRenderer\n    });\n\n    if (tpl.ownRenderer) {\n        return false;\n    }\n    else {\n        return tpl.initPromise;\n    }\n});\n\n\n\n\n\nDirective.registerAttribute(\"mjs-init\", 250, function(scope, node, expr){\n    createFunc(expr)(scope);\n});\n\nvar uaString = navigator.userAgent.toLowerCase();\n\n\n\nvar isIE = function(){\n\n    var msie    = parseInt((/msie (\\d+)/.exec(uaString) || [])[1], 10);\n\n    if (isNaN(msie)) {\n        msie    = parseInt((/trident\\/.*; rv:(\\d+)/.exec(uaString) || [])[1], 10) || false;\n    }\n\n    return function isIE() {\n        return msie;\n    };\n}();\n\n\n\n\n\n\n\n\nDirective.registerAttribute(\"mjs-model\", 1000, defineClass({\n\n    $extends: Directive,\n\n    inProg: false,\n    input: null,\n    binding: null,\n\n    autoOnChange: false,\n\n    $init: function(scope, node, expr) {\n\n        var self    = this,\n            cfg     = getNodeConfig(node, scope);\n\n        self.node           = node;\n        self.input          = new Input(node, self.onInputChange, self);\n        self.binding        = cfg.binding || \"both\";\n\n        self.$super(scope, node, expr);\n\n        var inputValue      = self.input.getValue(),\n            scopeValue      = self.watcher.getLastResult();\n\n        if (scopeValue != inputValue) {\n            // scope value takes priority\n            if (self.binding != \"input\" && scopeValue != undf) {\n                self.onChange(scopeValue);\n            }\n            else if (self.binding != \"scope\" && inputValue != undf) {\n                self.onInputChange(inputValue);\n            }\n        }\n    },\n\n    onInputChange: function(val) {\n\n        var self    = this,\n            scope   = self.scope;\n\n        if (self.binding != \"scope\") {\n\n            if (val && isString(val) && val.indexOf('\\\\{') != -1) {\n                val = val.replace(/\\\\{/g, '{');\n            }\n\n            if (self.watcher.getLastResult() == val) {\n                return;\n            }\n\n            self.watcher.setValue(val);\n\n            self.inProg = true;\n            if (scope instanceof Scope) {\n                scope.$root.$check();\n            }\n            else {\n                self.watcher.checkAll();\n            }\n            self.inProg = false;\n        }\n    },\n\n    destroy: function() {\n\n        var self        = this;\n        self.input.destroy();\n        self.$super();\n    },\n\n\n    onChange: function() {\n\n        var self    = this,\n            val     = self.watcher.getLastResult(),\n            ie;\n\n        if (self.binding != \"input\" && !self.inProg) {\n            if ((ie = isIE()) && ie < 8) {\n                async(self.input.setValue, self.input, [val]);\n            }\n            else {\n                self.input.setValue(val);\n            }\n        }\n    }\n\n\n}));\n\n\n\n\n\n\nDirective.registerAttribute(\"mjs-options\", 100, defineClass({\n\n    $extends: Directive,\n\n    model: null,\n    getterFn: null,\n    defOption: null,\n    prevGroup: null,\n    groupEl: null,\n    fragment: null,\n\n    $init: function(scope, node, expr) {\n\n        var self    = this;\n\n        self.parseExpr(expr);\n\n        self.node       = node;\n        self.scope      = scope;\n        self.defOption  = node.options.length ? node.options[0] : null;\n\n        while (node.firstChild) {\n            node.removeChild(node.firstChild);\n        }\n\n        self.defOption && setAttr(self.defOption, \"mjs-default-option\", \"\");\n\n        try {\n            self.watcher    = createWatchable(scope, self.model, self.onChange, self, null, ns);\n        }\n        catch (thrownError) {\n            error(thrownError);\n        }\n\n        self.render(toArray(self.watcher.getValue()));\n    },\n\n    onChange: function() {\n        this.render(toArray(this.watcher.getValue()));\n    },\n\n    renderOption: function(item, index, scope) {\n\n        var self        = this,\n            parent      = self.groupEl || self.fragment,\n            msie        = isIE(),\n            config,\n            option;\n\n        scope.item      = item;\n        scope.$index    = index;\n        config          = self.getterFn(scope);\n\n        config.group    != undf && (config.group = \"\"+config.group);\n\n        if (config.group !== self.prevGroup) {\n\n            if (config.group){\n                self.groupEl = parent = document.createElement(\"optgroup\");\n                setAttr(parent, \"label\", config.group);\n                if (config.disabledGroup) {\n                    setAttr(parent, \"disabled\", \"disabled\");\n                }\n                self.fragment.appendChild(parent);\n            }\n            else {\n                parent = self.fragment;\n                self.groupEl = null;\n            }\n        }\n        self.prevGroup  = config.group;\n\n        option  = document.createElement(\"option\");\n        setAttr(option, \"value\", config.value);\n        option.text = config.name;\n\n        if (msie && msie < 9) {\n            option.innerHTML = config.name;\n        }\n        if (config.disabled) {\n            setAttr(option, \"disabled\", \"disabled\");\n        }\n\n        parent.appendChild(option);\n    },\n\n    render: function(list) {\n\n        var self        = this,\n            node        = self.node,\n            value       = getValue(node),\n            def         = self.defOption,\n            tmpScope    = self.scope.$new(),\n            msie        = isIE(),\n            parent, next,\n            i, len;\n\n        self.fragment   = document.createDocumentFragment();\n        self.prevGroup  = null;\n        self.groupEl    = null;\n\n        while(node.firstChild) {\n            node.removeChild(node.firstChild);\n        }\n\n        for (i = 0, len = list.length; i < len; i++) {\n            self.renderOption(list[i], i, tmpScope);\n        }\n\n        if (def) {\n            node.insertBefore(def, node.firstChild);\n        }\n\n        tmpScope.$destroy();\n\n        // ie6 gives \"unspecified error when trying to set option.selected\"\n        // on node.appendChild(fragment);\n        // somehow this get fixed by detaching dom node\n        // and attaching it back\n        if (msie && msie < 8) {\n            next = node.nextSibling;\n            parent = node.parentNode;\n            parent.removeChild(node);\n        }\n\n        node.appendChild(self.fragment);\n        self.fragment = null;\n\n        if (msie && msie < 8) {\n            parent.insertBefore(node, next);\n        }\n\n        setValue(node, value);\n    },\n\n\n    parseExpr: function(expr) {\n\n        var splitIndex  = expr.indexOf(\" in \"),\n            model, item;\n\n        if (splitIndex == -1) {\n            model   = expr;\n            item    = '{name: .item, value: .$index}';\n        }\n        else {\n            model   = expr.substr(splitIndex + 4);\n            item    = expr.substr(0, splitIndex);\n        }\n\n        this.model = model;\n        this.getterFn = createGetter(item);\n    }\n\n}));\n\n\n\n\n\n\n\n(function(){\n\n    var booleanAttrs = [\"selected\", \"checked\", \"disabled\", \"readonly\", \"open\", \"required\"],\n        i, l;\n\n    var PropertyDirective = defineClass({\n\n        $extends: Directive,\n\n        propName: null,\n\n        $init: function(scope, node, expr, propName) {\n            this.propName = propName;\n            this.$super(scope, node, expr);\n        },\n\n        onChange: function(val) {\n\n            var name = this.propName;\n\n            val = !!val;\n\n            if (val) {\n                setAttr(this.node, name, name);\n            }\n            else {\n                removeAttr(this.node, name);\n            }\n        }\n    });\n\n    for (i = 0, l = booleanAttrs.length; i < l; i++) {\n        (function(name){\n\n            Directive.registerAttribute(\"mjs-\" + name, 1000, function(scope, node, expr){\n                return new PropertyDirective(scope, node, expr, name);\n            });\n\n        }(booleanAttrs[i]));\n    }\n\n}());\n\n\n\n\nvar preloadImage = function() {\n\n    var cache = {},\n        cacheCnt = 0;\n\n\n    return function preloadImage(src) {\n\n        if (cache[src]) {\n            return Promise.resolve(src);\n        }\n\n        if (cacheCnt > 1000) {\n            cache = {};\n            cacheCnt = 0;\n        }\n\n        var img = document.createElement(\"img\"),\n            style = img.style,\n            deferred = new Promise;\n\n        addListener(img, \"load\", function() {\n            cache[src] = true;\n            cacheCnt++;\n            document.body.removeChild(img);\n            deferred.resolve(src);\n        });\n\n        style.position = \"absolute\";\n        style.visibility = \"hidden\";\n        style.left = \"-10000px\";\n        style.top = \"0\";\n        img.src = src;\n        document.body.appendChild(img);\n\n        return deferred;\n    };\n\n}();\n\n\n\n\nDirective.registerAttribute(\"mjs-src\", 1000, defineClass({\n\n    $extends: Directive,\n\n    queue: null,\n    usePreload: true,\n\n    $constructor: function(scope, node, expr) {\n\n        var self = this,\n            cfg = getNodeConfig(node, scope);\n\n        if (cfg.deferred) {\n            self.$plugins.push(\"SrcDeferred\");\n        }\n\n        self.$super(scope, node, expr);\n    },\n\n    $init: function(scope, node, expr) {\n\n        var self = this,\n            cfg = getNodeConfig(node, scope);\n\n        if (cfg.noPreload) {\n            self.usePreload = false;\n        }\n\n        self.queue = new Queue({auto: true, async: true, mode: Queue.ONCE, thenable: true});\n        self.$super(scope, node, expr);\n    },\n\n\n    onChange: function() {\n        var self = this;\n        self.queue.add(self.doChange, self);\n    },\n\n    doChange: function() {\n        var self = this,\n            src = self.watcher.getLastResult();\n\n        if (self.usePreload) {\n            return preloadImage(src).done(function(){\n                if (self && self.node) {\n                    raf(function(){\n                        self.node.src = src;\n                        setAttr(self.node, \"src\", src);\n                    });\n                }\n            });\n        }\n        else {\n            self.node.src = src;\n            setAttr(self.node, \"src\", src);\n        }\n    },\n\n    destroy: function() {\n        this.queue.destroy();\n        this.$super();\n    }\n}));\n\n\n\nfunction parentData(node, key) {\n\n    var val;\n\n    while (node) {\n        val = data(node ,key);\n        if (val !== undf) {\n            return val;\n        }\n        node  = node.parentNode;\n    }\n\n    return undf;\n};\n\n\n\nfunction transclude(node) {\n\n    var contents  = parentData(node, 'mjs-transclude');\n\n    if (contents) {\n\n        if (node.firstChild) {\n            data(node, \"mjs-transclude\", toFragment(node.childNodes));\n        }\n\n        var parent      = node.parentNode,\n            next        = node.nextSibling,\n            cloned      = clone(contents),\n            children    = toArray(cloned.childNodes);\n\n        parent.removeChild(node);\n        parent.insertBefore(cloned, next);\n\n        return children;\n    }\n\n    return null;\n};\n\n\n\nDirective.registerAttribute(\"mjs-transclude\", 1000, function(scope, node) {\n    return transclude(node);\n});\n\n\n\nDirective.registerAttribute(\"mjs-view\", 200, function(scope, node, cls) {\n    resolveComponent(cls || \"MetaphorJs.View\", {scope: scope, node: node}, scope, node)\n    return false;\n});\n\n\n\n\nDirective.registerTag(\"mjs-include\", function(scope, node, value, parentRenderer) {\n\n    var tpl = new Template({\n        scope: scope,\n        node: node,\n        tpl: getAttr(node, \"src\"),\n        parentRenderer: parentRenderer,\n        replace: true\n    });\n\n    return tpl.initPromise;\n\n});\n\n\n\n\nDirective.registerTag(\"mjs-transclude\", function(scope, node) {\n    return transclude(node);\n});\n\n\n\n\nvar filterArray = function(){\n\n\n    var compareValues = function(value, to, opt) {\n\n            if (isFunction(to)) {\n                return to(value, opt);\n            }\n            else if (to === \"\" || to === undf) {\n                return true;\n            }\n            else if (value === undf) {\n                return false;\n            }\n            else if (isBool(value)) {\n                return value === to;\n            }\n            else if (to instanceof RegExp) {\n                return to.test(\"\" + value);\n            }\n            else if (opt == \"strict\") {\n                return \"\"+value === \"\"+to;\n            }\n            else if (opt === true || opt === null || opt === undf) {\n                return \"\"+value.indexOf(to) != -1;\n            }\n            else if (opt === false) {\n                return \"\"+value.indexOf(to) == -1;\n            }\n            return false;\n        },\n\n        compare = function(value, by, opt) {\n\n            if (isPrimitive(value)) {\n                if (by.$ === undf) {\n                    return true;\n                }\n                else {\n                    return compareValues(value, by.$, opt);\n                }\n            }\n\n            var k, i;\n            for (k in by) {\n                if (k == '$') {\n                    for (i in value) {\n                        if (compareValues(value[i], by.$, opt)) {\n                            return true;\n                        }\n                    }\n                }\n                else {\n                    if (compareValues(value[k], by[k], opt)) {\n                        return true;\n                    }\n                }\n            }\n\n            return false;\n        };\n\n    var filterArray = function filterArray(a, by, opt) {\n\n        if (!isPlainObject(by)) {\n            by = {$: by};\n        }\n\n        var ret = [],\n            i, l;\n\n        for (i = -1, l = a.length; ++i < l;) {\n            if (compare(a[i], by, opt)) {\n                ret.push(a[i]);\n            }\n        }\n\n        return ret;\n    };\n\n    filterArray.compare = compare;\n\n    return filterArray;\n\n}();\n\n\n\nnsAdd(\"filter.filter\", function(val, scope, by, opt) {\n    return filterArray(val, by, opt);\n});\n\n\n\n\n\n\n\nnsAdd(\"filter.join\", function(input, scope, separator) {\n\n    separator = separator || \", \";\n\n    if (input && input.length) {\n        if (!isArray(input)){\n            input = toArray(input);\n        }\n        return input.join(separator);\n    }\n\n    return \"\";\n});\n\n\n\nnsAdd(\"filter.l\", function(key, scope) {\n    return scope.$app.lang.get(key);\n});\n\n\n\n\nnsAdd(\"filter.limitTo\", function(input, scope, limit){\n\n    var isS = isString(input);\n\n    if (!isArray(input) && !isS) {\n        return input;\n    }\n\n    if (Math.abs(Number(limit)) === Infinity) {\n        limit = Number(limit);\n    } else {\n        limit = parseInt(limit, 10);\n    }\n\n    if (isS) {\n        //NaN check on limit\n        if (limit) {\n            return limit >= 0 ? input.slice(0, limit) : input.slice(limit, input.length);\n        } else {\n            return \"\";\n        }\n    }\n\n    var out = [],\n        i, n;\n\n    // if abs(limit) exceeds maximum length, trim it\n    if (limit > input.length)\n        limit = input.length;\n    else if (limit < -input.length)\n        limit = -input.length;\n\n    if (limit > 0) {\n        i = 0;\n        n = limit;\n    } else {\n        i = input.length + limit;\n        n = input.length;\n    }\n\n    for (; i<n; i++) {\n        out.push(input[i]);\n    }\n\n    return out;\n});\n\n\n\n\nnsAdd(\"filter.linkify\", function(input, scope, target){\n    target = target ? ' target=\"'+target+'\"' : \"\";\n    if (input) {\n        var exp = /(\\b(https?|ftp|file):\\/\\/[-A-Z0-9+&@#\\/%?=~_|!:,.;]*[-A-Z0-9+&@#\\/%=~_|])/ig;\n        return input.replace(exp, '<a href=\"$1\"'+target+'>$1</a>');\n    }\n    return \"\";\n});\n\n\n\n\nnsAdd(\"filter.lowercase\", function(val){\n    return val.toLowerCase();\n});\n\nvar dateFormats = {};\n\n\n\n\n\nnsAdd(\"filter.moment\",  function(val, scope, format) {\n    format  = dateFormats[format] || format;\n    return moment(val).format(format);\n});\n\n\nvar numberFormats = {};\n\n\n\n\n\n\n\nnsAdd(\"filter.numeral\",  function(val, scope, format) {\n    format  = numberFormats[format] || format;\n    return numeral(val).format(format);\n});\n\n\n\nnsAdd(\"filter.p\", function(key, scope, number) {\n    return scope.$app.lang.plural(key, parseInt(number, 10) || 0);\n});\n\n\n\nfunction sortArray(arr, by, dir) {\n\n    if (!dir) {\n        dir = \"asc\";\n    }\n\n    var ret = arr.slice();\n\n    ret.sort(function(a, b) {\n        var typeA = typeof a,\n            typeB = typeof b,\n            valueA  = a,\n            valueB  = b;\n\n        if (typeA != typeB) {\n            return 0;\n        }\n\n        if (typeA == \"object\") {\n            if (isFunction(by)) {\n                valueA = by(a);\n                valueB = by(b);\n            }\n            else {\n                valueA = a[by];\n                valueB = b[by];\n            }\n        }\n\n        if (typeof valueA == \"number\") {\n            return valueA - valueB;\n        }\n        else {\n            valueA = (\"\" + valueA).toLowerCase();\n            valueB = (\"\" + valueB).toLowerCase();\n\n            if (valueA === valueB) return 0;\n            return valueA > valueB ? 1 : -1;\n        }\n    });\n\n    return dir == \"desc\" ? ret.reverse() : ret;\n\n};\n\n\n\nnsAdd(\"filter.sortBy\", function(val, scope, field, dir) {\n    return sortArray(val, field, dir);\n});\n\n\n\n\nnsAdd(\"filter.split\", function(input, scope, sep, limit) {\n\n    limit       = limit || undf;\n    sep         = sep || \"/\\\\n|,/\";\n\n    if (!input) {\n        return [];\n    }\n\n    input       = \"\" + input;\n\n    if (sep.substr(0,1) == '/' && sep.substr(sep.length - 1) == \"/\") {\n        sep = getRegExp(sep.substring(1, sep.length-1));\n    }\n\n    var list = input.split(sep, limit),\n        i, l;\n\n    for (i = -1, l = list.length; ++i < l; list[i] = trim(list[i])){}\n\n    return list;\n});\n\n\n\n\n\nnsAdd(\"filter.toArray\", function(input){\n    return toArray(input);\n});\n\n\n\nnsAdd(\"filter.ucfirst\", function(val){\n    return val.substr(0, 1).toUpperCase() + val.substr(1);\n});\n\n\n\n\nnsAdd(\"filter.uppercase\", function(val){\n    return val.toUpperCase();\n});\n\n\nfunction removeListener(el, event, func) {\n    if (el.detachEvent) {\n        el.detachEvent('on' + event, func);\n    } else {\n        el.removeEventListener(event, func, false);\n    }\n};\n\n\n\n/**\n * @param {Function} fn\n */\nfunction onReady(fn) {\n\n    var done    = false,\n        top     = true,\n        win     = window,\n        doc     = win.document,\n        root    = doc.documentElement,\n\n        init    = function(e) {\n            if (e.type == 'readystatechange' && doc.readyState != 'complete') {\n                return;\n            }\n\n            removeListener(e.type == 'load' ? win : doc, e.type, init);\n\n            if (!done && (done = true)) {\n                fn.call(win, e.type || e);\n            }\n        },\n\n        poll = function() {\n            try {\n                root.doScroll('left');\n            } catch(thrownError) {\n                setTimeout(poll, 50);\n                return;\n            }\n\n            init('poll');\n        };\n\n    if (doc.readyState == 'complete') {\n        fn.call(win, 'lazy');\n    }\n    else {\n        if (doc.createEventObject && root.doScroll) {\n            try {\n                top = !win.frameElement;\n            } catch(thrownError) {}\n\n            top && poll();\n        }\n        addListener(doc, 'DOMContentLoaded', init);\n        addListener(doc, 'readystatechange', init);\n        addListener(win, 'load', init);\n    }\n};\n\n\n\nfunction initApp(node, cls, data, autorun) {\n\n    try {\n        var p = resolveComponent(cls || \"MetaphorJs.App\", false, data, node, [node, data]);\n\n        if (autorun !== false) {\n            return p.done(function(app){\n                app.run();\n            });\n        }\n        else {\n            return p;\n        }\n    }\n    catch (thrownError) {\n        error(thrownError);\n        return Promise.reject(thrownError);\n    }\n};\n\n\n\nfunction run() {\n\n    onReady(function() {\n\n        var appNodes    = select(\"[mjs-app]\"),\n            i, l, el;\n\n        for (i = -1, l = appNodes.length; ++i < l;){\n            el      = appNodes[i];\n            initApp(el, getAttr(el, \"mjs-app\"), null, true);\n        }\n    });\n\n};\n\n\n\n\nvar StoreRenderer = ListRenderer.$extend({\n\n        store: null,\n\n        $constructor: function(scope, node, expr) {\n\n\n            var cfg = getNodeConfig(node, scope);\n\n            if (cfg.pullNext) {\n                if (cfg.buffered) {\n                    cfg.bufferedPullNext = true;\n                    cfg.buffered = false;\n                }\n                this.$plugins.push(\"ListPullNext\");\n            }\n\n            this.$super(scope, node, expr);\n        },\n\n        afterInit: function(scope, node, expr) {\n\n            var self            = this,\n                store;\n\n            self.store          = store = createGetter(self.model)(scope);\n            self.watcher        = createWatchable(store, \".current\", self.onChange, self, null, ns);\n            self.trackByFn      = bind(store.getRecordId, store);\n            self.griDelegate    = bind(store.indexOfId, store);\n            self.bindStore(store, \"on\");\n        },\n\n\n        bindStore: function(store, fn) {\n\n            var self    = this;\n\n            store[fn](\"update\", self.onStoreUpdate, self);\n            store[fn](\"clear\", self.onStoreUpdate, self);\n            store[fn](\"destroy\", self.onStoreDestroy, self);\n        },\n\n        onStoreUpdate: function() {\n            this.watcher.check();\n        },\n\n        getListItem: function(list, index) {\n            return this.store.getRecordData(list[index]);\n        },\n\n        onStoreDestroy: function() {\n            var self = this;\n            self.onStoreUpdate();\n            self.watcher.unsubscribeAndDestroy(self.onChange, self);\n            self.watcher = null;\n        },\n\n        destroy: function() {\n            var self = this;\n            self.bindStore(self.store, \"un\");\n            self.$super();\n        }\n\n    },\n    {\n        $stopRenderer: true,\n        $registerBy: \"id\"\n    }\n);\n\n\n\n\n\n\n\nDirective.registerAttribute(\"mjs-each-in-store\", 100, StoreRenderer);\n\n\n\n\ndefineClass({\n\n    $class: \"DialogComponent\",\n    $extends: Component,\n\n    dialog: null,\n    dialogPreset: null,\n    dialogCfg: null,\n\n    initComponent: function() {\n\n\n        var self    = this;\n\n        self.$super();\n        self._createDialog();\n        self._oldShow = self.show;\n        self._oldHide = self.hide;\n    },\n\n    _getDialogCfg: function() {\n\n        var self    = this;\n\n        return extend({}, self.dialogCfg, {\n            render: {\n                el: self.node,\n                keepInDOM: true\n            }\n        }, true, true);\n    },\n\n    _createDialog: function() {\n\n        var self    = this;\n        self.dialog = new Dialog(self.dialogPreset, self._getDialogCfg());\n        self.dialog.on(\"show\", self._oldShow, self);\n        self.dialog.on(\"hide\", self._oldHide, self);\n        self.dialog.on(\"destroy\", self.onDialogDestroy, self);\n    },\n\n    show: function() {\n        this.dialog.show();\n    },\n\n    hide: function() {\n        this.dialog.hide();\n    },\n\n    onDialogDestroy: function() {\n        var self    = this;\n\n        if (!self.destroying) {\n            self.dialog = null;\n            self.$destroy();\n        }\n    },\n\n    destroy: function() {\n\n        var self    = this;\n\n        self.destroying = true;\n\n        if (self.dialog) {\n            self.dialog.destroy();\n        }\n\n        self.$super();\n\n    }\n\n});\n\n\nfunction eachNode(el, fn, context) {\n    var i, len,\n        children = el.childNodes;\n\n    if (fn.call(context, el) !== false) {\n        for(i =- 1, len = children.length>>>0;\n            ++i !== len;\n            eachNode(children[i], fn, context)){}\n    }\n};\n\n\n\n\n\n\ndefineClass({\n\n    $class: \"MetaphorJs.ValidatorComponent\",\n\n    node: null,\n    scope: null,\n    validator: null,\n    scopeState: null,\n\n    $init: function(node, scope, renderer) {\n\n        var self        = this;\n\n        self.node       = node;\n        self.scope      = scope;\n        self.scopeState = {};\n        self.validator  = self.createValidator();\n\n        self.initScope();\n        self.initScopeState();\n        self.initValidatorEvents();\n\n        // wait for the renderer to finish\n        // before making judgements :)\n        renderer.once(\"rendered\", self.validator.check, self.validator);\n    },\n\n    createValidator: function() {\n        var self    = this,\n            node    = self.node,\n            cfg     = {},\n            ncfg    = getNodeConfig(node),\n            submit;\n\n        if (submit = ncfg.submit) {\n            cfg.callback = cfg.callback || {};\n            cfg.callback.submit = function(fn, scope){\n                return function() {\n                    try {\n                        return fn(scope);\n                    }\n                    catch(thrownError) {\n                        error(thrownError);\n                    }\n                }\n            }(createFunc(submit), self.scope);\n        }\n\n        return new Validator(node, cfg);\n    },\n\n    initValidatorEvents: function() {\n\n        var self    = this,\n            v       = self.validator;\n\n        v.on('fieldstatechange', self.onFieldStateChange, self);\n        v.on('statechange', self.onFormStateChange, self);\n        v.on('displaystatechange', self.onDisplayStateChange, self);\n        v.on('reset', self.onFormReset, self);\n    },\n\n    initScope: function() {\n\n        var self    = this,\n            scope   = self.scope,\n            node    = self.node,\n            name    = getAttr(node, 'name') || getAttr(node, 'id') || '$form';\n\n        scope[name] = self.scopeState;\n    },\n\n    initScopeState: function() {\n\n        var self    = this,\n            node    = self.node,\n            state   = self.scopeState,\n            els, el,\n            i, l,\n            name;\n\n        if (node.elements) {\n            els     = node.elements;\n        }\n        else {\n            els     = [];\n            eachNode(node, function(el) {\n                if (isField(el)) {\n                    els.push(el);\n                }\n            });\n        }\n\n        for (i = -1, l = els.length; ++i < l;) {\n            el = els[i];\n            name = getAttr(el, \"name\") || getAttr(el, 'id');\n\n            if (name && !state[name]) {\n                state[name] = {\n                    $error: null,\n                    $invalid: null,\n                    $pristine: true,\n                    $errorMessage: null\n                };\n            }\n        }\n\n        state.$invalid = false;\n        state.$pristine = true;\n        state.$submit = bind(self.validator.onSubmit, self.validator);\n        state.$reset = bind(self.validator.reset, self.validator);\n\n        window.formState = state;\n    },\n\n    onDisplayStateChange: function(vld, state) {\n\n        var self    = this;\n\n        if (!state) {\n            self.onFormReset(vld);\n        }\n        else {\n            state   = self.scopeState;\n            var i,f;\n\n            for (i in state) {\n                f = state[i];\n                if (f.$real) {\n                    state[i] = f.$real;\n                }\n            }\n\n            state.$invalid = !vld.isValid();\n            state.$pristine = false;\n\n            self.scope.$check();\n        }\n\n    },\n\n    onFormReset: function(vld) {\n\n        var self    = this,\n            state   = self.scopeState,\n            i,f;\n\n        for (i in state) {\n            f = state[i];\n            f.$error = null;\n            f.$errorMessage = null;\n            f.$invalid = null;\n            f.$pristine = true;\n        }\n\n        state.$invalid = false;\n        state.$pristine = true;\n\n        self.scope.$check();\n    },\n\n    onFormStateChange: function(vld, valid) {\n\n        var self    = this,\n            state   = self.scopeState;\n\n        state.$invalid = valid === false && vld.isDisplayStateEnabled();\n        state.$pristine = false;\n\n        self.scope.$check();\n    },\n\n    onFieldStateChange: function(vld, field, valid) {\n\n        var self    = this,\n            state   = self.scopeState,\n            name    = field.getName(),\n            ds      = vld.isDisplayStateEnabled(),\n            fstate  = {\n                $error: field.getErrorRule(),\n                $errorMessage: field.getError(),\n                $invalid: valid === false,\n                $pristine: field.getExactValidState() === null\n            };\n\n        if (ds) {\n            state[name] = fstate;\n        }\n        else {\n            state[name].$real = fstate;\n        }\n\n        self.scope.$check();\n    }\n\n});\n\nDirective.registerAttribute(\"mjs-validate\", 250, ['$scope', '$node', '$attrValue', '$renderer',\n                                               function(scope, node, expr, renderer) {\n\n    var cls     = expr || \"MetaphorJs.ValidatorComponent\",\n        constr  = nsGet(cls);\n\n    if (!constr) {\n        error(new Error(\"Class '\"+cls+\"' not found\"));\n    }\n    else {\n        new constr(node, scope, renderer);\n    }\n}]);\n\nmodule.exports = MetaphorJs;\n"]}