diff --git a/README.md b/README.md index 8dd4a1d..8d6034b 100644 --- a/README.md +++ b/README.md @@ -537,6 +537,10 @@ Components feature is used when you have many element for one model. Each compon ```js sf.component.for('model-name', function(self, root){ self.data = "text"; + + // If you're using sf-repeat-this for this component + // This variable will have your item value instead of undefined + self.$item = {}; }); ``` diff --git a/dist/scarletsframe.js b/dist/scarletsframe.js index 7ad26bf..c1e31ae 100644 --- a/dist/scarletsframe.js +++ b/dist/scarletsframe.js @@ -73,6 +73,13 @@ function deepProperty(obj, path){ } return obj; } + +function capitalizeLetters(name){ + for (var i = 0; i < name.length; i++) { + name[i] = name[i][0].toUpperCase() + name[i].slice(1); + } + return name.join(''); +} // ==== ES5 Polyfill ==== if(typeof Object.assign != 'function'){ Object.defineProperty(Object, "assign", { @@ -837,13 +844,6 @@ sf.component = new function(){ window['$'+name] = func; } - - function capitalizeLetters(name){ - for (var i = 0; i < name.length; i++) { - name[i] = name[i][0].toUpperCase() + name[i].slice(1); - } - return name.join(''); - } }; // Data save and HTML content binding sf.model = function(scope){ @@ -1045,6 +1045,12 @@ sf.model = function(scope){ } var templateParser = function(template, item, original){ + if(template.constructor !== Object){ + var html = template.cloneNode(true); + html.model.$item = item; + return html; + } + var html = original === true ? template.html : template.html.cloneNode(true); var addresses = template.addresses; var parsed = templateExec(template.parse, item); @@ -2195,7 +2201,6 @@ sf.model = function(scope){ var loopParser = function(name, template, script, targetNode, parentNode){ var method = script.split(' in '); var mask = method[0]; - var isKeyed = parentNode.classList.contains('sf-keyed-list'); var items = root_(name)[method[1]]; if(items === void 0) @@ -2208,6 +2213,7 @@ sf.model = function(scope){ template = self.extractPreprocess(template, mask, name); if(method.length === 2){ + var isKeyed = parentNode.classList.contains('sf-keyed-list'); var tempDOM = document.createElement('div'); var modelRef = self.root[name]; @@ -2766,6 +2772,15 @@ sf.model = function(scope){ } self.extractPreprocess = function(targetNode, mask, name){ + // Check if it's component + var tagName = targetNode.tagName.toLowerCase(); + if(sf.component.registered[tagName] !== void 0){ + targetNode.parentNode.classList.add('sf-keyed-list'); + targetNode.textContent = ''; + targetNode.remove(); + return targetNode; + } + var copy = targetNode.outerHTML; // Mask the referenced item @@ -3170,7 +3185,7 @@ sf.controller = new function(){ return; } - name = name.sf$component === void 0 ? name.getAttribute('sf-controller') : name.sf$component; + name = name.sf$component === void 0? name.getAttribute('sf-controller') : name.sf$component; // Initialize it first if(name !== void 0 && !self.active[name]) @@ -3189,12 +3204,13 @@ sf.controller = new function(){ } var model = $.parent(element, '[sf-controller]'); - model = model.sf$component === void 0? model.getAttribute('sf-controller') : model; + model = model.sf$component === void 0 ? model.getAttribute('sf-controller') : model; + var _modelScope = sf.model.root[model]; - if(!sf.model.root[model]) + if(_modelScope === void 0) throw "Couldn't find model for "+model+" that was called from sf-click"; - var modelKeys = sf.model.modelKeys(sf.model.root[model]).join('|'); + var modelKeys = sf.model.modelKeys(_modelScope).join('|'); script = avoidQuotes(script, function(script_){ return script_.replace(RegExp(sf.regex.strictVar+'('+modelKeys+')\\b', 'g'), function(full, matched){ return '_modelScope.'+matched; diff --git a/dist/scarletsframe.min.js b/dist/scarletsframe.min.js index 33f4d6f..16319bd 100644 --- a/dist/scarletsframe.min.js +++ b/dist/scarletsframe.min.js @@ -6,5 +6,5 @@ https://github.com/ScarletsFiction/ScarletsFrame */ -!function(e,t){"object"==typeof exports&&"void 0"!=typeof module?module.exports=t(e):e.sf=t(e)}("void 0"!=typeof window?window:this,function(window){"use strict";void 0===typeof document&&(document=window.document);var internal={},sf=function(){if(arguments[0].constructor===Function)return sf.loader.onFinish.apply(null,arguments)};sf.internal={},sf.regex={getQuotes:/(['"])[\s\S]*?[^\\]\1/g,validFunctionCall:/[a-zA-Z0-9 \]\$\)]/,strictVar:"(?=\\b[^.]|^|\\n| +|\\t|\\W )",escapeHTML:/(?!&#.*?;)[\u00A0-\u9999<>\&]/gm,uniqueDataParser:/{{((@|#[\w])[\s\S]*?)}}/g,dataParser:/{{([^@%][\s\S]*?)}}/g};var allowedFunctionEval=[":","for","if","while","_content_.take","console.log"];function avoidQuotes(e,t){var r=[],n="<%$@>";e=t(e=e.replace(sf.regex.getQuotes,function(e){return r.push(e),n+(r.length-1)+n}));for(var o=0;o=0&&t.item(r)!==this;);return r>-1}),NodeList.prototype.forEach||(NodeList.prototype.forEach=function(e,t){t=t||window;for(var r=0;r=0;i--)n&&o[r][i].selector!==n||t.removeEventListener(r,o[r].splice(i,1),!0)}}else for(var i=0;i?,.\/ ]/;e.getSelector=function(e,t,o){var i=[];void 0===o&&(o=r);for(var l=t?"previousSibling":"previousElementSibling";null!==e.parentNode;){if(e.id&&!n.test(e.id)){i.unshift("#"+e.id);break}if(e===o)void 0===t?i.unshift(e.tagName):i.unshift(0);else{for(var a=e,s=t?0:1;a[l];)a=a[l],s++;t?i.unshift(s):i.unshift(":nth-child("+s+")")}if(null===(e=e.parentNode))break}return t?i:i.join(" > ")},e.childIndexes=function(e,t){var n=t||r,o=1;if(e[0].constructor===String&&n.id!==e[0].substr(1))n=n.querySelector(e[0]);else if(1===e.length)return n;for(o=o;o=0;r--)0!==$('link[href*="'+t[r]+'"]').length&&t.splice(r,1);if(0===t.length)return}e.turnedOff=!1,e.totalContent=e.totalContent+t.length;for(r=0;r=0;r--)0!==$('script[src*="'+t[r]+'"]').length&&t.splice(r,1);if(0===t.length)return}e.turnedOff=!1,e.totalContent=e.totalContent+t.length;for(r=0;r=0;r--)-1!==t[r].indexOf("$")&&t.splice(r,1);return t};var templateParser_regex=/{{%=([0-9]+)/gm,REF_DIRECT=0,REF_IF=1,REF_EXEC=2,templateExec=function(e,t,r){for(var n={},o=0;o"),r&&(e=e.replace(s,function(e){return"_model_."+e[0].slice(1)})),e.replace(a,function(e,t){return"_modelScope."+t})}).split("_model_._modelScope.").join("_model_."),"#noEval"===o){n=n.trim();var d=u.indexOf(n);return-1===d?(u.push(n),i.push({type:REF_DIRECT,data:[n,t,l]}),"{{%="+(u.length+f-1)):"{{%="+(d+f)}return(n=""+localEval.apply(self.root,[o+n,t,l])).replace(sf.regex.escapeHTML,function(e){return"&#"+e.charCodeAt(0)+";"})});return"#noEval"===o&&(u=l=t=r=n=o=a=s=e=null,setTimeout(function(){d=null},1)),d},uniqueDataParser=function(e,t,r,n,o){var i={length:0,take:function(e,o){if(null===e)return dataParser(this[o],t,r,n);var i='"use strict";var ',l=!0;for(var a in e)"string"==typeof e[a]?e[a]='"'+e[a].split('"').join('\\"')+'"':"object"==typeof e[a]&&(e[a]=JSON.stringify(e[a])),l||(i+=","),i+=a+" = "+e[a],l=!1;return!0===l&&(i=i.replace("var ","")),i=i.split("(").join("(").split(")").join(")"),dataParser(this[o],t,r,n,i+";")}};e=e.replace(/{\[([\s\S]*?)\]}/g,function(e,t){return!1===/{{.*?}}/.test(t)?"_result_ += '"+t.split("'").join("\\'")+"'":(i[i.length]=t,i.length++,"_result_ += _content_.take(&VarPass&, "+(i.length-1)+");")});var l=self.root[n],a=RegExp(sf.regex.strictVar+"("+self.modelKeys(l).join("|")+")\\b","g");if(r)var s=RegExp(sf.regex.strictVar+r+"\\.\\b","g");if("#noEval"===o)var u=[];var f=e.replace(sf.regex.uniqueDataParser,function(e,n){n=avoidQuotes(n,function(e){return e=e.split("&").join("&").split("<").join("<").split(">").join(">"),r&&(e=e.replace(s,function(e){return"_model_."+e[0].slice(1)})),e.replace(a,function(e,t){return"_modelScope."+t})}).split("_model_._modelScope.").join("_model_.");for(var f=!1,d=/(var|let)([\w,\s]+)(?=\s(?==|in|of))/g,c=[],p=null;null!==(p=d.exec(n));)c.push(p[2]);if(null===t&&"#noEval"===o&&c.push("_model_"),0!==c.length){for(var v=[],m=0;m=a?t.$virtual.dom:l);for(M=0;Mo){var y=m[o];o=m[r],r=y}else r=m[r],o=m[o];var E=o.nextSibling,C=o.parentNode;return r.parentNode.insertBefore(o,r.nextSibling),C.insertBefore(r,E),void(void 0!==v&&v.update&&(v.update(m[o],"swap"),v.update(m[r],"swap")))}if("removeRange"!==n){if("remove"!==n){if("update"===n){var $;void 0===r?(r=0,o=t.length):void 0===o?o=r+1:o<0?o=t.length+o:o+=r,($=t.length-o)<0&&(o+=$);for(M=r;M=a?(null===t.$virtual.vCursor.floor&&(t.$virtual.vCursor.floor=D),t.$virtual.dom.appendChild(D)):m[r-1].insertAdjacentElement("afterEnd",D),void(void 0!==v&&v.create&&v.create(D));l.appendChild(D),void 0!==v&&v.create&&v.create(D)}}}else if(m[r]){var T=!1,S=function(){T||(T=!0,m[r].remove())};void 0!==v&&v.remove&&v.remove(m[r],S)||S()}}else for(M=r;M=n&&0!==n){var u=n,f=arguments[0];for(a=0;a0&&(t.$virtual.DOMCursor--,t.$virtual.reinitCursor());else if("splice"===r){if(0===arguments[0]&&void 0===arguments[1])return e;var c=arguments[0];c<0&&(c=n+c);var p=arguments[1];p||0===p||(p=this.length);for(a=p-1;a>=0;a--)m(c+a,"remove");if(t.$virtual&&t.$virtual.DOMCursor>=c&&(t.$virtual.DOMCursor=c-p),arguments.length>=3){p=arguments.length-2,c>=this.length&&(c=this.length-1);for(a=0;a=c&&(t.$virtual.DOMCursor+=p)}}else if("unshift"===r){if(1===arguments.length)m(0,"prepend");else for(a=arguments.length-1;a>=0;a--)m(a,"prepend");t.$virtual&&0!==t.$virtual.DOMCursor&&(t.$virtual.DOMCursor+=arguments.length,t.$virtual.reinitCursor())}else"softRefresh"===r?(m(arguments[0],"update",arguments[1]),t.$virtual&&t.$virtual.DOMCursor&&t.$virtual.reinitCursor()):"hardRefresh"===r&&(m(arguments[0]||0,"hardRefresh"),t.$virtual&&(t.$virtual.DOMCursor=arguments[0]||0));return e}})};l&&l.classList.contains("sf-virtual-list")&&(delete t.$virtual,t.$virtual={},t.$virtual.dom=a,void 0!==v?t.$virtual.callback=v:t.$virtual.callback_={ref:c,var:p},l.replaceChild(e.html,f[1]),sf.internal.virtual_scroll.handle(t,i,l),e.html.remove());for(var g=0;g=0;o--){var i=r[o];if(void 0!==t||-1===excludes.indexOf(i.nodeName))if(1===i.nodeType){if(!0===enclosedHTMLParse)continue;var l=i.attributes;if(l["sf-bind-key"]||l["sf-repeat-this"]||l["sf-bind-list"])continue;for(var a=0;au)){enclosedHTMLParse=!0;continue}if(-1!==i.nodeValue.indexOf("{{")){if(void 0===t){n.push(i.parentNode);break}n.push(i)}}}return n},self.parsePreprocess=function(e,t){for(var r=0;r=0?"&":"?",l=n.method.toUpperCase();if(("GET"===l||"HEAD"===l||"OPTIONS"===l||"DELETE"===l)&&n.data){var a=void 0;(a="string"==typeof n.data?n.data.indexOf("?")>=0?n.data.split("?")[1]:n.data:serializeQuery(n.data)).length&&(n.url+=i+a,"?"===i&&(i="&"))}if("json"===n.dataType&&n.url.indexOf("callback=")>=0){var s,u="jsonp_"+(Date.now()+(jsonpRequests+=1)),f=n.url.split("callback="),d=f[0]+"callback="+u;if(f[1].indexOf("&")>=0){var c=f[1].split("&").filter(function(e){return e.indexOf("=")>0}).join("&");c.length>0&&(d+="&"+c)}var p=document.createElement("script");return p.type="text/javascript",p.onerror=function(){clearTimeout(s),o("error",null,"scripterror"),o("complete",null,"scripterror")},p.src=d,window[u]=function(e){clearTimeout(s),o("success",e),p.parentNode.removeChild(p),p=null,delete window[u]},document.querySelector("head").appendChild(p),void(n.timeout>0&&(s=setTimeout(function(){p.parentNode.removeChild(p),p=null,o("error",null,"timeout")},n.timeout)))}"GET"!==l&&"HEAD"!==l&&"OPTIONS"!==l&&"DELETE"!==l||!1===n.cache&&(n.url+=i+"_nocache"+Date.now());var v=new XMLHttpRequest;if(v.requestUrl=n.url,v.requestParameters=n,!1===o("beforeOpen",v,n))return v;v.open(l,n.url,n.async,n.user,n.password);var m,h=null;if(("POST"===l||"PUT"===l||"PATCH"===l)&&n.data)if(n.processData)if([ArrayBuffer,Blob,Document,FormData].indexOf(n.data.constructor)>=0)h=n.data;else{var g="---------------------------"+Date.now().toString(16);"multipart/form-data"===n.contentType?v.setRequestHeader("Content-Type","multipart/form-data; boundary="+g):v.setRequestHeader("Content-Type",n.contentType),h="";var b=serializeQuery(n.data);if("multipart/form-data"===n.contentType){b=b.split("&");for(var y=[],E=0;E=200&&v.status<300||0===v.status){var e=void 0;if("json"===n.dataType){var t=void 0;try{e=JSON.parse(v.responseText)}catch(e){t=!0}t?o("error",v,"parseerror"):o("success",e,v.status,v)}else o("success",e="text"===v.responseType||""===v.responseType?v.responseText:v.response,v.status,v)}else o("error",v,v.status);n.statusCode&&(globals.statusCode&&globals.statusCode[v.status]&&globals.statusCode[v.status](v),n.statusCode[v.status]&&n.statusCode[v.status](v)),o("complete",v,v.status)},v.onerror=function(){m&&clearTimeout(m),o("error",v,v.status),o("complete",v,"error")},n.timeout>0&&(v.onabort=function(){m&&clearTimeout(m)},m=setTimeout(function(){v.abort(),o("error",v,"timeout"),o("complete",v,"timeout")},n.timeout)),!1===o("beforeSend",v,n)?v:(v.send(h),v)}}function RequestShortcut(e){for(var t=[],r=1;r").join("--\x3e"),!isEmptyObject(u=JSON.parse(u))))for(var d=0;d title").innerHTML=u.title),v=!0},v=!1;for(var m in e.lazyViewPoint){if(-1!==r.indexOf(m))for(var h in e.lazyViewPoint[m])if(-1!==r.indexOf(m)){p(e.lazyViewPoint[m][h]);break}if(v)break}if(!v&&(sf.router.lazyViewPoint["@default"]&&p(sf.router.lazyViewPoint["@default"]),!v))for(d=0;d=n.length-n.$virtual.preparedLength?r.floor=n.$virtual.dCursor.floor.offsetTop+2*n.$virtual.scrollHeight:(r.floor=o.children[e.prepareCount+3].offsetTop,o.hasAttribute("scroll-reduce-floor")&&(r.floor-=o.getAttribute("scroll-reduce-floor"),r.ceiling-=o.getAttribute("scroll-reduce-floor"))),r.ceiling-=r.initial,r.floor-=r.initial}function o(e,t,o,i,l){var a=t.$virtual,s=0;if(e>=t.length-a.preparedLength&&(s-=o,e=t.length-a.preparedLength),!(e-a.DOMCursor==0||e>=t.length)){if(r=!0,0===a.DOMCursor&&ee&&a.DOMCursor+o=o?e0&&(u-=1),f=l.scrollTop-i.children[d].offsetTop}if(e||i.childElementCount-2>t.$virtual.preparedLength){t.$virtual.DOMCursor=t.length;var p=u;e||(p=u<=r?u:u+r),o(p,t,r,i,l),l.scrollTop+=f}s&&s(u),a&&a(),n(u,t.$virtual.bounding,t,i)}e.prepareCount=4,e.handle=function(f,d,c){t||(!function(){var e=document.getElementById("sf-styles");e||((e=document.createElement("style")).id="sf-styles",document.head.appendChild(e));e.sheet.insertRule(".sf-virtual-list .virtual-spacer{visibility: hidden;position: relative;height: 1px;transform-origin: 0 0;width: 1px;margin: 0;padding: 0;background: none;border: none;box-shadow: none;}",e.sheet.cssRules.length)}(),t=!0);var p=f.$virtual;p.reset=function(e){p.DOMCursor=0,p.bounding.ceiling=-1,p.bounding.floor=0,p.vCursor.ceiling=null,p.vCursor.floor=p.dom.firstElementChild,p.bounding.initial=p.dCursor.ceiling.offsetTop,n(0,p.bounding,f,c)},p.reinitCursor=function(){p.vCursor.ceiling=p.dom.children[p.DOMCursor-1]||null,p.vCursor.floor=p.dom.children[p.DOMCursor]||null},p.reinitScroll=function(){n(p.DOMCursor,p.bounding,f,c)},p.elements=function(){return function(e,t){for(var r=[],n=void 0,o=e.$virtual.DOMCursor,i=0;i=0;t--)s[t].element===e&&s.splice(t,1)}(c),delete f.$virtual},p.resetViewport=function(){p.visibleLength=Math.floor(v.clientHeight/p.scrollHeight),p.preparedLength=p.visibleLength+2*e.prepareCount,p.preparedLength<18&&(p.preparedLength=18)},setTimeout(function(){v=c;for(var t=c.getAttribute("scroll-parent-index")||0,d=0;d0&&(b-=l(r)),c.DOMCursorC.floor&&(!function(){var r=null;if(E(),null!==m.floor){null===m.ceiling&&(m.ceiling=m.floor.previousElementSibling);for(var n=0;n0&&(y-=l(r))}(y<0||null===r)&&(y=0);for(var o=f.childElementCount-2-t.$virtual.preparedLength,n=0;n=0;t--)(e=s[t]).element.scrollHeight!==e.height&&e.element.scrollWidth!==e.width&&(null!==e.element.parentElement?e.callback():s.splice(t,1));0===s.length&&(clearInterval(u),u=-1)},1e3));s.push({element:e,callback:t,height:e.scrollHeight,width:e.scrollWidth})}(f,function(){n(c.DOMCursor,C,t,f)})}(f,0,c,v)):function(t,l,s,u){for(var f=t.$virtual,d=f.dCursor.ceiling,c=f.dCursor.floor,p=f.preparedLength<=t.length?f.preparedLength:t.length,v=0;v=e.prepareCount)d.style.height=(r-e.prepareCount)*f.scrollHeight+"px",c.style.height=(t.length-f.preparedLength-r)*f.scrollHeight+"px";else{d.style.height=r*f.scrollHeight+"px";var n=t.length-f.preparedLength;c.style.height=(n||0)*f.scrollHeight+"px"}}f.refreshVirtualSpacer=m;var h=f.bounding;if(m(0),n(e.prepareCount,h,t,s),h.ceiling=-1,f.offsetTo=function(e){return e*f.scrollHeight+d.offsetTop},f.vCursor.floor=f.dom.firstElementChild,f.scrollTo=function(r){o(r,t,e.prepareCount,s,u)},f.refresh=function(r){a(r,t,e.prepareCount,s,u,C,m)},void 0!==f.callback_){var g=f.callback_;delete f.callback_}var b=!1,y=!0,E=!1;function C(){if(b||r||u.scrollTop>=h.ceiling&&u.scrollTop<=h.floor)E&&(0!==u.scrollTop&&u.scrollTop!==u.scrollHeight-u.clientHeight||(i(u),E=!1));else{var o=Math.floor(u.scrollTop/f.scrollHeight);o+f.preparedLength>t.length&&(o=t.length-f.preparedLength),y&&(o<2*e.prepareCount&&(o-=e.prepareCount),E&&(i(u),E=!1),y=!1),o=t.length&&(l=o+l-t.length),0!==l?(f.DOMCursor=o,function(e,t){var r=t.$virtual.dom,n=t.$virtual.vCursor,o=t.$virtual.dCursor;if(e>0){for(var i=0,l=0;l0;l--)null===n.ceiling?(n.ceiling=o.ceiling.nextElementSibling,r.insertAdjacentElement("afterBegin",n.ceiling)):(i=o.ceiling.nextElementSibling,n.ceiling.insertAdjacentElement("afterEnd",i),n.ceiling=i);n.floor=n.ceiling.nextElementSibling}else if(e<0){var i=0;e=-e;for(var l=0;l\&]/gm,uniqueDataParser:/{{((@|#[\w])[\s\S]*?)}}/g,dataParser:/{{([^@%][\s\S]*?)}}/g};var allowedFunctionEval=[":","for","if","while","_content_.take","console.log"];function avoidQuotes(e,t){var r=[],n="<%$@>";e=t(e=e.replace(sf.regex.getQuotes,function(e){return r.push(e),n+(r.length-1)+n}));for(var o=0;o=0&&t.item(r)!==this;);return r>-1}),NodeList.prototype.forEach||(NodeList.prototype.forEach=function(e,t){t=t||window;for(var r=0;r=0;i--)n&&o[r][i].selector!==n||t.removeEventListener(r,o[r].splice(i,1),!0)}}else for(var i=0;i?,.\/ ]/;e.getSelector=function(e,t,o){var i=[];void 0===o&&(o=r);for(var l=t?"previousSibling":"previousElementSibling";null!==e.parentNode;){if(e.id&&!n.test(e.id)){i.unshift("#"+e.id);break}if(e===o)void 0===t?i.unshift(e.tagName):i.unshift(0);else{for(var a=e,s=t?0:1;a[l];)a=a[l],s++;t?i.unshift(s):i.unshift(":nth-child("+s+")")}if(null===(e=e.parentNode))break}return t?i:i.join(" > ")},e.childIndexes=function(e,t){var n=t||r,o=1;if(e[0].constructor===String&&n.id!==e[0].substr(1))n=n.querySelector(e[0]);else if(1===e.length)return n;for(o=o;o=0;r--)0!==$('link[href*="'+t[r]+'"]').length&&t.splice(r,1);if(0===t.length)return}e.turnedOff=!1,e.totalContent=e.totalContent+t.length;for(r=0;r=0;r--)0!==$('script[src*="'+t[r]+'"]').length&&t.splice(r,1);if(0===t.length)return}e.turnedOff=!1,e.totalContent=e.totalContent+t.length;for(r=0;r=0;r--)-1!==t[r].indexOf("$")&&t.splice(r,1);return t};var templateParser_regex=/{{%=([0-9]+)/gm,REF_DIRECT=0,REF_IF=1,REF_EXEC=2,templateExec=function(e,t,r){for(var n={},o=0;o"),r&&(e=e.replace(s,function(e){return"_model_."+e[0].slice(1)})),e.replace(a,function(e,t){return"_modelScope."+t})}).split("_model_._modelScope.").join("_model_."),"#noEval"===o){n=n.trim();var d=u.indexOf(n);return-1===d?(u.push(n),i.push({type:REF_DIRECT,data:[n,t,l]}),"{{%="+(u.length+f-1)):"{{%="+(d+f)}return(n=""+localEval.apply(self.root,[o+n,t,l])).replace(sf.regex.escapeHTML,function(e){return"&#"+e.charCodeAt(0)+";"})});return"#noEval"===o&&(u=l=t=r=n=o=a=s=e=null,setTimeout(function(){d=null},1)),d},uniqueDataParser=function(e,t,r,n,o){var i={length:0,take:function(e,o){if(null===e)return dataParser(this[o],t,r,n);var i='"use strict";var ',l=!0;for(var a in e)"string"==typeof e[a]?e[a]='"'+e[a].split('"').join('\\"')+'"':"object"==typeof e[a]&&(e[a]=JSON.stringify(e[a])),l||(i+=","),i+=a+" = "+e[a],l=!1;return!0===l&&(i=i.replace("var ","")),i=i.split("(").join("(").split(")").join(")"),dataParser(this[o],t,r,n,i+";")}};e=e.replace(/{\[([\s\S]*?)\]}/g,function(e,t){return!1===/{{.*?}}/.test(t)?"_result_ += '"+t.split("'").join("\\'")+"'":(i[i.length]=t,i.length++,"_result_ += _content_.take(&VarPass&, "+(i.length-1)+");")});var l=self.root[n],a=RegExp(sf.regex.strictVar+"("+self.modelKeys(l).join("|")+")\\b","g");if(r)var s=RegExp(sf.regex.strictVar+r+"\\.\\b","g");if("#noEval"===o)var u=[];var f=e.replace(sf.regex.uniqueDataParser,function(e,n){n=avoidQuotes(n,function(e){return e=e.split("&").join("&").split("<").join("<").split(">").join(">"),r&&(e=e.replace(s,function(e){return"_model_."+e[0].slice(1)})),e.replace(a,function(e,t){return"_modelScope."+t})}).split("_model_._modelScope.").join("_model_.");for(var f=!1,d=/(var|let)([\w,\s]+)(?=\s(?==|in|of))/g,c=[],p=null;null!==(p=d.exec(n));)c.push(p[2]);if(null===t&&"#noEval"===o&&c.push("_model_"),0!==c.length){for(var v=[],m=0;m=a?t.$virtual.dom:l);for(M=0;Mo){var y=m[o];o=m[r],r=y}else r=m[r],o=m[o];var E=o.nextSibling,C=o.parentNode;return r.parentNode.insertBefore(o,r.nextSibling),C.insertBefore(r,E),void(void 0!==v&&v.update&&(v.update(m[o],"swap"),v.update(m[r],"swap")))}if("removeRange"!==n){if("remove"!==n){if("update"===n){var $;void 0===r?(r=0,o=t.length):void 0===o?o=r+1:o<0?o=t.length+o:o+=r,($=t.length-o)<0&&(o+=$);for(M=r;M=a?(null===t.$virtual.vCursor.floor&&(t.$virtual.vCursor.floor=D),t.$virtual.dom.appendChild(D)):m[r-1].insertAdjacentElement("afterEnd",D),void(void 0!==v&&v.create&&v.create(D));l.appendChild(D),void 0!==v&&v.create&&v.create(D)}}}else if(m[r]){var T=!1,S=function(){T||(T=!0,m[r].remove())};void 0!==v&&v.remove&&v.remove(m[r],S)||S()}}else for(M=r;M=n&&0!==n){var u=n,f=arguments[0];for(a=0;a0&&(t.$virtual.DOMCursor--,t.$virtual.reinitCursor());else if("splice"===r){if(0===arguments[0]&&void 0===arguments[1])return e;var c=arguments[0];c<0&&(c=n+c);var p=arguments[1];p||0===p||(p=this.length);for(a=p-1;a>=0;a--)m(c+a,"remove");if(t.$virtual&&t.$virtual.DOMCursor>=c&&(t.$virtual.DOMCursor=c-p),arguments.length>=3){p=arguments.length-2,c>=this.length&&(c=this.length-1);for(a=0;a=c&&(t.$virtual.DOMCursor+=p)}}else if("unshift"===r){if(1===arguments.length)m(0,"prepend");else for(a=arguments.length-1;a>=0;a--)m(a,"prepend");t.$virtual&&0!==t.$virtual.DOMCursor&&(t.$virtual.DOMCursor+=arguments.length,t.$virtual.reinitCursor())}else"softRefresh"===r?(m(arguments[0],"update",arguments[1]),t.$virtual&&t.$virtual.DOMCursor&&t.$virtual.reinitCursor()):"hardRefresh"===r&&(m(arguments[0]||0,"hardRefresh"),t.$virtual&&(t.$virtual.DOMCursor=arguments[0]||0));return e}})};l&&l.classList.contains("sf-virtual-list")&&(delete t.$virtual,t.$virtual={},t.$virtual.dom=a,void 0!==v?t.$virtual.callback=v:t.$virtual.callback_={ref:c,var:p},l.replaceChild(e.html,f[1]),sf.internal.virtual_scroll.handle(t,i,l),e.html.remove());for(var g=0;g=0;o--){var i=r[o];if(void 0!==t||-1===excludes.indexOf(i.nodeName))if(1===i.nodeType){if(!0===enclosedHTMLParse)continue;var l=i.attributes;if(l["sf-bind-key"]||l["sf-repeat-this"]||l["sf-bind-list"])continue;for(var a=0;au)){enclosedHTMLParse=!0;continue}if(-1!==i.nodeValue.indexOf("{{")){if(void 0===t){n.push(i.parentNode);break}n.push(i)}}}return n},self.parsePreprocess=function(e,t){for(var r=0;r=0?"&":"?",l=n.method.toUpperCase();if(("GET"===l||"HEAD"===l||"OPTIONS"===l||"DELETE"===l)&&n.data){var a=void 0;(a="string"==typeof n.data?n.data.indexOf("?")>=0?n.data.split("?")[1]:n.data:serializeQuery(n.data)).length&&(n.url+=i+a,"?"===i&&(i="&"))}if("json"===n.dataType&&n.url.indexOf("callback=")>=0){var s,u="jsonp_"+(Date.now()+(jsonpRequests+=1)),f=n.url.split("callback="),d=f[0]+"callback="+u;if(f[1].indexOf("&")>=0){var c=f[1].split("&").filter(function(e){return e.indexOf("=")>0}).join("&");c.length>0&&(d+="&"+c)}var p=document.createElement("script");return p.type="text/javascript",p.onerror=function(){clearTimeout(s),o("error",null,"scripterror"),o("complete",null,"scripterror")},p.src=d,window[u]=function(e){clearTimeout(s),o("success",e),p.parentNode.removeChild(p),p=null,delete window[u]},document.querySelector("head").appendChild(p),void(n.timeout>0&&(s=setTimeout(function(){p.parentNode.removeChild(p),p=null,o("error",null,"timeout")},n.timeout)))}"GET"!==l&&"HEAD"!==l&&"OPTIONS"!==l&&"DELETE"!==l||!1===n.cache&&(n.url+=i+"_nocache"+Date.now());var v=new XMLHttpRequest;if(v.requestUrl=n.url,v.requestParameters=n,!1===o("beforeOpen",v,n))return v;v.open(l,n.url,n.async,n.user,n.password);var m,h=null;if(("POST"===l||"PUT"===l||"PATCH"===l)&&n.data)if(n.processData)if([ArrayBuffer,Blob,Document,FormData].indexOf(n.data.constructor)>=0)h=n.data;else{var g="---------------------------"+Date.now().toString(16);"multipart/form-data"===n.contentType?v.setRequestHeader("Content-Type","multipart/form-data; boundary="+g):v.setRequestHeader("Content-Type",n.contentType),h="";var b=serializeQuery(n.data);if("multipart/form-data"===n.contentType){b=b.split("&");for(var y=[],E=0;E=200&&v.status<300||0===v.status){var e=void 0;if("json"===n.dataType){var t=void 0;try{e=JSON.parse(v.responseText)}catch(e){t=!0}t?o("error",v,"parseerror"):o("success",e,v.status,v)}else o("success",e="text"===v.responseType||""===v.responseType?v.responseText:v.response,v.status,v)}else o("error",v,v.status);n.statusCode&&(globals.statusCode&&globals.statusCode[v.status]&&globals.statusCode[v.status](v),n.statusCode[v.status]&&n.statusCode[v.status](v)),o("complete",v,v.status)},v.onerror=function(){m&&clearTimeout(m),o("error",v,v.status),o("complete",v,"error")},n.timeout>0&&(v.onabort=function(){m&&clearTimeout(m)},m=setTimeout(function(){v.abort(),o("error",v,"timeout"),o("complete",v,"timeout")},n.timeout)),!1===o("beforeSend",v,n)?v:(v.send(h),v)}}function RequestShortcut(e){for(var t=[],r=1;r").join("--\x3e"),!isEmptyObject(u=JSON.parse(u))))for(var d=0;d title").innerHTML=u.title),v=!0},v=!1;for(var m in e.lazyViewPoint){if(-1!==r.indexOf(m))for(var h in e.lazyViewPoint[m])if(-1!==r.indexOf(m)){p(e.lazyViewPoint[m][h]);break}if(v)break}if(!v&&(sf.router.lazyViewPoint["@default"]&&p(sf.router.lazyViewPoint["@default"]),!v))for(d=0;d=n.length-n.$virtual.preparedLength?r.floor=n.$virtual.dCursor.floor.offsetTop+2*n.$virtual.scrollHeight:(r.floor=o.children[e.prepareCount+3].offsetTop,o.hasAttribute("scroll-reduce-floor")&&(r.floor-=o.getAttribute("scroll-reduce-floor"),r.ceiling-=o.getAttribute("scroll-reduce-floor"))),r.ceiling-=r.initial,r.floor-=r.initial}function o(e,t,o,i,l){var a=t.$virtual,s=0;if(e>=t.length-a.preparedLength&&(s-=o,e=t.length-a.preparedLength),!(e-a.DOMCursor==0||e>=t.length)){if(r=!0,0===a.DOMCursor&&ee&&a.DOMCursor+o=o?e0&&(u-=1),f=l.scrollTop-i.children[d].offsetTop}if(e||i.childElementCount-2>t.$virtual.preparedLength){t.$virtual.DOMCursor=t.length;var p=u;e||(p=u<=r?u:u+r),o(p,t,r,i,l),l.scrollTop+=f}s&&s(u),a&&a(),n(u,t.$virtual.bounding,t,i)}e.prepareCount=4,e.handle=function(f,d,c){t||(!function(){var e=document.getElementById("sf-styles");e||((e=document.createElement("style")).id="sf-styles",document.head.appendChild(e));e.sheet.insertRule(".sf-virtual-list .virtual-spacer{visibility: hidden;position: relative;height: 1px;transform-origin: 0 0;width: 1px;margin: 0;padding: 0;background: none;border: none;box-shadow: none;}",e.sheet.cssRules.length)}(),t=!0);var p=f.$virtual;p.reset=function(e){p.DOMCursor=0,p.bounding.ceiling=-1,p.bounding.floor=0,p.vCursor.ceiling=null,p.vCursor.floor=p.dom.firstElementChild,p.bounding.initial=p.dCursor.ceiling.offsetTop,n(0,p.bounding,f,c)},p.reinitCursor=function(){p.vCursor.ceiling=p.dom.children[p.DOMCursor-1]||null,p.vCursor.floor=p.dom.children[p.DOMCursor]||null},p.reinitScroll=function(){n(p.DOMCursor,p.bounding,f,c)},p.elements=function(){return function(e,t){for(var r=[],n=void 0,o=e.$virtual.DOMCursor,i=0;i=0;t--)s[t].element===e&&s.splice(t,1)}(c),delete f.$virtual},p.resetViewport=function(){p.visibleLength=Math.floor(v.clientHeight/p.scrollHeight),p.preparedLength=p.visibleLength+2*e.prepareCount,p.preparedLength<18&&(p.preparedLength=18)},setTimeout(function(){v=c;for(var t=c.getAttribute("scroll-parent-index")||0,d=0;d0&&(b-=l(r)),c.DOMCursorC.floor&&(!function(){var r=null;if(E(),null!==m.floor){null===m.ceiling&&(m.ceiling=m.floor.previousElementSibling);for(var n=0;n0&&(y-=l(r))}(y<0||null===r)&&(y=0);for(var o=f.childElementCount-2-t.$virtual.preparedLength,n=0;n=0;t--)(e=s[t]).element.scrollHeight!==e.height&&e.element.scrollWidth!==e.width&&(null!==e.element.parentElement?e.callback():s.splice(t,1));0===s.length&&(clearInterval(u),u=-1)},1e3));s.push({element:e,callback:t,height:e.scrollHeight,width:e.scrollWidth})}(f,function(){n(c.DOMCursor,C,t,f)})}(f,0,c,v)):function(t,l,s,u){for(var f=t.$virtual,d=f.dCursor.ceiling,c=f.dCursor.floor,p=f.preparedLength<=t.length?f.preparedLength:t.length,v=0;v=e.prepareCount)d.style.height=(r-e.prepareCount)*f.scrollHeight+"px",c.style.height=(t.length-f.preparedLength-r)*f.scrollHeight+"px";else{d.style.height=r*f.scrollHeight+"px";var n=t.length-f.preparedLength;c.style.height=(n||0)*f.scrollHeight+"px"}}f.refreshVirtualSpacer=m;var h=f.bounding;if(m(0),n(e.prepareCount,h,t,s),h.ceiling=-1,f.offsetTo=function(e){return e*f.scrollHeight+d.offsetTop},f.vCursor.floor=f.dom.firstElementChild,f.scrollTo=function(r){o(r,t,e.prepareCount,s,u)},f.refresh=function(r){a(r,t,e.prepareCount,s,u,C,m)},void 0!==f.callback_){var g=f.callback_;delete f.callback_}var b=!1,y=!0,E=!1;function C(){if(b||r||u.scrollTop>=h.ceiling&&u.scrollTop<=h.floor)E&&(0!==u.scrollTop&&u.scrollTop!==u.scrollHeight-u.clientHeight||(i(u),E=!1));else{var o=Math.floor(u.scrollTop/f.scrollHeight);o+f.preparedLength>t.length&&(o=t.length-f.preparedLength),y&&(o<2*e.prepareCount&&(o-=e.prepareCount),E&&(i(u),E=!1),y=!1),o=t.length&&(l=o+l-t.length),0!==l?(f.DOMCursor=o,function(e,t){var r=t.$virtual.dom,n=t.$virtual.vCursor,o=t.$virtual.dCursor;if(e>0){for(var i=0,l=0;l0;l--)null===n.ceiling?(n.ceiling=o.ceiling.nextElementSibling,r.insertAdjacentElement("afterBegin",n.ceiling)):(i=o.ceiling.nextElementSibling,n.ceiling.insertAdjacentElement("afterEnd",i),n.ceiling=i);n.floor=n.ceiling.nextElementSibling}else if(e<0){var i=0;e=-e;for(var l=0;l\\&]/gm,\r\n\r\n\tuniqueDataParser:/{{((@|#[\\w])[\\s\\S]*?)}}/g,\r\n\tdataParser:/{{([^@%][\\s\\S]*?)}}/g,\r\n};\r\n\r\nvar allowedFunctionEval = [':', 'for', 'if', 'while', '_content_.take', 'console.log'];\r\n\r\nfunction avoidQuotes(str, func){\r\n\tvar temp = [];\r\n\tvar es = '<%$@>';\r\n\tstr = str.replace(sf.regex.getQuotes, function(full){\r\n\t\ttemp.push(full);\r\n\t\treturn es+(temp.length-1)+es;\r\n\t});\r\n\tstr = func(str);\r\n\tfor (var i = 0; i < temp.length; i++) {\r\n\t\tstr = str.replace(es+i+es, temp[i]);\r\n\t}\r\n\treturn str;\r\n}\r\n\r\nfunction isEmptyObject(obj){\r\n\tfor(var key in obj){\r\n\t\treturn false;\r\n\t}\r\n\treturn true\r\n}\r\n\r\nfunction compareObject(obj1, obj2){\r\n\tif(!obj1 || !obj2)\r\n\t\treturn false;\r\n\r\n\tfor(var i in obj1){\r\n\t\tif(typeof obj1[i] !== 'object' && obj1[i] !== obj2[i])\r\n\t\t\treturn false;\r\n\t}\r\n\treturn true;\r\n}\r\n\r\nfunction hiddenProperty(obj, property, value){\r\n\tObject.defineProperty(obj, property, {\r\n\t\tenumerable: false,\r\n\t\tconfigurable: true,\r\n\t\tvalue: value\r\n\t});\r\n}\r\n\r\nfunction deepProperty(obj, path){\r\n for(var i = 0; i < path.length; i++){\r\n obj = obj[path[i]];\r\n if(obj === void 0) return obj;\r\n }\r\n return obj;\r\n}","// ==== ES5 Polyfill ====\r\nif(typeof Object.assign != 'function'){\r\n Object.defineProperty(Object, \"assign\", {\r\n value: function assign(target, varArgs) {\r\n 'use strict';\r\n if (target == null)\r\n throw new TypeError('Cannot convert void 0 or null to object');\r\n var to = Object(target);\r\n for (var index = 1; index < arguments.length; index++) {\r\n var nextSource = arguments[index];\r\n if (nextSource != null) {\r\n for (var nextKey in nextSource) {\r\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey))\r\n to[nextKey] = nextSource[nextKey];\r\n }\r\n }\r\n }\r\n return to;\r\n },\r\n writable: true,\r\n configurable: true\r\n });\r\n}\r\n\r\nif(Element.prototype.remove === void 0 || CharacterData.prototype.remove === void 0 || DocumentType.prototype.remove === void 0){\r\n (function (arr) {\r\n arr.forEach(function (item) {\r\n if (item.hasOwnProperty('remove')) {\r\n return;\r\n }\r\n Object.defineProperty(item, 'remove', {\r\n configurable: true,\r\n enumerable: true,\r\n writable: true,\r\n value: function remove() {\r\n if (this.parentNode !== null)\r\n this.parentNode.removeChild(this);\r\n }\r\n });\r\n });\r\n })([Element.prototype, CharacterData.prototype, DocumentType.prototype]);\r\n}\r\n\r\nif(!Element.prototype.matches){\r\n Element.prototype.matches = (Element.prototype).matchesSelector ||\r\n (Element.prototype).mozMatchesSelector || (Element.prototype).msMatchesSelector ||\r\n (Element.prototype).oMatchesSelector || (Element.prototype).webkitMatchesSelector ||\r\n function (s) {\r\n var matches = (this.document || this.ownerDocument).querySelectorAll(s),\r\n i = matches.length;\r\n while (--i >= 0 && matches.item(i) !== this){}\r\n return i > -1;\r\n };\r\n}\r\n\r\nif(!NodeList.prototype.forEach){\r\n NodeList.prototype.forEach = function (callback, thisArg) {\r\n thisArg = thisArg || window;\r\n for (var i = 0; i < this.length; i++) {\r\n callback.call(thisArg, this[i], i, this);\r\n }\r\n };\r\n}\r\n\r\nif(!window.location.origin)\r\n window.location.origin = window.location.protocol + \"//\" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');\r\n\r\nif(!Object.values)\r\n Object.values = function(obj){\r\n var res = [];\r\n for (var i in obj) {\r\n if (obj.hasOwnProperty(i)) {\r\n res.push(obj[i]);\r\n }\r\n }\r\n return res;\r\n }\r\n\r\nif(Object.setPrototypeOf === void 0)\r\n Object.setPrototypeOf = function(obj, proto) {\r\n obj.__proto__ = proto;\r\n return obj; \r\n }\r\n\r\nif(typeof Reflect === 'undefined'){\r\n Reflect = {};\r\n Reflect.construct = function(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; };\r\n}","sf.dom = function(selector, context){\r\n\tif(selector[0] === '<') return sf.dom.parseElement(selector);\r\n\tif(selector.constructor !== String) return selector;\r\n\r\n\tif(context) return context.querySelectorAll(selector);\r\n\treturn document.querySelectorAll(selector);\r\n}\r\n\r\nvar $ = sf.dom; // Shortcut\r\n\r\n;(function(){\r\n\tvar self = sf.dom;\r\n\r\n\tself.findOne = function(selector, context){\r\n\t\tif(context !== void 0) return context.querySelector(selector);\r\n\t\treturn document.querySelector(selector);\r\n\t}\r\n\r\n\tself.parent = function(element, selector){\r\n\t\tif(element.closest) return element.closest(selector);\r\n\r\n\t\tdo {\r\n\t\t\tif(element.matches(selector) === true)\r\n\t\t\t\treturn element;\r\n\r\n\t\t\telement = element.parentElement;\r\n\t\t} while (element !== null);\r\n\r\n\t\treturn null;\r\n\t}\r\n\r\n\tself.prevAll = function(element, selector, isNext){\r\n\t\tvar result = [];\r\n\t\tvar findNodes = selector === null || selector.constructor !== String ? true : false;\r\n\r\n\t\t// Skip current element\r\n\t\telement = isNext ? element.nextSibling : element.previousSibling;\r\n\t\twhile (element !== null) {\r\n\t\t\tif(findNodes === false && element.matches(selector) === true)\r\n\t\t\t\tresult.push(element);\r\n\t\t\telse{\r\n\t\t\t\tif(element === selector)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tresult.push(element);\r\n\t\t\t}\r\n\r\n\t\t\tif(isNext)\r\n\t\t\t\telement = element.nextSibling;\r\n\t\t\telse\r\n\t\t\t\telement = element.previousSibling;\r\n\t\t}\r\n\r\n\t\treturn result;\r\n\t}\r\n\r\n\t// Shorcut\r\n\tself.nextAll = function(element, selector){\r\n\t\treturn self.prevAll(element, selector, true);\r\n\t}\r\n\r\n\t/**\r\n\t * Listen to an event\r\n\t * @param Node \t\t\telement \tparent element\r\n\t * @param string \t\t\tevent \tevent name\r\n\t * @param function|string selector callback function or selector\r\n\t * @param function\t\t\tcallback callback function\r\n\t * @param boolean\t\t\tonce \tcall once\r\n\t * @return null\r\n\t */\r\n\tself.on = function(element, event, selector, callback, once){\r\n\t\tif(typeof element === 'string'){\r\n\t\t\telement = document;\r\n\t\t\tcallback = selector;\r\n\t\t\tselector = event;\r\n\t\t\tevent = element;\r\n\t\t}\r\n\r\n\t\tif(typeof selector === 'function'){\r\n\t\t\tcallback = selector;\r\n\t\t\tselector = null;\r\n\t\t}\r\n\r\n\t\tif(selector){\r\n\t\t\tvar tempCallback = callback;\r\n\t\t\tcallback = function(ev){\r\n\t\t\t\tif(self.parent(ev.target, selector) !== null)\r\n\t\t\t\t\ttempCallback(ev);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tcallback.selector = selector;\r\n\t\tcallback.once = once;\r\n\t\telement.addEventListener(event, callback, {capture:true, once:once === true});\r\n\r\n\t\t// Save event listener\r\n\t\tif(element.sf$eventListener === void 0)\r\n\t\t\telement.sf$eventListener = {};\r\n\r\n\t\tif(element.sf$eventListener[event] === void 0)\r\n\t\t\telement.sf$eventListener[event] = [];\r\n\r\n\t\telement.sf$eventListener[event].push(callback);\r\n\t}\r\n\r\n\t// Shorcut\r\n\tself.once = function(element, event, selector, callback){\r\n\t\tself.on(element, event, selector, callback, true);\r\n\t}\r\n\r\n\t/**\r\n\t * Remove event listener\r\n\t * @param Node \telement \tparent element\r\n\t * @param string \tevent \tevent name\r\n\t * @param string \tselector selector\r\n\t * @return null\r\n\t */\r\n\tself.off = function(element, event, selector){\r\n\t\t// Remove all event\r\n\t\tif(event === void 0){\r\n\t\t\tif(element.sf$eventListener === void 0)\r\n\t\t\t\treturn;\r\n\r\n\t\t\tvar events = element.sf$eventListener[event];\r\n\t\t\tfor (var i = 0; i < events.length; i++) {\r\n\t\t\t\tself.off(element, events[i]);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar events = event.split(' ');\r\n\t\tif(events.length !== 1){\r\n\t\t\tfor (var i = 0; i < events.length; i++) {\r\n\t\t\t\tself.off(element, events[i]);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Remove listener\r\n\t\tif(element.sf$eventListener === void 0)\r\n\t\t\treturn;\r\n\r\n\t\tvar ref = element.sf$eventListener;\r\n\t\tif(ref !== void 0 && ref[event] !== void 0){\r\n\t\t\tfor (var i = ref[event].length - 1; i >= 0; i--) {\r\n\t\t\t\tif(selector && ref[event][i].selector !== selector)\r\n\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\telement.removeEventListener(event, ref[event].splice(i, 1), true);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tself.animateCSS = function(element, animationName, callback, duration) {\r\n\t\tvar animationEnd = {\r\n\t\t\tanimation: 'animationend',\r\n\t\t\tOAnimation: 'oAnimationEnd',\r\n\t\t\tMozAnimation: 'mozAnimationEnd',\r\n\t\t\tWebkitAnimation: 'webkitAnimationEnd',\r\n\t\t};\r\n\r\n\t\tfor (var t in animationEnd){\r\n\t\t\tif(element.style[t] !== void 0){\r\n\t\t\t\tanimationEnd = animationEnd[t];\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif(duration){\r\n\t\t\telement.style.webkitAnimationDuration = duration+'s';\r\n\t\t\telement.style.animationDuration = duration+'s';\r\n\t\t}\r\n\r\n\t\tvar list = ('animated ' + animationName).split(' ');\r\n\t\telement.classList.add.apply(element.classList, list);\r\n\t\t$.once(element, animationEnd, function(){\r\n\t\t\telement.classList.remove.apply(element.classList, list);\r\n\t\t\t\r\n\t\t\tif(duration) setTimeout(function(){\r\n\t\t\t\telement.style.webkitAnimationDuration = duration+'s';\r\n\t\t\t\telement.style.animationDuration = duration+'s';\r\n\t\t\t}, 1);\r\n\r\n\t\t\tif(typeof callback === 'function') callback();\r\n\t\t});\r\n\t}\r\n\r\n\tvar emptyDOM = {\r\n\t\tdiv:document.createElement('div'),\r\n\t\tul:document.createElement('ul'),\r\n\t\ttbody:document.createElement('tbody'),\r\n\t\ttr:document.createElement('tr'),\r\n\t\ttable:document.createElement('table'),\r\n\t\tselect:document.createElement('select'),\r\n\t};\r\n\tself.parseElement = function(html, returnNode){\r\n\t\tvar result = [];\r\n\t\tvar tempDOM = emptyDOM.div;\r\n\r\n if(html.indexOf('?,./ ]/;\r\n\tself.getSelector = function(element, childIndexes, untilElement){\r\n\t\tvar names = [];\r\n\t\tif(untilElement === void 0) untilElement = documentElement;\r\n\r\n\t\tvar previousSibling = childIndexes ? 'previousSibling' : 'previousElementSibling';\r\n\r\n\t\twhile(element.parentNode !== null){\r\n\t\t\tif(element.id && !haveSymbol.test(element.id)){\r\n\t\t\t\tnames.unshift('#'+element.id);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\tif(element === untilElement){\r\n\t\t\t\t\tif(childIndexes === void 0)\r\n\t\t\t\t\t\tnames.unshift(element.tagName);\r\n\t\t\t\t\telse names.unshift(0);\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tvar e = element;\r\n\t\t\t\t\tvar i = childIndexes ? 0 : 1;\r\n\r\n\t\t\t\t\twhile(e[previousSibling]){\r\n\t\t\t\t\t\te = e[previousSibling];\r\n\t\t\t\t\t\ti++;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif(childIndexes)\r\n\t\t\t\t\t\tnames.unshift(i);\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tnames.unshift(\":nth-child(\"+i+\")\");\r\n\t\t\t\t}\r\n\r\n\t\t\t\telement = element.parentNode;\r\n\t\t\t\tif(element === null)\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif(childIndexes)\r\n\t\t\treturn names;\r\n\t\treturn names.join(\" > \");\r\n\t}\r\n\r\n\tself.childIndexes = function(array, context){\r\n\t\tvar element = context || documentElement;\r\n\t\tvar i = 1;\r\n\r\n\t\tif(array[0].constructor === String && element.id !== array[0].substr(1))\r\n\t\t\telement = element.querySelector(array[0]);\r\n\r\n\t\telse if(array.length === 1)\r\n\t\t\treturn element;\r\n\r\n\t\tfor (i = i; i < array.length; i++) {\r\n\t\t\telement = element.childNodes.item(array[i]);\r\n\r\n\t\t\tif(element === null)\r\n\t\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\treturn element;\r\n\t}\r\n\r\n})();","sf.loader = new function(){\r\n\tvar self = this;\r\n\tself.loadedContent = 0;\r\n\tself.totalContent = 0;\r\n\tself.DOMWasLoaded = false;\r\n\tself.DOMReady = false;\r\n\tself.turnedOff = true;\r\n\r\n\tvar whenDOMReady = [];\r\n\tvar whenDOMLoaded = [];\r\n\tvar whenProgress = [];\r\n\r\n\tself.off = function(){\r\n\t\tself.turnedOff = true;\r\n\t}\r\n\r\n\t// Make event listener\r\n\tself.onFinish = function(func){\r\n\t\tif(self.DOMWasLoaded) return func();\r\n\t\tif(whenDOMLoaded.indexOf(func) !== -1) return;\r\n\t\twhenDOMLoaded.push(func);\r\n\t}\r\n\tself.domReady = function(func){\r\n\t\tif(self.DOMReady) return func();\r\n\t\tif(whenDOMReady.indexOf(func) !== -1) return;\r\n\t\twhenDOMReady.push(func);\r\n\t}\r\n\tself.onProgress = function(func){\r\n\t\tif(self.DOMWasLoaded) return func(self.loadedContent, self.totalContent);\r\n\t\tif(whenProgress.indexOf(func) !== -1) return;\r\n\t\twhenProgress.push(func);\r\n\t}\r\n\r\n\tself.f = function(element){\r\n\t\tself.loadedContent++;\r\n\t\tfor (var i = 0; i < whenProgress.length; i++) {\r\n\t\t\twhenProgress[i](self.loadedContent, self.totalContent);\r\n\t\t}\r\n\t}\r\n\r\n\tself.css = function(list){\r\n\t\tif(self.DOMWasLoaded){\r\n\t\t\t// check if some list was loaded\r\n\t\t\tfor (var i = list.length - 1; i >= 0; i--) {\r\n\t\t\t\tif($('link[href*=\"'+list[i]+'\"]').length !== 0)\r\n\t\t\t\t\tlist.splice(i, 1);\r\n\t\t\t}\r\n\t\t\tif(list.length === 0) return;\r\n\t\t}\r\n\t\tself.turnedOff = false;\r\n\r\n\t\tself.totalContent = self.totalContent + list.length;\r\n\t\tfor(var i = 0; i < list.length; i++){\r\n\t\t\tvar s = document.createElement('link');\r\n\t s.rel = 'stylesheet';\r\n\t s.href = list[i];\r\n\t s.addEventListener('load', sf.loader.f, {once:true});\r\n\t s.addEventListener('error', sf.loader.f, {once:true});\r\n\t document.head.appendChild(s);\r\n\t\t}\r\n\t}\r\n\r\n\tself.js = function(list){\r\n\t\tif(self.DOMWasLoaded){\r\n\t\t\t// check if some list was loaded\r\n\t\t\tfor (var i = list.length - 1; i >= 0; i--) {\r\n\t\t\t\tif($('script[src*=\"'+list[i]+'\"]').length !== 0)\r\n\t\t\t\t\tlist.splice(i, 1);\r\n\t\t\t}\r\n\t\t\tif(list.length === 0) return;\r\n\t\t}\r\n\t\tself.turnedOff = false;\r\n\r\n\t\tself.totalContent = self.totalContent + list.length;\r\n\t\tfor(var i = 0; i < list.length; i++){\r\n\t\t\tvar s = document.createElement('script');\r\n\t s.type = \"text/javascript\";\r\n\t s.async = true;\r\n\t s.src = list[i];\r\n\t s.addEventListener('load', sf.loader.f, {once:true});\r\n\t s.addEventListener('error', sf.loader.f, {once:true});\r\n\t document.head.appendChild(s);\r\n\t\t}\r\n\t}\r\n\r\n\tsetTimeout(function(){\r\n\t\tif(self.totalContent === 0 && !self.turnedOff){\r\n\t\t\tself.loadedContent = self.totalContent = 1;\r\n\t\t\tconsole.warn(\"If you don't use content loader feature, please turn it off with `sf.loader.off()`\");\r\n\t\t}\r\n\t}, 10000);\r\n\r\n\r\n\tvar isQueued = false;\r\n\tvar lastState = '';\r\n\tdocument.addEventListener(\"load\", function domLoadEvent(event){\r\n\t\t// Add processing class to queued element\r\n\t\tif(isQueued === false && document.body){\r\n\t\t\tdocument.removeEventListener('load', domLoadEvent, true);\r\n\r\n\t\t\tisQueued = sf.model.queuePreprocess(document.body);\r\n\r\n\t\t\tfor (var i = 0; i < isQueued.length; i++) {\r\n\t\t\t\tisQueued[i].classList.add('sf-dom-queued');\r\n\t\t\t}\r\n\r\n\t\t\tif(isQueued.length === 0) isQueued = false;\r\n\r\n\t\t\tif(lastState === 'loading'){\r\n\t\t\t\tvar repeatedList = $('[sf-repeat-this]', document.body);\r\n\t\t\t\tfor (var i = 0; i < repeatedList.length; i++) {\r\n\t\t\t\t\trepeatedList[i].classList.add('sf-dom-queued');\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Find images\r\n\t\t\t\tvar temp = $('img:not(onload)[src]');\r\n\t\t\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\t\t\tsf.loader.totalContent++;\r\n\t\t\t\t\ttemp[i].addEventListener('load', sf.loader.f, {once:true});\r\n\t\t\t\t\ttemp[i].addEventListener('error', sf.loader.f, {once:true});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}, true);\r\n\r\n\tdocument.addEventListener('readystatechange', function domStateEvent(){\r\n\t\tif(document.readyState === 'interactive' || document.readyState === 'complete'){\r\n\t\t\tif(self.DOMReady === false){\r\n\t\t\t\tself.DOMReady = true;\r\n\t\t\t\tfor (var i = 0; i < whenDOMReady.length; i++) {\r\n\t\t\t\t\ttry{\r\n\t\t\t\t\t\twhenDOMReady[i]();\r\n\t\t\t\t\t} catch(e) {\r\n\t\t\t\t\t\tconsole.error(e);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif(isQueued === false)\r\n\t\t\t\tisQueued = sf.model.queuePreprocess(document.body);\r\n\r\n\t\t\tresourceWaitTimer = setInterval(waitResources, 100);\r\n\t\t\tdocument.removeEventListener('readystatechange', domStateEvent, true);\r\n\t\t}\r\n\t}, true);\r\n\r\n\tvar resourceWaitTimer = -1;\r\n\tfunction waitResources(){\r\n\t\tif(self.turnedOff === false && self.loadedContent < self.totalContent)\r\n\t\t\treturn;\r\n\r\n\t\tclearInterval(resourceWaitTimer);\r\n\r\n\t\tvar listener = sf.dom('script, link, img');\r\n\t\tfor (var i = 0; i < listener.length; i++) {\r\n\t\t\tlistener[i].removeEventListener('error', sf.loader.f);\r\n\t\t\tlistener[i].removeEventListener('load', sf.loader.f);\r\n\t\t}\r\n\r\n\t\tself.DOMWasLoaded = true;\r\n\t\tfor (var i = 0; i < whenDOMLoaded.length; i++) {\r\n\t\t\ttry{\r\n\t\t\t\twhenDOMLoaded[i]();\r\n\t\t\t} catch(e){\r\n\t\t\t\tconsole.error(e);\r\n\t\t\t}\r\n\t\t}\r\n\t\twhenProgress.splice(0);\r\n\t\twhenDOMReady.splice(0);\r\n\t\twhenDOMLoaded.splice(0);\r\n\t\twhenDOMReady = whenDOMLoaded = null;\r\n\r\n\t\t// Last init\r\n\t\tsf.controller.init();\r\n\t\tsf.model.init(document.body, isQueued);\r\n\t\tsf.router.init();\r\n\r\n\t\tisQueued = null;\r\n\t}\r\n}\r\nsf.prototype.constructor = sf.loader.onFinish;","sf.component = new function(){\r\n\tvar self = this;\r\n\tvar scope = internal.component = {};\r\n\tself.registered = {};\r\n\tself.available = {};\r\n\r\n\tvar bases = {};\r\n\tvar events = {};\r\n\r\n\tself.for = function(name, func, extend){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.for(name, func);\r\n\t\t\t});\r\n\r\n\t\tif(self.registered[name] === void 0)\r\n\t\t\tself.registered[name] = [func, sf.controller.pending[name], 0, false, extend];\r\n\t\tself.registered[name][0] = func;\r\n\t\tdelete sf.controller.pending[name];\r\n\r\n\t\tdefineComponent(name);\r\n\t}\r\n\r\n\tself.event = function(name, func){\r\n\t\tevents[name] = func;\r\n\t}\r\n\r\n\tself.base = function(name, func){\r\n\t\tbases[name] = func;\r\n\t}\r\n\r\n\tself.html = function(name, outerHTML){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.html(name, outerHTML);\r\n\t\t\t});\r\n\r\n\t\tif(self.registered[name] === void 0)\r\n\t\t\tself.registered[name] = [false, false, 0, false];\r\n\r\n\t\tvar temp = $.parseElement(outerHTML);\r\n\t\tif(temp.length === 1){\r\n\t\t\tself.registered[name][3] = temp[0];\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar tempDOM = document.createElement('div');\r\n\t\ttempDOM.tempDOM = true;\r\n\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\ttempDOM.appendChild(temp[i]);\r\n\t\t}\r\n\t\tself.registered[name][3] = tempDOM;\r\n\t}\r\n\r\n\tscope.triggerEvent = function(name, event, obj){\r\n\t\tif(events[name] === void 0 || events[name][event] === void 0)\r\n\t\t\treturn;\r\n\r\n\t\tevents[name][event](obj, event);\r\n\t}\r\n\r\n\tvar tempDOM = document.createElement('div');\r\n\tself.new = function(name, element, isCreated, retriggered){\r\n\t\tif(isCreated === true){\r\n\t\t\tif(sf.loader.DOMWasLoaded === false)\r\n\t\t\t\treturn sf(function(){\r\n\t\t\t\t\tself.new(name, element, isCreated);\r\n\t\t\t\t});\r\n\t\t\tif(self.registered[name][3] === false)\r\n\t\t\t\treturn setTimeout(function(){\r\n\t\t\t\t\tself.new(name, element, isCreated, true);\r\n\t\t\t\t}, 0);\r\n\t\t}\r\n\r\n\t\tif(element === void 0)\r\n\t\t\treturn new window['$'+capitalizeLetters(name.split('-'))];\r\n\r\n\t\tvar newElement = element === void 0;\r\n\t\tif(element === void 0){\r\n\t\t\tif(self.registered[name][3] === false){\r\n\t\t\t\tconsole.error(\"HTML content for '\"+name+\"' was not defined\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\telement = self.registered[name][3].cloneNode(true);\r\n\t\t}\r\n\r\n\t\tvar newID = name+'@'+(self.registered[name][2]++);\r\n\r\n\t\tif(self.available[name] === void 0)\r\n\t\t\tself.available[name] = [];\r\n\r\n\t\tself.available[name].push(newID);\r\n\r\n\t\tvar newObj = sf.model.root[newID] = {};\r\n\t\tself.registered[name][0](newObj, sf.model);\r\n\r\n\t\tvar extend = self.registered[name][4];\r\n\t\tif(extend !== void 0){\r\n\t\t\tif(extend.constructor === Array){\r\n\t\t\t\tfor (var i = 0; i < extend.length; i++) {\r\n\t\t\t\t\tif(bases[extend[i]] === void 0)\r\n\t\t\t\t\t\treturn console.error(\"'\"+extend[i]+\"' base is not found\");\r\n\t\t\t\t\tbases[extend[i]](newObj, sf.model);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\tif(bases[extend] === void 0)\r\n\t\t\t\t\treturn console.error(\"'\"+extend+\"' base is not found\");\r\n\t\t\t\tbases[extend](newObj, sf.model);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif(self.registered[name][1])\r\n\t\t\tself.registered[name][1](newObj, sf.model);\r\n\r\n\t\tscope.triggerEvent(name, 'created', newObj);\r\n\r\n\t\tif(newElement !== true && isCreated !== true){\r\n\t\t\tcomponentInit(element, newID, name);\r\n\t\t\telement.model = sf.model.root[newID];\r\n\t\t\treturn newID;\r\n\t\t}\r\n\r\n\t\tvar temp = self.registered[name][3];\r\n\t\tif(temp.tempDOM === true){\r\n\t\t\ttemp = temp.cloneNode(true).childNodes;\r\n\t\t\tfor (var i = 0, n = temp.length; i < n; i++) {\r\n\t\t\t\telement.appendChild(temp[0]);\r\n\t\t\t}\r\n\t\t}\r\n\t\telse element.appendChild(temp.cloneNode(true));\r\n\r\n\t\tif(element.parentNode === null){\r\n\t\t\t// Wrap to temporary vDOM\r\n\t\t\ttempDOM.appendChild(element);\r\n\t\t\tcomponentInit(element, newID, name);\r\n\t\t\tsf.model.init(element);\r\n\t\t\telement = tempDOM.firstElementChild;\r\n\t\t\telement.remove();\r\n\t\t}\r\n\t\telse if(isCreated === true){\r\n\t\t\tcomponentInit(element, newID, name);\r\n\t\t\tsf.model.init(element);\r\n\t\t}\r\n\r\n\t\telement.model = sf.model.root[newID];\r\n\t\telement.destroy = function(){\r\n\t\t\tif(this.parentElement === null)\r\n\t\t\t\tinternal.model.DOMNodeRemoved(this);\r\n\t\t\telse this.remove();\r\n\t\t}\r\n\t\treturn element;\r\n\t}\r\n\r\n\tfunction componentInit(element, newID, from){\r\n\t\telement.setAttribute('sf-controller', '');\r\n\t\telement.sf$component = newID;\r\n\t\telement.sf$componentFrom = from;\r\n\t}\r\n\r\n\tvar HTMLElement = window.HTMLElement;\r\n\tvar customElements = window.customElements;\r\n\r\n\tvar HTMLElement_wrap = (function(Class){\r\n\t\tfunction Wrapper(){\r\n\t\t\treturn Reflect.construct(Class, arguments, Object.getPrototypeOf(this).constructor);\r\n\t\t}\r\n\t\tWrapper.prototype = Object.create(Class.prototype, {constructor:{value: Wrapper, enumerable: false, writable: true, configurable: true}}); \r\n\t\treturn Object.setPrototypeOf(Wrapper, Class);\r\n\t})(HTMLElement);\r\n\r\n\t// name = 'tag-name'\r\n\tfunction defineComponent(name){\r\n\t\tname = name.replace(/[^\\w-]+/g, '');\r\n\t\tvar tagName = name;\r\n\t\tname = name.split('-');\r\n\t\tif(name.length === 1)\r\n\t\t\treturn console.error(\"Please use '-' when defining component tags\");\r\n\r\n\t\tname = capitalizeLetters(name);\r\n\t\tvar func = eval(\"function \"+name+\"(){var he = HTMLElement_wrap.call(this);self.new(tagName, he, true);return he}\"+name);\r\n\t\tfunc.prototype = Object.create(HTMLElement.prototype);\r\n\t\tfunc.prototype.constructor = func;\r\n\t\tfunc.__proto__ = HTMLElement;\r\n\r\n\t\t// func.prototype.connectedCallback = function(){};\r\n\r\n\t\ttry{\r\n\t\t customElements.define(tagName, func);\r\n\t\t}catch(err){console.error(e)}\r\n\r\n\t\twindow['$'+name] = func;\r\n\t}\r\n\r\n\tfunction capitalizeLetters(name){\r\n\t\tfor (var i = 0; i < name.length; i++) {\r\n\t\t\tname[i] = name[i][0].toUpperCase() + name[i].slice(1);\r\n\t\t}\r\n\t\treturn name.join('');\r\n\t}\r\n};","// Data save and HTML content binding\r\nsf.model = function(scope){\r\n\tif(sf.component.registered[scope] !== void 0)\r\n\t\treturn root_(scope);\r\n\r\n\tif(!sf.model.root[scope])\r\n\t\tsf.model.root[scope] = {};\r\n\r\n\tif(sf.controller.pending[scope])\r\n\t\tsf.controller.run(scope);\r\n\r\n\treturn sf.model.root[scope];\r\n};\r\n\r\n(function(){\r\n\tvar self = sf.model;\r\n\tvar scope = internal.model = {};\r\n\tvar bindingEnabled = false;\r\n\tself.root = {};\r\n\r\n\tvar processingElement = null;\r\n\r\n\t// For debugging, normalize indentation\r\n\tfunction trimIndentation(text){\r\n\t\tvar indent = text.split(\"\\n\", 3);\r\n\t\tif(indent[0][0] !== ' ' || indent[0][0] !== \"\\t\")\r\n\t\t\tindent = indent[1];\r\n\t\telse indent = indent[0];\r\n\r\n\t\tif(indent === void 0) return text;\r\n\t\tindent = indent.length - indent.trim().length;\r\n\t\tif(indent === 0) return text;\r\n\t\treturn text.replace(RegExp('^([\\\\t ]{'+indent+'})', 'gm'), '');\r\n\t}\r\n\r\n\t// Secured evaluation\r\n\tvar bracketMatch = RegExp('([\\\\w.]*?[\\\\S\\\\s])\\\\('+sf.regex.avoidQuotes, 'g');\r\n\tvar chackValidFunctionCall = sf.regex.validFunctionCall;\r\n\tvar localEval = function(script, _model_, _modelScope, _content_){\r\n\t\t\"use strict\";\r\n\r\n\t\t// ==== Security check ====\r\n\t\tvar tempScript = script;\r\n\r\n\t\t// Remove all inner quotes\r\n\t\ttempScript = tempScript.replace(sf.regex.getQuotes, '\"Quotes\"');\r\n\r\n\t\t// Prevent vulnerability by remove bracket to avoid a function call\r\n\t\tvar preventExecution = false;\r\n\t\tvar check_ = null;\r\n\t\twhile((check_ = bracketMatch.exec(tempScript)) !== null){\r\n\t\t\tcheck_[1] = check_[1].trim();\r\n\r\n\t\t\tif(allowedFunctionEval.indexOf(check_[1]) === -1 &&\r\n\t\t\t\tcheck_[1].split('.')[0] !== '_modelScope' &&\r\n\t\t\t\tchackValidFunctionCall.test(check_[1][check_[1].length-1])\r\n\t\t\t){\r\n\t\t\t\tpreventExecution = check_[1];\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif(preventExecution){\r\n\t\t\tconsole.error(\"Trying to executing unrecognized function (\"+preventExecution+\")\");\r\n\t\t\tconsole.log(trimIndentation(processingElement.outerHTML).trim());\r\n\t\t\t//console.log(tempScript);\r\n\t\t\treturn '#DOMError';\r\n\t\t}\r\n\t\t// ==== Security check ended ====\r\n\t\r\n\t\tvar _result_ = '';\r\n\t\ttry{\r\n\t\t\tif(/@return /.test(script) === true){\r\n\t\t\t\tvar _evaled_ = eval('(function(){'+script.split('@return ').join('return ')+'})()');\r\n\t\t\t\treturn _result_ + _evaled_;\r\n\t\t\t}\r\n\t\t\telse var _evaled_ = eval(script);\r\n\t\t} catch(e){\r\n\t\t\tconsole.error(e);\r\n\t\t\tconsole.log(trimIndentation(processingElement.outerHTML).trim());\r\n\t\t\t//console.log(tempScript);\r\n\t\t\treturn '#DOMError';\r\n\t\t}\r\n\r\n\t\tif(_result_ !== '') return _result_;\r\n\t\treturn _evaled_;\r\n\t}\r\n\r\n\t// Find an index for the element on the list\r\n\tself.index = function(element){\r\n\t\tvar i = -1;\r\n\t\tvar tagName = element.tagName;\r\n\t\tvar currentElement = element;\r\n\r\n\t\twhile(element !== null) {\r\n\t\t\tif(element.tagName === tagName)\r\n\t\t\t\ti++;\r\n\r\n\t\t\telement = element.previousElementSibling;\r\n\t\t}\r\n\r\n\t\tvar list = currentElement.getAttribute('sf-bind-list');\r\n\t\tif(!list) return i;\r\n\r\n\t\tvar ref = self.root[sf.controller.modelName(currentElement)][list];\r\n\t\tif(!ref.$virtual) return i;\r\n\r\n\t\treturn i + ref.$virtual.DOMCursor - 1;\r\n\t}\r\n\r\n\t// Declare model for the name with a function\r\n\tself.for = function(name, func){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.for(name, func);\r\n\t\t\t});\r\n\t\t\r\n\t\tfunc(self(name), self);\r\n\t}\r\n\r\n\t// Get property of the model\r\n\tself.modelKeys = function(modelRef){\r\n\t\tvar keys = Object.keys(modelRef);\r\n\t\tfor (var i = keys.length - 1; i >= 0; i--) {\r\n\t\t\tif(keys[i].indexOf('$') !== -1)\r\n\t\t\t\tkeys.splice(i, 1);\r\n\t\t}\r\n\t\treturn keys;\r\n\t}\r\n\r\n\t// Escape the escaped quote\r\n\tfunction escapeEscapedQuote(text){\r\n\t\treturn text.split('\\\\\"').join('\\\\$%*').split(\"\\\\'\").join('\\\\%$*');\r\n\t}\r\n\r\n\tfunction unescapeEscapedQuote(text){\r\n\t\treturn text.split('\\\\$%*').join('\\\\\"').split('\\\\%$*').join(\"\\\\'\");\r\n\t}\r\n\r\n\tfunction elseIfHandle(else_, scopes){\r\n\t\tvar elseIf = else_.elseIf;\r\n\r\n\t\t// Else if\r\n\t\tfor (var i = 0; i < elseIf.length; i++) {\r\n\t\t\t// Check the condition\r\n\t\t\tscopes[0] = elseIf[i][0];\r\n\t\t\tif(!localEval.apply(self.root, scopes))\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\t// Get the value\r\n\t\t\tscopes[0] = elseIf[i][1];\r\n\t\t\treturn localEval.apply(self.root, scopes);\r\n\t\t}\r\n\r\n\t\t// Else\r\n\t\tif(else_.elseValue === null)\r\n\t\t\treturn '';\r\n\r\n\t\tscopes[0] = else_.elseValue;\r\n\t\treturn localEval.apply(self.root, scopes);\r\n\t}\r\n\r\n\t// ==== Template parser ====\r\n\tvar templateParser_regex = /{{%=([0-9]+)/gm;\r\n\tvar REF_DIRECT = 0, REF_IF = 1, REF_EXEC = 2;\r\n\tvar templateExec = function(parse, item, atIndex){\r\n\t\tvar parsed = {};\r\n\r\n\t\t// Get or evaluate static or dynamic data\r\n\t\tfor (var i = 0; i < parse.length; i++) {\r\n\t\t\tif(atIndex !== void 0 && atIndex.indexOf(i) === -1)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tvar ref = parse[i];\r\n\t\t\tref.data[1] = item;\r\n\r\n\t\t\t// Direct evaluation type\r\n\t\t\tif(ref.type === REF_DIRECT || ref.type === REF_EXEC)\r\n\t\t\t\tparsed[i] = {type:ref.type, data:localEval.apply(self.root, ref.data)};\r\n\r\n\t\t\t// Conditional type\r\n\t\t\telse if(ref.type === REF_IF){\r\n\t\t\t\tvar scopes = ref.data;\r\n\t\t\t\tparsed[i] = {type:ref.type, data:''};\r\n\t\t\t\tscopes[0] = ref.if[0];\r\n\r\n\t\t\t\t// If condition was not meet\r\n\t\t\t\tif(!localEval.apply(self.root, scopes)){\r\n\t\t\t\t\tparsed[i].data = elseIfHandle(ref, scopes);\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tscopes[0] = ref.if[1];\r\n\t\t\t\tparsed[i].data = localEval.apply(self.root, scopes);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn parsed;\r\n\t}\r\n\r\n\tvar templateParser = function(template, item, original){\r\n\t\tvar html = original === true ? template.html : template.html.cloneNode(true);\r\n\t\tvar addresses = template.addresses;\r\n\t\tvar parsed = templateExec(template.parse, item);\r\n\r\n\t\t// Save model item reference to node\r\n\t\thtml.model = item;\r\n\r\n\t\tvar changesReference = [];\r\n\t\tvar pendingInsert = [];\r\n\r\n\t\t// Find element where the data belongs to\r\n\t\tfor (var i = 0; i < addresses.length; i++) {\r\n\t\t\tvar ref = addresses[i];\r\n\t\t\tvar current = $.childIndexes(ref.address, html);\r\n\r\n\t\t\t// Modify element attributes\r\n\t\t\tif(ref.nodeType === 1){\r\n\t\t\t\tvar refA = ref.attributes;\r\n\t\t\t\tfor(var a = 0; a < refA.length; a++){\r\n\t\t\t\t\tvar refB = refA[a];\r\n\r\n\t\t\t\t\tvar isValueInput = (refB.name === 'value' && (current.tagName === 'TEXTAREA' ||\r\n\t\t\t\t\t\t(current.tagName === 'INPUT' && /checkbox|radio|hidden/.test(current.type) === false)\r\n\t\t\t\t\t));\r\n\r\n\t\t\t\t\tchangesReference.push({\r\n\t\t\t\t\t\tattribute:isValueInput === true ? current : current.attributes[refB.name],\r\n\t\t\t\t\t\tref:refB\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tif(refB.direct !== void 0){\r\n\t\t\t\t\t\tif(refB.name === 'value' && isValueInput === true){\r\n\t\t\t\t\t\t\tcurrent.value = parsed[refB.direct].data;\r\n\t\t\t\t\t\t\tcurrent.removeAttribute('value');\r\n\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tcurrent.setAttribute(refB.name, parsed[refB.direct].data);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Below is used for multiple data\r\n\t\t\t\t\tif(refB.name === 'value' && isValueInput === true){\r\n\t\t\t\t\t\tvar temp = current.value;\r\n\t\t\t\t\t\tcurrent.removeAttribute('value');\r\n\t\t\t\t\t\tcurrent.value = temp;\r\n\t\t\t\t\t\trefB = current;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse refB = current.attributes[refB.name];\r\n\r\n\t\t\t\t\trefB.value = refB.value.replace(templateParser_regex, function(full, match){\r\n\t\t\t\t\t\treturn parsed[match].data;\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Replace text node\r\n\t\t\tif(ref.nodeType === 3){\r\n\t\t\t\tvar refA = current;\r\n\r\n\t\t\t\tchangesReference.push({\r\n\t\t\t\t\ttextContent:refA,\r\n\t\t\t\t\tref:ref\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif(ref.direct !== void 0){\r\n\t\t\t\t\trefA.textContent = parsed[ref.direct].data;\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Below is used for multiple/dynamic data\r\n\t\t\t\trefA.textContent = refA.textContent.replace(templateParser_regex, function(full, match){\r\n\t\t\t\t\treturn parsed[match].data;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Replace dynamic node\r\n\t\t\tif(ref.nodeType === -1){\r\n\t\t\t\tvar cRef = {\r\n\t\t\t\t\tdynamicFlag:current,\r\n\t\t\t\t\tdirect:ref.parse_index,\r\n\t\t\t\t\tparentNode:current.parentNode,\r\n\t\t\t\t\tstartFlag:ref.startFlag && $.childIndexes(ref.startFlag, html)\r\n\t\t\t\t};\r\n\t\t\t\tchangesReference.push(cRef);\r\n\r\n\t\t\t\t// Pending element insert to take other element reference\r\n\t\t\t\tpendingInsert.push(cRef);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Save reference to element\r\n\t\thtml.sf$elementReferences = changesReference;\r\n\t\t// html.sf$modelParsed = parsed;\r\n\r\n\t\t// Run the pending element\r\n\t\tfor (var i = 0; i < pendingInsert.length; i++) {\r\n\t\t\tvar ref = pendingInsert[i];\r\n\t\t\tvar tDOM = $.parseElement(parsed[ref.direct].data, true);\r\n\t\t\tfor (var a = 0; a < tDOM.length; a++) {\r\n\t\t\t\tref.parentNode.insertBefore(tDOM[a], ref.dynamicFlag);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn html;\r\n\t}\r\n\r\n\tfunction syntheticCache(element, template, item){\r\n\t\tif(element.sf$cache === void 0)\r\n\t\t\telement.sf$cache = {};\r\n\r\n\t\tvar cache = element.sf$cache;\r\n\t\tvar modelRef_array = template.modelRef_array;\r\n\r\n\t\tfor (var i = 0; i < modelRef_array.length; i++) {\r\n\t\t\tvar ref = modelRef_array[i];\r\n\t\t\tcache[ref[0]] = deepProperty(item, ref[1]);\r\n\t\t}\r\n\t}\r\n\r\n\tfunction syntheticTemplate(element, template, property, item){\r\n\t\tvar cache = element.sf$cache;\r\n\t\tvar modelRef_array = template.modelRef_array;\r\n\r\n\t\tif(property !== void 0){\r\n\t\t\tvar changes = template.modelReference[property];\r\n\t\t\tif(changes === void 0 || changes.length === 0){\r\n\t\t\t\tconsole.error(\"Failed to run syntheticTemplate because property '\"+property+\"' is not observed\");\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\r\n\t\t\tif(cache)\r\n\t\t\t\tfor (var i = 0; i < modelRef_array.length; i++) {\r\n\t\t\t\t\tvar ref = modelRef_array[i];\r\n\t\t\t\t\tif(ref[0] !== property) continue;\r\n\r\n\t\t\t\t\tvar newData = deepProperty(item, ref[1]);\r\n\r\n\t\t\t\t\t// Check if data was different\r\n\t\t\t\t\tif(cache[ref[0]] !== newData)\r\n\t\t\t\t\t\tcache[ref[0]] = newData;\r\n\t\t\t\t}\r\n\t\t}\r\n\t\telse{\r\n\t\t\tvar changes = [];\r\n\t\t\tfor (var i = 0; i < modelRef_array.length; i++) {\r\n\t\t\t\tvar ref = modelRef_array[i];\r\n\t\t\t\tif(cache === void 0){\r\n\t\t\t\t\tArray.prototype.push.apply(changes, template.modelReference[ref[0]]);\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tvar newData = deepProperty(item, ref[1]);\r\n\r\n\t\t\t\t// Check if data was different\r\n\t\t\t\tif(cache[ref[0]] !== newData){\r\n\t\t\t\t\tArray.prototype.push.apply(changes, template.modelReference[ref[0]]);\r\n\t\t\t\t\tcache[ref[0]] = newData;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif(changes.length === 0) return false;\r\n\t\t}\r\n\r\n\t\tvar parsed = templateExec(template.parse, item, changes);\r\n\t\tfunction checkRelatedChanges(parseIndex){\r\n\t\t\tvar found = false;\r\n\t\t\tfor (var i = 0; i < parseIndex.length; i++) {\r\n\t\t\t\tif(changes.indexOf(parseIndex[i]) !== -1){\r\n\t\t\t\t\tfound = true;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif(found === false)\r\n\t\t\t\treturn false;\r\n\r\n\t\t\t// Prepare all required data\r\n\t\t\tchanges = [];\r\n\t\t\tfor (var i = 0; i < parseIndex.length; i++) {\r\n\t\t\t\tif(parsed[parseIndex[i]] === void 0){\r\n\t\t\t\t\tchanges.push(parseIndex[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tObject.assign(parsed, templateExec(template.parse, item, changes));\r\n\t\t\treturn true;\r\n\t\t}\r\n\r\n\t\tvar changesReference = element.sf$elementReferences;\r\n\t\tvar haveChanges = false;\r\n\t\tfor (var i = 0; i < changesReference.length; i++) {\r\n\t\t\tvar cRef = changesReference[i];\r\n\r\n\t\t\tif(cRef.dynamicFlag !== void 0){ // Dynamic data\r\n\t\t\t\tif(parsed[cRef.direct] !== void 0){\r\n\t\t\t\t\tvar tDOM = $.parseElement(parsed[cRef.direct].data, true).reverse();\r\n\t\t\t\t\tvar currentDOM = $.prevAll(cRef.dynamicFlag, cRef.startFlag);\r\n\t\t\t\t\tvar notExist = false;\r\n\r\n\t\t\t\t\t// Replace if exist, skip if similar\r\n\t\t\t\t\tfor (var a = 0; a < tDOM.length; a++) {\r\n\t\t\t\t\t\tif(currentDOM[a] === void 0){\r\n\t\t\t\t\t\t\tnotExist = true;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif(currentDOM[a].isEqualNode(tDOM[a]) === false)\r\n\t\t\t\t\t\t\tcRef.parentNode.replaceChild(tDOM[a], currentDOM[a]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add if not exist\r\n\t\t\t\t\tif(notExist){\r\n\t\t\t\t\t\tfor (var a = 0; a < tDOM.length; a++)\r\n\t\t\t\t\t\t\tcRef.parentNode.insertBefore(tDOM[a], cRef.dynamicFlag);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Remove if over index\r\n\t\t\t\t\telse{\r\n\t\t\t\t\t\tfor (var a = tDOM.length; a < currentDOM.length; a++) {\r\n\t\t\t\t\t\t\tcurrentDOM[a].remove();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\thaveChanges = true;\r\n\t\t\t\t}\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tif(cRef.textContent !== void 0){ // Text only\r\n\t\t\t\tif(cRef.ref.parse_index !== void 0){ // Multiple\r\n\t\t\t\t\tif(checkRelatedChanges(cRef.ref.parse_index) === true){\r\n\t\t\t\t\t\tvar temp = cRef.ref.value.replace(templateParser_regex, function(full, match){\r\n\t\t\t\t\t\t\treturn parsed[match].data;\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\tif(cRef.textContent.textContent === temp) continue;\r\n\t\t\t\t\t\tcRef.textContent.textContent = temp;\r\n\r\n\t\t\t\t\t\thaveChanges = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Direct value\r\n\t\t\t\telse if(parsed[cRef.ref.direct]){\r\n\t\t\t\t\tvar value = parsed[cRef.ref.direct].data;\r\n\t\t\t\t\tif(cRef.textContent.textContent === value) continue;\r\n\r\n\t\t\t\t\tvar ref_ = cRef.textContent;\r\n\t\t\t\t\t// Remove old element if exist\r\n\t\t\t\t\tif(ref_.sf$haveChilds === true){\r\n\t\t\t\t\t\twhile(ref_.previousSibling && ref_.previousSibling.sf$childRoot === ref_){\r\n\t\t\t\t\t\t\tref_.previousSibling.remove();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tref_.textContent = value;\r\n\t\t\t\t\thaveChanges = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if(cRef.attribute !== void 0){ // Attributes\r\n\t\t\t\tif(cRef.ref.parse_index !== void 0){ // Multiple\r\n\t\t\t\t\tif(checkRelatedChanges(cRef.ref.parse_index) === true){\r\n\t\t\t\t\t\tvar temp = cRef.ref.value.replace(templateParser_regex, function(full, match){\r\n\t\t\t\t\t\t\treturn parsed[match].data;\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\tif(cRef.attribute.value === temp) continue;\r\n\t\t\t\t\t\tcRef.attribute.value = temp;\r\n\r\n\t\t\t\t\t\thaveChanges = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Direct value\r\n\t\t\t\telse if(parsed[cRef.ref.direct]){\r\n\t\t\t\t\tvar value = parsed[cRef.ref.direct].data;\r\n\t\t\t\t\tif(cRef.attribute.value === value) continue;\r\n\t\t\t\t\tcRef.attribute.value = value;\r\n\r\n\t\t\t\t\thaveChanges = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn haveChanges;\r\n\t}\r\n\r\n\t// For contributor of this library\r\n\t// Please be careful when you're passing the eval argument\r\n\tvar dataParser = function(html, _model_, mask, scope, runEval, preParsedReference){\r\n\t\tvar _modelScope = self.root[scope];\r\n\t\tif(!runEval) runEval = '';\r\n\r\n\t\t// Don't match text inside quote, or object keys\r\n\t\tvar scopeMask = RegExp(sf.regex.strictVar+'('+self.modelKeys(_modelScope).join('|')+')\\\\b', 'g');\r\n\r\n\t\tif(mask)\r\n\t\t\tvar itemMask = RegExp(sf.regex.strictVar+mask+'\\\\.\\\\b', 'g');\r\n\r\n\t\tbindingEnabled = true;\r\n\r\n\t\tif(runEval === '#noEval'){\r\n\t\t\tvar preParsed = [];\r\n\t\t\tvar lastParsedIndex = preParsedReference.length;\r\n\t\t}\r\n\r\n\t\tvar prepared = html.replace(sf.regex.dataParser, function(actual, temp){\r\n\t\t\ttemp = avoidQuotes(temp, function(temp_){\r\n\t\t\t\t// Unescape HTML\r\n\t\t\t\ttemp = temp.split('&').join('&').split('<').join('<').split('>').join('>');\r\n\r\n\t\t\t\t// Mask item variable\r\n\t\t\t\tif(mask)\r\n\t\t\t\t\ttemp_ = temp_.replace(itemMask, function(matched){\r\n\t\t\t\t\t\treturn '_model_.'+matched[0].slice(1);\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t// Mask model for variable\r\n\t\t\t\treturn temp_.replace(scopeMask, function(full, matched){\r\n\t\t\t\t\treturn '_modelScope.'+matched;\r\n\t\t\t\t});\r\n\t\t\t}).split('_model_._modelScope.').join('_model_.');\r\n\r\n\t\t\t// Evaluate\r\n\t\t\tif(runEval === '#noEval'){\r\n\t\t\t\ttemp = temp.trim();\r\n\r\n\t\t\t\t// Simplicity similar\r\n\t\t\t\tvar exist = preParsed.indexOf(temp);\r\n\r\n\t\t\t\tif(exist === -1){\r\n\t\t\t\t\tpreParsed.push(temp);\r\n\t\t\t\t\tpreParsedReference.push({type:REF_DIRECT, data:[temp, _model_, _modelScope]});\r\n\t\t\t\t\treturn '{{%=' + (preParsed.length + lastParsedIndex - 1);\r\n\t\t\t\t}\r\n\t\t\t\treturn '{{%=' + (exist + lastParsedIndex);\r\n\t\t\t}\r\n\r\n\t\t\ttemp = '' + localEval.apply(self.root, [runEval + temp, _model_, _modelScope]);\r\n\r\n\t\t\treturn temp.replace(sf.regex.escapeHTML, function(i) {\r\n\t\t return '&#'+i.charCodeAt(0)+';';\r\n\t\t });\r\n\t\t});\r\n\r\n\t\tif(runEval === '#noEval'){\r\n\t\t\t// Clear memory before return\r\n\t\t\tpreParsed = _modelScope = _model_ = mask = scope = runEval = scopeMask = itemMask = html = null;\r\n\t\t\tsetTimeout(function(){prepared = null}, 1);\r\n\t\t}\r\n\t\treturn prepared;\r\n\t}\r\n\r\n\t// Dynamic data parser\r\n\tvar uniqueDataParser = function(html, _model_, mask, scope, runEval){\r\n\t\t// Get prepared html content\r\n\t\tvar _content_ = {\r\n\t\t\tlength:0,\r\n\t\t\ttake:function(passVar, currentIndex){\r\n\t\t\t\tif(passVar === null)\r\n\t\t\t\t\treturn dataParser(this[currentIndex], _model_, mask, scope);\r\n\r\n\t\t\t\t// Use strict mode and prepare for new variables\r\n\t\t\t\tvar strDeclare = '\"use strict\";var ';\r\n\t\t\t\tvar firstTime = true;\r\n\r\n\t\t\t\t// Declare new variable\r\n\t\t\t\tfor(var key in passVar){\r\n\t\t\t\t\tif(typeof passVar[key] === 'string')\r\n\t\t\t\t\t\tpassVar[key] = '\"'+passVar[key].split('\"').join('\\\\\"')+'\"';\r\n\t\t\t\t\telse if(typeof passVar[key] === 'object')\r\n\t\t\t\t\t\tpassVar[key] = JSON.stringify(passVar[key]);\r\n\r\n\t\t\t\t\tif(!firstTime)\r\n\t\t\t\t\t\tstrDeclare += ',';\r\n\r\n\t\t\t\t\tstrDeclare += key + ' = ' + passVar[key];\r\n\t\t\t\t\tfirstTime = false;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Remove var because no variable are being passed\r\n\t\t\t\tif(firstTime === true)\r\n\t\t\t\t\tstrDeclare = strDeclare.replace('var ', '');\r\n\r\n\t\t\t\t// Escape function call for addional security eval protection\r\n\t\t\t\tstrDeclare = strDeclare.split('(').join('(').split(')').join(')');\r\n\r\n\t\t\t\t// Pass to static data parser for another HTML data\r\n\t\t\t\treturn dataParser(this[currentIndex], _model_, mask, scope, strDeclare + ';');\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\t// Build script preparation\r\n\t\thtml = html.replace(/{\\[([\\s\\S]*?)\\]}/g, function(full, matched){\r\n\t\t\tif(/{{.*?}}/.test(matched) === false)\r\n\t\t\t\treturn \"_result_ += '\"+matched.split(\"'\").join(\"\\\\'\")+\"'\";\r\n\r\n\t\t\t_content_[_content_.length] = matched;\r\n\t\t\t_content_.length++;\r\n\t\t\treturn '_result_ += _content_.take(&VarPass&, '+(_content_.length - 1)+');';\r\n\t\t});\r\n\r\n\t\tvar _modelScope = self.root[scope];\r\n\r\n\t\t// Don't match text inside quote, or object keys\r\n\t\tvar scopeMask = RegExp(sf.regex.strictVar+'('+self.modelKeys(_modelScope).join('|')+')\\\\b', 'g');\r\n\r\n\t\tif(mask)\r\n\t\t\tvar itemMask = RegExp(sf.regex.strictVar+mask+'\\\\.\\\\b', 'g');\r\n\r\n\t\tif(runEval === '#noEval')\r\n\t\t\tvar preParsedReference = [];\r\n\r\n\t\tvar prepared = html.replace(sf.regex.uniqueDataParser, function(actual, temp){\r\n\t\t\ttemp = avoidQuotes(temp, function(temp_){\r\n\t\t\t\t// Unescape HTML\r\n\t\t\t\ttemp_ = temp_.split('&').join('&').split('<').join('<').split('>').join('>');\r\n\r\n\t\t\t\t// Mask item variable\r\n\t\t\t\tif(mask)\r\n\t\t\t\t\ttemp_ = temp_.replace(itemMask, function(matched){\r\n\t\t\t\t\t\treturn '_model_.'+matched[0].slice(1);\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t// Mask model for variable\r\n\t\t\t\treturn temp_.replace(scopeMask, function(full, matched){\r\n\t\t\t\t\treturn '_modelScope.'+matched;\r\n\t\t\t\t});\r\n\t\t\t}).split('_model_._modelScope.').join('_model_.');\r\n\r\n\t\t\tvar result = '';\r\n\t\t\tvar check = false;\r\n\r\n\t\t\t// Get defined variables\r\n\t\t\tvar VarPass_ = /(var|let)([\\w,\\s]+)(?=\\s(?==|in|of))/g;\r\n\t\t\tvar VarPass = [];\r\n\t\t\tvar s1 = null;\r\n\t\t\twhile((s1 = VarPass_.exec(temp)) !== null){\r\n\t\t\t\tVarPass.push(s1[2]);\r\n\t\t\t}\r\n\r\n\t\t\tif(_model_ === null && runEval === '#noEval')\r\n\t\t\t\tVarPass.push('_model_');\r\n\r\n\t\t\tif(VarPass.length !== 0){\r\n\t\t\t\tvar obtained = [];\r\n\t\t\t\tfor (var i = 0; i < VarPass.length; i++) {\r\n\t\t\t\t\tVarPass[i].replace(/([\\n\\t\\r]| )+/g, '').split(',').forEach(function(val){\r\n\t\t\t\t\t\tobtained.push(val);\r\n\t\t\t\t\t});\r\n\t\t\t\t};\r\n\t\t\t\tVarPass = obtained;\r\n\t\t\t\tfor (var i = 0; i < VarPass.length; i++) {\r\n\t\t\t\t\tVarPass[i] += ':(typeof '+VarPass[i]+'!==\"void 0\"?'+VarPass[i]+':void 0)';\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(VarPass.length === 0)\r\n\t\t\t\t\tVarPass = 'null';\r\n\t\t\t\telse VarPass = '{'+VarPass.join(',')+'}';\r\n\t\t\t\ttemp = temp.split('&VarPass&').join(VarPass);\r\n\t\t\t}\r\n\t\t\telse temp = temp.split('&VarPass&').join('null');\r\n\r\n\t\t\tcheck = temp.split('@if ');\r\n\t\t\tif(check.length !== 1){\r\n\t\t\t\tcheck = check[1].split(':');\r\n\r\n\t\t\t\t// {if, elseIf:([if, value], ...), elseValue}\r\n\t\t\t\tvar findElse = function(text){\r\n\t\t\t\t\ttext = text.join(':');\r\n\t\t\t\t\tvar else_ = null;\r\n\r\n\t\t\t\t\t// Split elseIf\r\n\t\t\t\t\ttext = text.split('@elseif ');\r\n\r\n\t\t\t\t\t// Get else value\r\n\t\t\t\t\tvar else_ = text[text.length - 1].split('@else');\r\n\t\t\t\t\tif(else_.length === 2){\r\n\t\t\t\t\t\ttext[text.length - 1] = else_[0];\r\n\t\t\t\t\t\telse_ = else_.pop();\r\n\t\t\t\t\t\telse_ = else_.substr(else_.indexOf(':') + 1);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse else_ = null;\r\n\r\n\t\t\t\t\tvar obj = {\r\n\t\t\t\t\t\tif:text.shift(),\r\n\t\t\t\t\t\telseIf:[],\r\n\t\t\t\t\t\telseValue:else_\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\t\t// Separate condition script and value\r\n\t\t\t\t\tfor (var i = 0; i < text.length; i++) {\r\n\t\t\t\t\t\tvar val = text[i].split(':');\r\n\t\t\t\t\t\tobj.elseIf.push([val.shift(), val.join(':')]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn obj;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(runEval === '#noEval'){\r\n\t\t\t\t\tvar condition = check.shift();\r\n\t\t\t\t\tvar elseIf = findElse(check);\r\n\t\t\t\t\telseIf.type = REF_IF;\r\n\t\t\t\t\telseIf.data = [null, _model_, _modelScope, _content_];\r\n\r\n\t\t\t\t\t// Trim Data\r\n\t\t\t\t\telseIf.if = [condition.trim(), elseIf.if.trim()];\r\n\t\t\t\t\tif(elseIf.elseValue !== null)\r\n\t\t\t\t\t\telseIf.elseValue = elseIf.elseValue.trim();\r\n\r\n\t\t\t\t\tfor (var i = 0; i < elseIf.elseIf.length; i++) {\r\n\t\t\t\t\t\telseIf.elseIf[i][0] = elseIf.elseIf[i][0].trim();\r\n\t\t\t\t\t\telseIf.elseIf[i][1] = elseIf.elseIf[i][1].trim();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Push data\r\n\t\t\t\t\tpreParsedReference.push(elseIf);\r\n\t\t\t\t\treturn '{{%%=' + (preParsedReference.length - 1);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar scopes = [check[0], _model_, _modelScope, _content_];\r\n\r\n\t\t\t\t// If condition was not meet\r\n\t\t\t\tif(!localEval.apply(self.root, scopes)){\r\n\t\t\t\t\tcheck.shift();\r\n\t\t\t\t\treturn elseIfHandle(findElse(check), scopes);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcheck.shift();\r\n\t\t\t\tscopes[0] = check.join(':');\r\n\r\n\t\t\t\treturn localEval.apply(self.root, scopes);\r\n\t\t\t}\r\n\r\n\t\t\t// Warning! Avoid unencoded user inputted content\r\n\t\t\t// And always check/remove closing ']}' in user content\r\n\t\t\t// Any function call will be removed for addional security\r\n\t\t\tcheck = temp.split('@exec');\r\n\t\t\tif(check.length !== 1){\r\n\t\t\t\tvar scopes = [check[1], _model_, _modelScope, _content_];\r\n\r\n\t\t\t\tif(runEval === '#noEval'){\r\n\t\t\t\t\tpreParsedReference.push({type:REF_EXEC, data:scopes});\r\n\t\t\t\t\treturn '{{%%=' + (preParsedReference.length - 1);\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttemp = localEval.apply(self.root, scopes);\r\n\t\t\t\treturn temp;\r\n\t\t\t}\r\n\t\t\treturn '';\r\n\t\t});\r\n\r\n\t\tif(runEval === '#noEval'){\r\n\t\t\t// Clear memory before return\r\n\t\t\t_modelScope = runEval = scopeMask = itemMask = html = null;\r\n\t\t\tsetTimeout(function(){prepared = null}, 1);\r\n\t\t\treturn [prepared, preParsedReference, _content_];\r\n\t\t}\r\n\r\n\t\treturn prepared;\r\n\t}\r\n\r\n\tvar bindArray = function(template, list, mask, modelName, propertyName, targetNode, parentNode, tempDOM){\r\n\t\tvar editProperty = ['pop', 'push', 'splice', 'shift', 'unshift', 'swap', 'move', 'replace', 'softRefresh', 'hardRefresh'];\r\n\t\tvar refreshTimer = -1;\r\n\t\tvar parentChilds = parentNode.children;\r\n\t\tvar isKeyed = parentNode.classList.contains('sf-keyed-list');\r\n\r\n\t\t// Update callback\r\n\t\tvar modelRef = self.root[modelName];\r\n\t\tvar eventVar = 'on$'+propertyName;\r\n\t\tvar callback = modelRef[eventVar];\r\n\r\n\t\tvar processElement = function(index, options, other, count){\r\n\t\t\t// Find boundary for inserting to virtual DOM\r\n\t\t\tif(list.$virtual){\r\n\t\t\t\tvar vStartRange = list.$virtual.DOMCursor;\r\n\t\t\t\tvar vEndRange = vStartRange + list.$virtual.preparedLength;\r\n\t\t\t}\r\n\r\n\t\t\tif(options === 'clear'){\r\n\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\tvar spacer = [parentNode.firstElementChild, parentNode.lastElementChild];\r\n\r\n\t\t\t\tparentNode.textContent = '';\r\n\r\n\t\t\t\tif(list.$virtual){\r\n\t\t\t\t\tparentNode.appendChild(spacer[0]);\r\n\t\t\t\t\tparentNode.appendChild(spacer[1]);\r\n\t\t\t\t\tlist.$virtual.dom.textContent = '';\r\n\t\t\t\t\tspacer[1].style.height = \r\n\t\t\t\t\tspacer[0].style.height = 0;\r\n\t\t\t\t\tlist.$virtual.reset(true);\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Avoid multiple refresh by set a timer\r\n\t\t\tif(list.$virtual){\r\n\t\t\t\tvar exist = list.$virtual.elements();\r\n\r\n\t\t\t\tclearTimeout(refreshTimer);\r\n\t\t\t\trefreshTimer = setTimeout(function(){\r\n\t\t\t\t\tlist.$virtual.reinitScroll();\r\n\t\t\t\t}, 100);\r\n\t\t\t}\r\n\t\t\telse exist = parentChilds;\r\n\r\n\t\t\t// Hard refresh - Append element\r\n\t\t\tif(options === 'hardRefresh'){\r\n\t\t\t\t// Clear siblings after the index\r\n\t\t\t\tfor (var i = index; i < exist.length; i++) {\r\n\t\t\t\t\texist[i].remove();\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\tvar vCursor = list.$virtual.vCursor;\r\n\r\n\t\t\t\tfor (var i = index; i < list.length; i++) {\r\n\t\t\t\t\tvar temp = templateParser(template, list[i]);\r\n\t\t\t\t\tif(list.$virtual){\r\n\t\t\t\t\t\tif(vCursor.floor === null && i < vEndRange)\r\n\t\t\t\t\t\t\tparentNode.insertBefore(temp, parentNode.lastElementChild);\r\n\t\t\t\t\t\telse list.$virtual.dom.appendChild(temp);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse parentNode.appendChild(temp);\r\n\r\n\t\t\t\t\tif(isKeyed === false)\r\n\t\t\t\t\t\tsyntheticCache(temp, template, list[i]);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(list.$virtual && list.$virtual.refreshVirtualSpacer)\r\n\t\t\t\t\tlist.$virtual.refreshVirtualSpacer(list.$virtual.DOMCursor);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif(callback === void 0)\r\n\t\t\t\tcallback = modelRef[eventVar];\r\n\r\n\t\t\tif(options === 'swap' || options === 'move'){\r\n\t\t\t\tif(options === 'move'){\r\n\t\t\t\t\tvar overflow = list.length - index - count;\r\n\t\t\t\t\tif(overflow < 0)\r\n\t\t\t\t\t\tcount += overflow;\r\n\r\n\t\t\t\t\t// Move to virtual DOM\r\n\t\t\t\t\tvar vDOM = document.createElement('div');\r\n\t\t\t\t\tfor (var i = 0; i < count; i++) {\r\n\t\t\t\t\t\tvDOM.appendChild(exist[index + i]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tvar nextSibling = exist[other] || null;\r\n\t\t\t\t\tvar theParent = nextSibling && nextSibling.parentNode;\r\n\r\n\t\t\t\t\tif(theParent === false){\r\n\t\t\t\t\t\tif(list.$virtual && list.length >= vEndRange)\r\n\t\t\t\t\t\t\ttheParent = list.$virtual.dom;\r\n\t\t\t\t\t\telse theParent = parentNode;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Move to defined index\r\n\t\t\t\t\tfor (var i = 0; i < count; i++) {\r\n\t\t\t\t\t\ttheParent.insertBefore(vDOM.firstElementChild, nextSibling);\r\n\r\n\t\t\t\t\t\tif(callback !== void 0 && callback.update)\r\n\t\t\t\t\t\t\tcallback.update(exist[index + i], 'move');\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(index > other){\r\n\t\t\t\t\tvar index_a = exist[other];\r\n\t\t\t\t\tother = exist[index];\r\n\t\t\t\t\tindex = index_a;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tindex = exist[index];\r\n\t\t\t\t\tother = exist[other];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar other_sibling = other.nextSibling;\r\n\t\t\t\tvar other_parent = other.parentNode;\r\n\t index.parentNode.insertBefore(other, index.nextSibling);\r\n\t other_parent.insertBefore(index, other_sibling);\r\n\r\n\t\t\t\tif(callback !== void 0 && callback.update){\r\n\t\t\t\t\tcallback.update(exist[other], 'swap');\r\n\t\t\t\t\tcallback.update(exist[index], 'swap');\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Clear unused element if current array < last array\r\n\t\t\tif(options === 'removeRange'){\r\n\t\t\t\tfor (var i = index; i < other; i++) {\r\n\t\t\t\t\texist[i].remove();\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Remove\r\n\t\t\tif(options === 'remove'){\r\n\t\t\t\tif(exist[index]){\r\n\t\t\t\t\tvar currentRemoved = false;\r\n\t\t\t\t\tvar startRemove = function(){\r\n\t\t\t\t\t\tif(currentRemoved) return;\r\n\t\t\t\t\t\tcurrentRemoved = true;\r\n\r\n\t\t\t\t\t\texist[index].remove();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif(callback !== void 0 && callback.remove){\r\n\t\t\t\t\t\t// Auto remove if return false\r\n\t\t\t\t\t\tif(!callback.remove(exist[index], startRemove))\r\n\t\t\t\t\t\t\tstartRemove();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Auto remove if no callback\r\n\t\t\t\t\telse startRemove();\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Update\r\n\t\t\telse if(options === 'update'){\r\n\t\t\t\tif(index === void 0){\r\n\t\t\t\t\tindex = 0;\r\n\t\t\t\t\tother = list.length;\r\n\t\t\t\t}\r\n\t\t\t\telse if(other === void 0) other = index + 1;\r\n\t\t\t\telse if(other < 0) other = list.length + other;\r\n\t\t\t\telse other += index;\r\n\r\n\t\t\t\t// Trim length\r\n\t\t\t\tvar overflow = list.length - other;\r\n\t\t\t\tif(overflow < 0) other = other + overflow;\r\n\r\n\t\t\t\tfor (var i = index; i < other; i++) {\r\n\t\t\t\t\tvar oldChild = exist[i];\r\n\t\t\t\t\tif(oldChild === void 0 || list[i] === void 0)\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tvar temp = templateParser(template, list[i]);\r\n\t\t\t\t\tif(isKeyed === false)\r\n\t\t\t\t\t\tsyntheticCache(temp, template, list[i]);\r\n\r\n\t\t\t\t\tif(list.$virtual){\r\n\t\t\t\t\t\toldChild.parentNode.replaceChild(temp, oldChild);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tparentNode.replaceChild(temp, oldChild);\r\n\t\t\t\t\tif(callback !== void 0 && callback.update)\r\n\t\t\t\t\t\tcallback.update(temp, 'replace');\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tvar item = list[index];\r\n\t\t\tif(item === void 0) return;\r\n\r\n\t\t\tvar temp = templateParser(template, item);\r\n\t\t\tif(isKeyed === false)\r\n\t\t\t\tsyntheticCache(temp, template, item);\r\n\r\n\t\t\t// Create\r\n\t\t\tif(options === 'insertAfter'){\r\n\t\t\t\tif(exist.length === 0)\r\n\t\t\t\t\tparentNode.insertBefore(temp, parentNode.lastElementChild);\r\n\t\t\t\telse{\r\n\t\t\t\t\tvar referenceNode = exist[index - 1];\r\n\t\t\t\t\treferenceNode.parentNode.insertBefore(temp, referenceNode.nextSibling);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(callback !== void 0 && callback.create)\r\n\t\t\t\t\tcallback.create(temp);\r\n\t\t\t}\r\n\t\t\telse if(options === 'prepend'){\r\n\t\t\t\tvar referenceNode = exist[0];\r\n\t\t\t\tif(referenceNode !== void 0){\r\n\t\t\t\t\treferenceNode.parentNode.insertBefore(temp, referenceNode);\r\n\r\n\t\t\t\t\tif(callback !== void 0 && callback.create)\r\n\t\t\t\t\t\tcallback.create(temp);\r\n\t\t\t\t}\r\n\t\t\t\telse options = 'append';\r\n\t\t\t}\r\n\t\t\tif(options === 'append'){\r\n\t\t\t\tif(list.$virtual){\r\n\t\t\t\t\tif(index === 0) // Add before virtual scroller\r\n\t\t\t\t\t\tparentNode.insertBefore(temp, parentNode.lastElementChild);\r\n\t\t\t\t\telse if(index >= vEndRange){ // To virtual DOM\r\n\t\t\t\t\t\tif(list.$virtual.vCursor.floor === null)\r\n\t\t\t\t\t\t\tlist.$virtual.vCursor.floor = temp;\r\n\r\n\t\t\t\t\t\tlist.$virtual.dom.appendChild(temp);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse // To real DOM\r\n\t\t\t\t\t\texist[index-1].insertAdjacentElement('afterEnd', temp);\r\n\r\n\t\t\t\t\tif(callback !== void 0 && callback.create)\r\n\t\t\t\t\t\tcallback.create(temp);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tparentNode.appendChild(temp);\r\n\t\t\t\tif(callback !== void 0 && callback.create)\r\n\t\t\t\t\tcallback.create(temp);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tvar _double_zero = [0,0]; // For arguments\r\n\t\tvar propertyProxy = function(subject, name){\r\n\t\t\tObject.defineProperty(subject, name, {\r\n\t\t\t\tenumerable: false,\r\n\t\t\t\tconfigurable: true,\r\n\t\t\t\tvalue: function(){\r\n\t\t\t\t\tvar temp = void 0;\r\n\t\t\t\t\tvar lastLength = this.length;\r\n\r\n\t\t\t\t\tif(name === 'move'){\r\n\t\t\t\t\t\tvar from = arguments[0];\r\n\t\t\t\t\t\tvar to = arguments[1];\r\n\t\t\t\t\t\tif(from === to) return;\r\n\t\t\t\t\t\tvar count = arguments[2] || 1;\r\n\t\t\t\t\t\tprocessElement(from, 'move', to, count);\r\n\r\n\t\t\t\t\t\tvar temp = Array.prototype.splice.apply(this, [from, count]);\r\n\t\t\t\t\t\ttemp.unshift(to, 0);\r\n\t\t\t\t\t\tArray.prototype.splice.apply(this, temp);\r\n\r\n\t\t\t\t\t\t// Reset virtual ceiling and floor\r\n\t\t\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\t\t\tlist.$virtual.reinitCursor();\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif(name === 'swap'){\r\n\t\t\t\t\t\tvar i = arguments[0];\r\n\t\t\t\t\t\tvar o = arguments[1];\r\n\t\t\t\t\t\tif(i === o) return;\r\n\t\t\t\t\t\tprocessElement(i, 'swap', o);\r\n\t\t\t\t\t\tvar temp = this[i];\r\n\t\t\t\t\t\tthis[i] = this[o];\r\n\t\t\t\t\t\tthis[o] = temp;\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'replace'){\r\n\t\t\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\t\t\tlist.$virtual.resetViewport();\r\n\r\n\t\t\t\t\t\t// Check if item has same reference\r\n\t\t\t\t\t\tif(arguments[0].length >= lastLength && lastLength !== 0){\r\n\t\t\t\t\t\t\tvar matchLeft = lastLength;\r\n\t\t\t\t\t\t\tvar ref = arguments[0];\r\n\r\n\t\t\t\t\t\t\tfor (var i = 0; i < lastLength; i++) {\r\n\t\t\t\t\t\t\t\tif(ref[i] === this[i]){\r\n\t\t\t\t\t\t\t\t\tmatchLeft--;\r\n\t\t\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// Add new element at the end\r\n\t\t\t\t\t\t\tif(matchLeft === 0){\r\n\t\t\t\t\t\t\t\tif(ref.length === lastLength) return;\r\n\r\n\t\t\t\t\t\t\t\tvar temp = arguments[0].slice(lastLength);\r\n\t\t\t\t\t\t\t\ttemp.unshift(lastLength, 0);\r\n\t\t\t\t\t\t\t\tthis.splice.apply(this, temp);\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// Add new element at the middle\r\n\t\t\t\t\t\t\telse if(matchLeft !== lastLength){\r\n\t\t\t\t\t\t\t\tif(arguments[1] === true){\r\n\t\t\t\t\t\t\t\t\tvar temp = arguments[0].slice(i);\r\n\t\t\t\t\t\t\t\t\ttemp.unshift(i, lastLength - i);\r\n\t\t\t\t\t\t\t\t\tArray.prototype.splice.apply(this, temp);\r\n\r\n\t\t\t\t\t\t\t\t\tlist.refresh(i, lastLength);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Build from zero\r\n\t\t\t\t\t\tif(lastLength === 0){\r\n\t\t\t\t\t\t\tArray.prototype.push.apply(this, arguments[0]);\r\n\t\t\t\t\t\t\tprocessElement(0, 'hardRefresh');\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Clear all items and merge the new one\r\n\t\t\t\t\t\tvar temp = [0, lastLength];\r\n\t\t\t\t\t\tArray.prototype.push.apply(temp, arguments[0]);\r\n\t\t\t\t\t\tArray.prototype.splice.apply(this, temp);\r\n\r\n\t\t\t\t\t\t// Rebuild all element\r\n\t\t\t\t\t\tif(arguments[1] !== true || isKeyed){\r\n\t\t\t\t\t\t\tprocessElement(0, 'clear');\r\n\t\t\t\t\t\t\tprocessElement(0, 'hardRefresh');\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Reuse some element\r\n\t\t\t\t\t\telse{\r\n\t\t\t\t\t\t\t// Clear unused element if current array < last array\r\n\t\t\t\t\t\t\tif(this.length < lastLength)\r\n\t\t\t\t\t\t\t\tprocessElement(this.length, 'removeRange', lastLength);\r\n\r\n\t\t\t\t\t\t\t// And start refreshing\r\n\t\t\t\t\t\t\tlist.refresh(0, this.length);\r\n\r\n\t\t\t\t\t\t\tif(list.$virtual && list.$virtual.refreshVirtualSpacer)\r\n\t\t\t\t\t\t\t\tlist.$virtual.refreshVirtualSpacer(list.$virtual.DOMCursor);\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Reset virtual list\r\n\t\t\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\t\t\tlist.$virtual.reset();\r\n\r\n\t\t\t\t\t\treturn this;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'splice' && arguments[0] === 0 && arguments[1] === void 0){\r\n\t\t\t\t\t\tprocessElement(0, 'clear');\r\n\t\t\t\t\t\treturn Array.prototype.splice.apply(this, arguments);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif(Array.prototype[name])\r\n\t\t\t\t\t\ttemp = Array.prototype[name].apply(this, arguments);\r\n\r\n\t\t\t\t\tif(name === 'pop')\r\n\t\t\t\t\t\tprocessElement(this.length, 'remove');\r\n\r\n\t\t\t\t\telse if(name === 'push'){\r\n\t\t\t\t\t\tif(arguments.length === 1)\r\n\t\t\t\t\t\t\tprocessElement(lastLength, 'append');\r\n\t\t\t\t\t\telse{\r\n\t\t\t\t\t\t\tfor (var i = 0; i < arguments.length; i++) {\r\n\t\t\t\t\t\t\t\tprocessElement(lastLength + i, 'append');\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'shift'){\r\n\t\t\t\t\t\tprocessElement(0, 'remove');\r\n\r\n\t\t\t\t\t\tif(list.$virtual && list.$virtual.DOMCursor > 0){\r\n\t\t\t\t\t\t\tlist.$virtual.DOMCursor--;\r\n\t\t\t\t\t\t\tlist.$virtual.reinitCursor();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'splice'){\r\n\t\t\t\t\t\tif(arguments[0] === 0 && arguments[1] === void 0)\r\n\t\t\t\t\t\t\treturn temp;\r\n\r\n\t\t\t\t\t\t// Removing data\r\n\t\t\t\t\t\tvar real = arguments[0];\r\n\t\t\t\t\t\tif(real < 0) real = lastLength + real;\r\n\r\n\t\t\t\t\t\tvar limit = arguments[1];\r\n\t\t\t\t\t\tif(!limit && limit !== 0) limit = this.length;\r\n\r\n\t\t\t\t\t\tfor (var i = limit - 1; i >= 0; i--) {\r\n\t\t\t\t\t\t\tprocessElement(real + i, 'remove');\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif(list.$virtual && list.$virtual.DOMCursor >= real)\r\n\t\t\t\t\t\t\tlist.$virtual.DOMCursor = real - limit;\r\n\r\n\t\t\t\t\t\tif(arguments.length >= 3){ // Inserting data\r\n\t\t\t\t\t\t\tlimit = arguments.length - 2;\r\n\r\n\t\t\t\t\t\t\t// Trim the index if more than length\r\n\t\t\t\t\t\t\tif(real >= this.length)\r\n\t\t\t\t\t\t\t\treal = this.length - 1;\r\n\r\n\t\t\t\t\t\t\tfor (var i = 0; i < limit; i++) {\r\n\t\t\t\t\t\t\t\tprocessElement(real + i, 'insertAfter');\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tif(list.$virtual && list.$virtual.DOMCursor >= real)\r\n\t\t\t\t\t\t\t\tlist.$virtual.DOMCursor += limit;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'unshift'){\r\n\t\t\t\t\t\tif(arguments.length === 1)\r\n\t\t\t\t\t\t\tprocessElement(0, 'prepend');\r\n\t\t\t\t\t\telse{\r\n\t\t\t\t\t\t\tfor (var i = arguments.length - 1; i >= 0; i--) {\r\n\t\t\t\t\t\t\t\tprocessElement(i, 'prepend');\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif(list.$virtual && list.$virtual.DOMCursor !== 0){\r\n\t\t\t\t\t\t\tlist.$virtual.DOMCursor += arguments.length;\r\n\t\t\t\t\t\t\tlist.$virtual.reinitCursor();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'softRefresh'){\r\n\t\t\t\t\t\tprocessElement(arguments[0], 'update', arguments[1]);\r\n\r\n\t\t\t\t\t\tif(list.$virtual && list.$virtual.DOMCursor)\r\n\t\t\t\t\t\t\tlist.$virtual.reinitCursor();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'hardRefresh'){\r\n\t\t\t\t\t\tprocessElement(arguments[0] || 0, 'hardRefresh');\r\n\r\n\t\t\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\t\t\tlist.$virtual.DOMCursor = arguments[0] || 0;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn temp;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tif(parentNode && parentNode.classList.contains('sf-virtual-list')){\r\n\t\t\tdelete list.$virtual;\r\n\t\t\tlist.$virtual = {};\r\n\r\n\t\t\t// Transfer virtual DOM\r\n\t\t\tlist.$virtual.dom = tempDOM;\r\n\t\t\tif(callback !== void 0)\r\n\t\t\t\tlist.$virtual.callback = callback;\r\n\t\t\telse list.$virtual.callback_ = {ref:modelRef, var:eventVar};\r\n\r\n\t\t\tparentNode.replaceChild(template.html, parentChilds[1]);\r\n\t\t\tsf.internal.virtual_scroll.handle(list, targetNode, parentNode);\r\n\t\t\ttemplate.html.remove();\r\n\t\t}\r\n\r\n\t\tfor (var i = 0; i < editProperty.length; i++) {\r\n\t\t\tpropertyProxy(list, editProperty[i]);\r\n\t\t}\r\n\r\n\t\t// Todo: Enable auto item binding\r\n\t\tif(false && list.auto !== false){\r\n\t\t\t// for (var i = 0; i < list.length; i++) {\r\n\t\t\t// \tlist[i]\r\n\t\t\t// }\r\n\t\t}\r\n\r\n\t\thiddenProperty(list, '$replace', function(index, key, needle, func){\r\n\t\t\tvar elRef = list.getElement(index).sf$elementReferences;\r\n\t\t\tvar process = template.modelReference[key];\r\n\t\t\tif(process === void 0){\r\n\t\t\t\tconsole.error(\"Can't found binding for '\"+key+\"'\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tfor (var i = 0; i < elRef.length; i++) {\r\n\t\t\t\tif(elRef[i].textContent === void 0 || elRef[i].ref.direct === void 0)\r\n\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\tif(process.indexOf(elRef[i].ref.direct) !== -1){\r\n\t\t\t\t\tvar ref = elRef[i].textContent;\r\n\t\t\t\t\tvar content = $.escapeText(list[index][key]).replace(needle, func);\r\n\r\n\t\t\t\t\t// Skip if nothing was changed\r\n\t\t\t\t\tif(list[index][key] === content) continue;\r\n\t\t\t\t\tref.textContent = ''; // Let this empty for later referencing\r\n\t\t\t\t\tref.sf$haveChilds = true;\r\n\t\t\t\t\tcontent = $.parseElement(content, true);\r\n\r\n\t\t\t\t\t// Remove old element if exist\r\n\t\t\t\t\twhile(ref.previousSibling && ref.previousSibling.sf$childRoot === ref){\r\n\t\t\t\t\t\tref.previousSibling.remove();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tvar parentNode_ = ref.parentNode;\r\n\t\t\t\t\tfor (var i = 0; i < content.length; i++) {\r\n\t\t\t\t\t\tcontent[i].sf$childRoot = ref;\r\n\t\t\t\t\t\tparentNode_.insertBefore(content[i], ref);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\thiddenProperty(list, 'refresh', function(index, length, property){\r\n\t\t\tif(index === void 0 || index.constructor === String){\r\n\t\t\t\tproperty = index;\r\n\t\t\t\tindex = 0;\r\n\t\t\t\tlength = list.length;\r\n\t\t\t}\r\n\t\t\telse if(length === void 0) length = index + 1;\r\n\t\t\telse if(length.constructor === String){\r\n\t\t\t\tproperty = length;\r\n\t\t\t\tlength = index + 1;\r\n\t\t\t}\r\n\t\t\telse if(length < 0) length = list.length + length;\r\n\t\t\telse length += index;\r\n\r\n\t\t\t// Trim length\r\n\t\t\tvar overflow = list.length - length;\r\n\t\t\tif(overflow < 0) length = length + overflow;\r\n\r\n\t\t\tfor (var i = index; i < length; i++) {\r\n\t\t\t\tvar elem = list.getElement(i);\r\n\r\n\t\t\t\t// Create element if not exist\r\n\t\t\t\tif(elem === void 0){\r\n\t\t\t\t\tlist.hardRefresh(i);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tif(isKeyed === true)\r\n\t\t\t\t\t\tlist.softRefresh(i);\r\n\t\t\t\t\telse if(syntheticTemplate(elem, template, property, list[i]) === false)\r\n\t\t\t\t\t\tcontinue; // Continue if no update\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(callback !== void 0 && callback.update)\r\n\t\t\t\t\tcallback.update(elem, 'replace');\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tvar virtualChilds = null;\r\n\t\tif(list.$virtual)\r\n\t\t\tvirtualChilds = list.$virtual.dom.children;\r\n\t\thiddenProperty(list, 'getElement', function(index){\r\n\t\t\tif(virtualChilds !== null){\r\n\t\t\t\tvar ret = void 0;\r\n\t\t\t\tif(index < list.$virtual.DOMCursor)\r\n\t\t\t\t\treturn virtualChilds[index];\r\n\t\t\t\telse {\r\n\t\t\t\t\tindex -= list.$virtual.DOMCursor;\r\n\t\t\t\t\tvar childElement = parentNode.childElementCount - 2;\r\n\r\n\t\t\t\t\tif(index < childElement)\r\n\t\t\t\t\t\treturn parentChilds[index + 1];\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn virtualChilds[index - childElement + list.$virtual.DOMCursor];\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn void 0;\r\n\t\t\t}\r\n\r\n\t\t\treturn parentChilds[index];\r\n\t\t});\r\n\t}\r\n\r\n\tvar loopParser = function(name, template, script, targetNode, parentNode){\r\n\t\tvar method = script.split(' in ');\r\n\t\tvar mask = method[0];\r\n\t\tvar isKeyed = parentNode.classList.contains('sf-keyed-list');\r\n\r\n\t\tvar items = root_(name)[method[1]];\r\n\t\tif(items === void 0)\r\n\t\t\titems = root_(name)[method[1]] = [];\r\n\r\n\t\ttemplate.setAttribute('sf-bind-list', method[1]);\r\n\r\n\t\t// Get reference for debugging\r\n\t\tprocessingElement = template;\r\n\t\ttemplate = self.extractPreprocess(template, mask, name);\r\n\r\n\t\tif(method.length === 2){\r\n\t\t\tvar tempDOM = document.createElement('div');\r\n\t\t\tvar modelRef = self.root[name];\r\n\r\n\t\t\tfor (var i = 0; i < items.length; i++) {\r\n\t\t\t\tvar elem = templateParser(template, items[i]);\r\n\t\t\t\ttempDOM.appendChild(elem);\r\n\r\n\t\t\t\tif(isKeyed === false)\r\n\t\t\t\t\tsyntheticCache(elem, template, items[i]);\r\n\t\t\t}\r\n\r\n\t\t\t// Enable element binding\r\n\t\t\tif(modelRef.sf$bindedKey === void 0)\r\n\t\t\t\tinitBindingInformation(modelRef);\r\n\r\n\t\t\tif(modelRef.sf$bindedKey[method[1]] === void 0)\r\n\t\t\t\tmodelRef.sf$bindedKey[method[1]] = null;\r\n\r\n\t\t\tObject.defineProperty(modelRef, method[1], {\r\n\t\t\t\tenumerable: true,\r\n\t\t\t\tconfigurable: true,\r\n\t\t\t\tget:function(){\r\n\t\t\t\t\treturn items;\r\n\t\t\t\t},\r\n\t\t\t\tset:function(val){\r\n\t\t\t\t\tif(val.length === 0)\r\n\t\t\t\t\t\treturn items.splice(0);\r\n\t\t\t\t\treturn items.replace(val, true);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tbindArray(template, items, mask, name, method[1], targetNode, parentNode, tempDOM);\r\n\r\n\t\t\t// Output to real DOM if not being used for virtual list\r\n\t\t\tif(items.$virtual === void 0){\r\n\t\t\t\tvar children = tempDOM.children;\r\n\t\t\t\tfor (var i = 0, n = children.length; i < n; i++) {\r\n\t\t\t\t\tparentNode.appendChild(children[0]);\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttempDOM.remove();\r\n\t\t\t\ttempDOM = null;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tvar callInputListener = function(model, property, value){\r\n\t\tvar callback = model['on$'+property];\r\n\t\tvar v2m = model['v2m$'+property];\r\n\t\tvar newValue1 = void 0; var newValue2 = void 0;\r\n\t\tif(callback !== void 0 || v2m !== void 0){\r\n\t\t\tvar old = model[property];\r\n\t\t\tif(old !== null && old !== void 0 && old.constructor === Array)\r\n\t\t\t\told = old.slice(0);\r\n\r\n\t\t\ttry{\r\n\t\t\t\tif(v2m !== void 0)\r\n\t\t\t\t\tnewValue1 = v2m(old, value);\r\n\r\n\t\t\t\tif(callback !== void 0)\r\n\t\t\t\t\tnewValue2 = callback(old, value);\r\n\t\t\t}catch(e){console.error(e)}\r\n\t\t}\r\n\t\treturn newValue2 !== void 0 ? newValue2 : newValue1;\r\n\t}\r\n\r\n\tvar inputBoundRunning = false;\r\n\tvar inputTextBound = function(e){\r\n\t\tif(e.fromSFFramework === true) return;\r\n\r\n\t\tinputBoundRunning = true;\r\n\t\tvar ref = e.target;\r\n\t\tref.viewInputted = true;\r\n\t\tvar value = ref.typeData === Number ? Number(ref.value) : ref.value;\r\n\t\tvar newValue = callInputListener(ref.sfModel, ref.sfBounded, value);\r\n\t\tif(newValue !== void 0)\r\n\t\t\tref.sfModel[ref.sfBounded] = newValue;\r\n\t\telse ref.sfModel[ref.sfBounded] = value;\r\n\t}\r\n\tvar inputFilesBound = function(e){\r\n\t\tif(e.fromSFFramework === true) return;\r\n\t\t\r\n\t\tvar ref = e.target;\r\n\t\tcallInputListener(ref.sfModel, ref.sfBounded, ref.files);\r\n\t\tref.sfModel[ref.sfBounded] = ref.files;\r\n\t}\r\n\r\n\tvar inputCheckBoxBound = function(e){\r\n\t\tif(e.fromSFFramework === true) return;\r\n\t\t\r\n\t\tinputBoundRunning = true;\r\n\t\tvar ref = e.target;\r\n\t\tref.viewInputted = true;\r\n\t\tvar value = ref.typeData === Number ? Number(ref.value) : ref.value;\r\n\t\tvar newValue = callInputListener(ref.sfModel, ref.sfBounded, value);\r\n\t\tif(newValue !== void 0)\r\n\t\t\tvalue = newValue;\r\n\r\n\t\tvar model = ref.sfModel;\r\n\t\tvar constructor = model[ref.sfBounded];\r\n\r\n\t\tif(constructor === Array){\r\n\t\t\tvar i = model[ref.sfBounded].indexOf(value);\r\n\r\n\t\t\tif(i === -1 && ref.checked === true)\r\n\t\t\t\tmodel[ref.sfBounded].push(value);\r\n\t\t\telse if(i !== -1 && ref.checked === false)\r\n\t\t\t\tmodel[ref.sfBounded].splice(i, 1);\r\n\t\t}\r\n\t\telse if(constructor === Boolean || ref.typeData === Boolean)\r\n\t\t\tmodel[ref.sfBounded] = ref.checked;\r\n\t\telse model[ref.sfBounded] = value;\r\n\t}\r\n\r\n\tvar inputSelectBound = function(e){\r\n\t\tif(e.fromSFFramework === true) return;\r\n\t\t\r\n\t\tinputBoundRunning = true;\r\n\t\tvar ref = e.target;\r\n\t\tref.viewInputted = true;\r\n\t\tvar typeData = ref.typeData;\r\n\t\tif(ref.multiple === true){\r\n\t\t\tvar temp = ref.selectedOptions;\r\n\t\t\tvar value = [];\r\n\t\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\t\tvalue.push(typeData === Number ? Number(temp[i].value) : temp[i].value);\r\n\t\t\t}\r\n\t\t}\r\n\t\telse value = typeData === Number ? Number(ref.selectedOptions[0].value) : ref.selectedOptions[0].value;\r\n\r\n\t\tvar newValue = callInputListener(ref.sfModel, ref.sfBounded, value);\r\n\t\tif(newValue !== void 0)\r\n\t\t\tref.sfModel[ref.sfBounded] = newValue;\r\n\t\telse ref.sfModel[ref.sfBounded] = value;\r\n\t}\r\n\r\n\tvar assignElementData = {\r\n\t\tselect:function(model, property, element){\r\n\t\t\tvar list = element.options;\r\n\t\t\tvar typeData = element.typeData;\r\n\t\t\tvar arrayValue = model[property].constructor === Array ? model[property] : false;\r\n\t\t\tfor (var i = 0, n = list.length; i < n; i++) {\r\n\t\t\t\tif(arrayValue === false){\r\n\t\t\t\t\tif(typeData === String)\r\n\t\t\t\t\t\tlist[i].selected = list[i].value === model[property];\r\n\t\t\t\t\telse list[i].selected = list[i].value == model[property];\r\n\t\t\t\t}\r\n\t\t\t\telse list[i].selected = arrayValue.indexOf(typeData === Number ? Number(list[i].value) : list[i].value) !== -1;\r\n\t\t\t}\r\n\t\t},\r\n\t\tcheckbox:function(model, property, element){\r\n\t\t\tif(model[property].constructor === Array)\r\n\t\t\t\telement.checked = model[property].indexOf(element.typeData === Number ? Number(element.value) : element.value) !== -1;\r\n\t\t\telse if(model[property].constructor === Boolean)\r\n\t\t\t\telement.checked = Boolean(model[property]);\r\n\t\t\telse{\r\n\t\t\t\tif(element.typeData === String)\r\n\t\t\t\t\telement.checked = element.value === model[property];\r\n\t\t\t\telse element.checked = element.value == model[property];\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tvar inputBoundRun = function(model, property, elements){\r\n\t\tif(inputBoundRunning === true)\r\n\t\t\treturn; // Avoid multiple assigment\r\n\r\n\t\tfor (var i = 0; i < elements.length; i++) {\r\n\t\t\tvar ev = new Event('change');\r\n\t\t\tev.fromSFFramework = true;\r\n\r\n\t\t\tif(elements.type === 1) // text\r\n\t\t\t\telements[i].value = model[property];\r\n\t\t\telse if(elements.type === 2) // select options\r\n\t\t\t\tassignElementData.select(model, property, elements[i]);\r\n\t\t\telse if(elements.type === 3) // radio\r\n\t\t\t\telements[i].checked = model[property] == elements[i].value;\r\n\t\t\telse if(elements.type === 4) // checkbox\r\n\t\t\t\tassignElementData.checkbox(model, property, elements[i]);\r\n\r\n\t\t\telements[i].dispatchEvent(ev);\r\n\t\t}\r\n\t}\r\n\r\n\tvar triggerInputEvent = function(e){\r\n\t\tif(e.fromSFFramework === true) return;\r\n\t\tif(e.target.viewInputted === true){\r\n\t\t\te.target.viewInputted = false;\r\n\t\t\treturn;\r\n\t\t}\r\n\t\te.target.dispatchEvent(new Event('input'));\r\n\t}\r\n\r\n\tvar elementBoundChanges = function(model, property, element, oneWay){\r\n\t\t// Enable multiple element binding\r\n\t\tif(model.sf$bindedKey === void 0)\r\n\t\t\tinitBindingInformation(model);\r\n\r\n\t\tvar type = 0;\r\n\t\tvar typeData = null;\r\n\t\tif(model[property] !== null && model[property] !== void 0)\r\n\t\t\ttypeData = model[property].constructor;\r\n\r\n\t\tvar assignedType = (element.getAttribute('typedata') || '').toLowerCase();\r\n\t\tif(assignedType === 'number')\r\n\t\t\ttypeData = Number;\r\n\r\n\t\telement.typeData = typeData;\r\n\t\t$.on(element, 'change', triggerInputEvent);\r\n\r\n\t\t// Bound value change\r\n\t\tif(element.tagName === 'TEXTAREA'){\r\n\t\t\t$.on(element, 'input', inputTextBound);\r\n\t\t\telement.value = model[property];\r\n\t\t\ttype = 1;\r\n\t\t}\r\n\r\n\t\telse if(element.selectedOptions !== void 0){\r\n\t\t\t$.on(element, 'input', inputSelectBound);\r\n\t\t\ttype = 2;\r\n\r\n\t\t\tassignElementData.select(model, property, element);\r\n\t\t}\r\n\r\n\t\telse{\r\n\t\t\tvar type = element.type.toLowerCase();\r\n\t\t\tif(type === 'radio'){\r\n\t\t\t\t$.on(element, 'input', inputTextBound);\r\n\t\t\t\ttype = 3;\r\n\r\n\t\t\t\telement.checked = model[property] == element.value;\r\n\t\t\t}\r\n\t\t\telse if(type === 'checkbox'){\r\n\t\t\t\t$.on(element, 'input', inputCheckBoxBound);\r\n\t\t\t\ttype = 4;\r\n\r\n\t\t\t\tassignElementData.checkbox(model, property, element);\r\n\t\t\t}\r\n\r\n\t\t\telse if(type === 'file'){\r\n\t\t\t\t$.on(element, 'input', inputFilesBound);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\telse{\r\n\t\t\t\t$.on(element, 'input', inputTextBound);\r\n\t\t\t\telement.value = model[property];\r\n\t\t\t\ttype = 1;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif(oneWay === true) return;\r\n\t\tmodelToViewBinding(model, property, inputBoundRun, element, type);\r\n\t}\r\n\r\n\tvar bindInput = function(targetNode){\r\n\t\tvar temp = $('input[sf-bound], textarea[sf-bound], select[sf-bound], input[sf-bind], textarea[sf-bind], select[sf-bind]', targetNode);\r\n\r\n\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\tvar element = temp[i];\r\n\t\t\tvar model = sf.controller.modelName(element);\r\n\t\t\tif(!model) return;\r\n\t\t\tvar modelScope = self.root[model];\r\n\r\n\t\t\tvar oneWay = false;\r\n\t\t\tvar propertyName = element.getAttribute('sf-bound');\r\n\t\t\tif(propertyName === null){\r\n\t\t\t\tpropertyName = element.getAttribute('sf-bind');\r\n\t\t\t\toneWay = true;\r\n\t\t\t}\r\n\t\t\tif(propertyName === \"\")\r\n\t\t\t\tpropertyName = element.getAttribute('name');\r\n\r\n\t\t\tif(propertyName === null){\r\n\t\t\t\tconsole.error(\"Property key to be bound wasn't be found\", element);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Get reference\r\n\t\t\tif(modelScope[propertyName] === void 0){\r\n\t\t\t\tconsole.error('Can\\'t get property \"'+propertyName+'\" on model \"' + model + '\"');\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\telement.sfBounded = propertyName;\r\n\t\t\telement.sfModel = modelScope;\r\n\t\t\tif(oneWay === false){\r\n\t\t\t\telement.setAttribute('sf-bounded', '');\r\n\t\t\t\telement.removeAttribute('sf-bound');\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\telement.setAttribute('sf-binded', '');\r\n\t\t\t\telement.removeAttribute('sf-bind');\r\n\t\t\t}\r\n\r\n\t\t\telementBoundChanges(modelScope, propertyName, element, oneWay);\r\n\t\t}\r\n\t}\r\n\r\n\tvar alreadyInitialized = false;\r\n\tself.init = function(targetNode, queued){\r\n\t\tif(alreadyInitialized && !targetNode) return;\r\n\t\talreadyInitialized = true;\r\n\t\tsetTimeout(function(){\r\n\t\t\talreadyInitialized = false;\r\n\t\t}, 50);\r\n\r\n\t\tif(!targetNode) targetNode = document.body;\r\n\r\n\t\tself.parsePreprocess(queued || self.queuePreprocess(targetNode), queued);\r\n\t\tbindInput(targetNode);\r\n\r\n\t\t// Find element for array binding\r\n\t\tvar temp = $('[sf-repeat-this]', targetNode);\r\n\t\tfor (var a = 0; a < temp.length; a++) {\r\n\t\t\tvar element = temp[a];\r\n\t\t\tvar parent = element.parentElement;\r\n\r\n\t\t\tif(queued !== void 0)\r\n\t\t\t\telement.classList.remove('sf-dom-queued');\r\n\r\n\t\t\tif(parent.classList.contains('sf-virtual-list')){\r\n\t\t\t\tvar ceiling = document.createElement(element.tagName);\r\n\t\t\t\tceiling.classList.add('virtual-spacer');\r\n\t\t\t\tvar floor = ceiling.cloneNode(true);\r\n\r\n\t\t\t\tceiling.classList.add('ceiling');\r\n\t\t\t\tparent.insertBefore(ceiling, parent.firstElementChild); // prepend\r\n\r\n\t\t\t\tfloor.classList.add('floor');\r\n\t\t\t\tparent.appendChild(floor); // append\r\n\t\t\t}\r\n\r\n\t\t\tvar after = element.nextElementSibling;\r\n\t\t\tif(after === null || element === after)\r\n\t\t\t\tafter = false;\r\n\r\n\t\t\tvar before = element.previousElementSibling;\r\n\t\t\tif(before === null || element === before)\r\n\t\t\t\tbefore = false;\r\n\r\n\t\t\tvar script = element.getAttribute('sf-repeat-this');\r\n\t\t\telement.removeAttribute('sf-repeat-this');\r\n\r\n\t\t\t// Check if the element was already bound to prevent vulnerability\r\n\t\t\tif(/sf-bind-key|sf-bind-list/.test(element.outerHTML))\r\n\t\t\t\tthrow \"Can't parse element that already bound\";\r\n\r\n\t\t\tvar controller = sf.controller.modelName(element);\r\n\t\t\tloopParser(controller, element, script, targetNode, parent);\r\n\t\t\telement.remove();\r\n\t\t}\r\n\t}\r\n\r\n\t// Reset model properties\r\n\t// Don't call if the removed element is TEXT or #comment\r\n\tvar DOMNodeRemoved = scope.DOMNodeRemoved = function(element){\r\n\t\tif(element.hasAttribute('sf-controller') !== false){\r\n\t\t\tvar modelName = element.sf$component === void 0 ? element.getAttribute('sf-controller') : element.sf$component;\r\n\r\n\t\t\tremoveModelBinding(modelName);\r\n\t\t\tif(element.sf$component !== void 0){\r\n\t\t\t\tvar modelFrom = element.sf$componentFrom;\r\n\t\t\t\tvar components = sf.component.available[modelFrom];\r\n\t\t\t\tcomponents.splice(components.indexOf(modelName), 1);\r\n\t\t\t\tinternal.component.triggerEvent(modelFrom, 'removed', self.root[modelName]);\r\n\t\t\t\tdelete self.root[modelName];\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar temp = $('[sf-controller]', element);\r\n\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\tDOMNodeRemoved(temp[i]);\r\n\t\t}\r\n\t}\r\n\r\n\tsf(function(){\r\n\t\tvar everyRemovedNodes = function(nodes){\r\n\t\t\tif(nodes.nodeType !== 1 || nodes.firstElementChild === null)\r\n\t\t\t\treturn;\r\n\r\n\t\t\tif(nodes.sf$elementReferences !== void 0) return;\r\n\t\t\tDOMNodeRemoved(nodes);\r\n\t\t}\r\n\r\n\t\tif(typeof MutationObserver === 'function' && MutationObserver.prototype.observe){\r\n\t\t\tvar everyRecords = function(record){\r\n\t\t\t\trecord.removedNodes.forEach(everyRemovedNodes);\r\n\t\t\t}\r\n\r\n\t\t\tvar observer = new MutationObserver(function(records){\r\n\t\t\t\tif(!bindingEnabled) return;\r\n\t\t\t\trecords.forEach(everyRecords);\r\n\t\t\t});\r\n\r\n\t\t\tobserver.observe(document.body, { childList: true, subtree: true });\r\n\t\t}\r\n\t\telse {\r\n\t\t\tdocument.body.addEventListener('DOMNodeRemoved', function(e){\r\n\t\t\t\tif(!bindingEnabled) return;\r\n\t\t\t\teveryRemovedNodes(e.target);\r\n\t\t\t});\r\n\t\t}\r\n\t});\r\n\r\n\tvar removeModelBinding = self.reset = function(modelName){\r\n\t\tvar ref = self.root[modelName];\r\n\t\tif(ref === void 0)\r\n\t\t\treturn;\r\n\r\n\t\tvar bindedKey = ref.sf$bindedKey;\r\n\t\tvar temp = null;\r\n\t\tfor(var key in bindedKey){\r\n\t\t\tdelete bindedKey[key];\r\n\r\n\t\t\tif(ref[key] === void 0 || ref[key] === null)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tif(ref[key].constructor === String ||\r\n\t\t\t\tref[key].constructor === Number ||\r\n\t\t\t\tref[key].constructor === Boolean\r\n\t\t\t){/* Ok */}\r\n\r\n\t\t\telse if(ref[key].constructor === Array){\r\n\t\t\t\tif(ref[key].$virtual){\r\n\t\t\t\t\tref[key].$virtual.destroy();\r\n\t\t\t\t\tdelete ref[key].$virtual;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Reset property without copying the array\r\n\t\t\t\ttemp = ref[key].splice('obtain');\r\n\t\t\t\tdelete ref[key];\r\n\t\t\t\tref[key] = temp;\r\n\t\t\t}\r\n\t\t\telse continue;\r\n\r\n\t\t\tif(Object.getOwnPropertyDescriptor(ref, key) === void 0)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\t// Reconfigure / Remove property descriptor\r\n\t\t\tvar temp = ref[key];\r\n\t\t\tdelete ref[key];\r\n\t\t\tref[key] = temp;\r\n\t\t}\r\n\t}\r\n\r\n\tfunction modelToViewBinding(model, propertyName, callback, elementBind, type){\r\n\t\t// Enable multiple element binding\r\n\t\tif(model.sf$bindedKey === void 0)\r\n\t\t\tinitBindingInformation(model);\r\n\r\n\t\tif(model.sf$bindedKey[propertyName] !== void 0){\r\n\t\t\tvar ref = model.sf$bindedKey[propertyName];\r\n\t\t\tif(ref.indexOf(callback) === -1)\r\n\t\t\t\tref.push(callback);\r\n\r\n\t\t\tif(elementBind !== void 0){\r\n\t\t\t\tif(ref.input === void 0){\r\n\t\t\t\t\tref.input = [elementBind];\r\n\t\t\t\t\tref.input.type = type;\r\n\t\t\t\t}\r\n\t\t\t\telse ref.input.push(elementBind);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmodel.sf$bindedKey[propertyName] = [callback];\r\n\r\n\t\tif(elementBind !== void 0){\r\n\t\t\tvar ref = model.sf$bindedKey[propertyName];\r\n\t\t\tref.input = [elementBind];\r\n\t\t\tref.input.type = type;\r\n\t\t}\r\n\r\n\t\t// Proxy property\r\n\t\tif(Object.getOwnPropertyDescriptor(model, propertyName).set !== void 0)\r\n\t\t\treturn;\r\n\r\n\t\tvar objValue = model[propertyName]; // Object value\r\n\t\tObject.defineProperty(model, propertyName, {\r\n\t\t\tenumerable: true,\r\n\t\t\tconfigurable: true,\r\n\t\t\tget:function(getAssigner){\r\n\t\t\t\treturn objValue;\r\n\t\t\t},\r\n\t\t\tset:function(val){\r\n\t\t\t\tif(objValue !== val){\r\n\t\t\t\t\tvar m2v = model['m2v$'+propertyName];\r\n\t\t\t\t\tvar out = inputBoundRunning === false ? model['out$'+propertyName] : void 0;\r\n\t\t\t\t\tvar callback = inputBoundRunning === false ? model['on$'+propertyName] : void 0;\r\n\r\n\t\t\t\t\tif(callback !== void 0 || m2v !== void 0 || out !== void 0){\r\n\t\t\t\t\t\tvar newValue1 = void 0; var newValue2 = void 0; var newValue3 = void 0;\r\n\t\t\t\t\t\ttry{\r\n\t\t\t\t\t\t\tif(m2v !== void 0)\r\n\t\t\t\t\t\t\t\tnewValue1 = m2v(objValue, val);\r\n\r\n\t\t\t\t\t\t\tif(out !== void 0)\r\n\t\t\t\t\t\t\t\tnewValue2 = out(objValue, val);\r\n\r\n\t\t\t\t\t\t\tif(callback !== void 0)\r\n\t\t\t\t\t\t\t\tnewValue3 = callback(objValue, val);\r\n\t\t\t\t\t\t}catch(e){console.error(e)}\r\n\r\n\t\t\t\t\t\tobjValue = (newValue3 !== void 0 ? newValue3 : \r\n\t\t\t\t\t\t\t(newValue2 !== void 0 ? newValue2 : \r\n\t\t\t\t\t\t\t(newValue1 !== void 0 ? newValue1 : val)\r\n\t\t\t\t\t\t));\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse objValue = val;\r\n\r\n\t\t\t\t\tvar ref = model.sf$bindedKey[propertyName];\r\n\t\t\t\t\tfor (var i = 0; i < ref.length; i++) {\r\n\t\t\t\t\t\tif(inputBoundRun === ref[i]){\r\n\t\t\t\t\t\t\tif(inputBoundRunning !== true) // Avoid multiple assigment\r\n\t\t\t\t\t\t\t\tref[i](model, propertyName, ref.input);\r\n\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tref[i]();\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tinputBoundRunning = false;\r\n\t\t\t\treturn objValue;\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tvar dcBracket = /{{[^#][\\s\\S]*?}}/;\r\n\tself.bindElement = function(element){\r\n\t\tvar modelName = sf.controller.modelName(element);\r\n\t\tvar model = self.root[modelName];\r\n\t\tif(!model) return console.error(\"Model for \"+modelName+\" was not found while binding:\", element);\r\n\r\n\t\tvar data = self.extractPreprocess(element, null, modelName);\r\n\t\ttemplateParser(data, model, true);\r\n\t\tdelete data.addresses;\r\n\t\telement.parentNode.replaceChild(data.html, element);\r\n\t\telement = data.html;\r\n\r\n\t\tvar onChanges = function(){\r\n\t\t\tif(syntheticTemplate(element, data, void 0, model) === false)\r\n\t\t\t\t0; //No update\r\n\t\t};\r\n\r\n\t\tvar properties = data.modelRef_array;\r\n\t\tfor (var i = 0; i < properties.length; i++) {\r\n\t\t\tvar propertyName = properties[i][0];\r\n\r\n\t\t\tif(model[propertyName] === void 0)\r\n\t\t\t\tmodel[propertyName] = '';\r\n\r\n\t\t\tmodelToViewBinding(model, propertyName, onChanges);\r\n\t\t}\r\n\t}\r\n\r\n\tself.extractPreprocess = function(targetNode, mask, name){\r\n\t\tvar copy = targetNode.outerHTML;\r\n\r\n\t\t// Mask the referenced item\r\n\t\tif(mask !== null)\r\n\t\t\tcopy = copy.split('#'+mask).join('_model_');\r\n\r\n\t\t// Extract data to be parsed\r\n\t\tcopy = uniqueDataParser(copy, null, mask, name, '#noEval');\r\n\t\tvar preParsed = copy[1];\r\n\t\tvar _content_ = copy[2];\r\n\t\tcopy = dataParser(copy[0], null, mask, name, '#noEval', preParsed);\r\n\r\n\t\tfunction findModelProperty(){\r\n\t\t\tif(mask === null){\r\n\t\t\t\t// Get model keys and sort by text length, make sure the longer one is from first index to avoid wrong match\r\n\t\t\t\tvar extract = RegExp('('+self.modelKeys(self.root[name]).sort(function(a, b){\r\n\t\t\t\t\treturn b.length - a.length\r\n\t\t\t\t}).join('|')+')', 'g');\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t\tvar extract = RegExp('\\\\b(?:_model_|'+mask+')\\\\.([a-zA-Z0-9.[\\'\\\\]]+)(?:$|[^\\'\\\\]])', 'g');\r\n\t\t\tvar found = {};\r\n\r\n\t\t\tfor (var i = 0; i < preParsed.length; i++) {\r\n\t\t\t\tvar current = preParsed[i];\r\n\r\n\t\t\t\t// Text or attribute\r\n\t\t\t\tif(current.type === 0){\r\n\t\t\t\t\tcurrent.data[0].split('\"').join(\"'\").replace(extract, function(full, match){\r\n\t\t\t\t\t\tmatch = match.replace(/\\['(.*?)'\\]/g, function(full_, match_){\r\n\t\t\t\t\t\t\treturn '.'+match_;\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\tif(found[match] === void 0) found[match] = [i];\r\n\t\t\t\t\t\telse if(found[match].indexOf(i) === -1)\r\n\t\t\t\t\t\t\tfound[match].push(i);\r\n\t\t\t\t\t});\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Dynamic data\r\n\t\t\t\tif(current.type === 1){\r\n\t\t\t\t\tvar checkList = current.if.join(';');\r\n\r\n\t\t\t\t\tif(current.elseValue !== null)\r\n\t\t\t\t\t\tcheckList += ';' + current.elseValue;\r\n\r\n\t\t\t\t\tfor (var a = 0; a < current.elseIf.length; a++) {\r\n\t\t\t\t\t\tcheckList += current.elseIf[a].join(';');\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse if(current.type === 2)\r\n\t\t\t\t\tvar checkList = current.data[0];\r\n\r\n\t\t\t\tcheckList = checkList.replace(/_result_ \\+= _content_\\.take\\(.*?, ([0-9]+)\\);/g, function(full, match){\r\n\t\t\t\t\treturn _content_[match];\r\n\t\t\t\t});\r\n\r\n\t\t\t\tcheckList.split('\"').join(\"'\").replace(extract, function(full, match){\r\n\t\t\t\t\tmatch = match.replace(/\\['(.*?)'\\]/g, function(full_, match_){\r\n\t\t\t\t\t\treturn '.'+match_;\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tif(found[match] === void 0) found[match] = [i];\r\n\t\t\t\t\telse if(found[match].indexOf(i) === -1)\r\n\t\t\t\t\t\tfound[match].push(i);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\treturn found;\r\n\t\t}\r\n\r\n\t\t// Build element and start addressing\r\n\t\tcopy = $.parseElement(copy)[0];\r\n\t\tvar nodes = self.queuePreprocess(copy, true).reverse();\r\n\t\tvar addressed = [];\r\n\r\n\t\tfunction addressAttributes(currentNode){\r\n\t\t\tvar attrs = currentNode.attributes;\r\n\t\t\tvar keys = [];\r\n\t\t\tvar indexes = 0;\r\n\t\t\tfor (var a = 0; a < attrs.length; a++) {\r\n\t\t\t\tvar found = attrs[a].value.split('{{%=');\r\n\t\t\t\tif(found.length !== 1){\r\n\t\t\t\t\tif(attrs[a].name[0] === ':'){\r\n\t\t\t\t\t\tvar key = {\r\n\t\t\t\t\t\t\tname:attrs[a].name.split(':').join(''),\r\n\t\t\t\t\t\t\tvalue:attrs[a].value\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t\tcurrentNode.removeAttribute(attrs[a].name);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse var key = {\r\n\t\t\t\t\t\tname:attrs[a].name,\r\n\t\t\t\t\t\tvalue:attrs[a].value\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\t\tindexes = [];\r\n\t\t\t\t\tfound = key.value.replace(/{{%=([0-9]+)/g, function(full, match){\r\n\t\t\t\t\t\tindexes.push(Number(match));\r\n\t\t\t\t\t\treturn '';\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tif(found === '' && indexes.length === 1)\r\n\t\t\t\t\t\tkey.direct = indexes[0];\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tkey.parse_index = indexes;\r\n\r\n\t\t\t\t\tkeys.push(key);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn keys;\r\n\t\t}\r\n\r\n\t\tvar currentElement = addressAttributes(copy);\r\n\t\tif(currentElement.length !== 0)\r\n\t\t\taddressed.push({\r\n\t\t\t\tnodeType:1,\r\n\t\t\t\taddress:[0],\r\n\t\t\t\tattributes:currentElement\r\n\t\t\t});\r\n\r\n\t\tfor (var i = 0; i < nodes.length; i++) {\r\n\t\t\tvar temp = {\r\n\t\t\t\tnodeType:nodes[i].nodeType\r\n\t\t\t};\r\n\r\n\t\t\tif(temp.nodeType === 1){ // Element\r\n\t\t\t\ttemp.attributes = addressAttributes(nodes[i]);\r\n\t\t\t\ttemp.address = $.getSelector(nodes[i], true);\r\n\t\t\t}\r\n\r\n\t\t\telse if(temp.nodeType === 3){ // Text node\r\n\t\t\t\tvar innerHTML = nodes[i].textContent;\r\n\t\t\t\tvar indexes = [];\r\n\r\n\t\t\t\tinnerHTML.replace(/{{%%=([0-9]+)/gm, function(full, match){\r\n\t\t\t\t\tindexes.push(Number(match));\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// Check for dynamic mode\r\n\t\t\t\tif(indexes.length !== 0){\r\n\t\t\t\t\tinnerHTML = innerHTML.split(/{{%%=[0-9]+/gm);\r\n\t\t\t\t\tfor (var a = 0; a < innerHTML.length; a++) {\r\n\t\t\t\t\t\tinnerHTML[a] = trimIndentation(innerHTML[a]).trim();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tnodes[i].textContent = innerHTML.shift();\r\n\r\n\t\t\t\t\tvar parent = nodes[i].parentNode;\r\n\t\t\t\t\tvar nextSibling = nodes[i].nextSibling;\r\n\r\n\t\t\t\t\t// Dynamic boundary start\r\n\t\t\t\t\tvar addressStart = null;\r\n\t\t\t\t\tif(indexes.length !== 0 && nodes[i].textContent.length !== 0)\r\n\t\t\t\t\t\taddressStart = $.getSelector(nodes[i], true);\r\n\t\t\t\t\telse if(nodes[i].previousSibling !== null)\r\n\t\t\t\t\t\taddressStart = $.getSelector(nodes[i].previousSibling, true);\r\n\r\n\t\t\t\t\t// Find boundary ends\r\n\t\t\t\t\tvar commentFlag = [];\r\n\t\t\t\t\tfor(var a = 0; a < indexes.length; a++){\r\n\t\t\t\t\t\tvar flag = document.createComment('');\r\n\t\t\t\t\t\tparent.insertBefore(flag, nextSibling);\r\n\t\t\t\t\t\tcommentFlag.push({\r\n\t\t\t\t\t\t\tnodeType:-1,\r\n\t\t\t\t\t\t\tparse_index:indexes[a],\r\n\t\t\t\t\t\t\tstartFlag:addressStart,\r\n\t\t\t\t\t\t\taddress:$.getSelector(flag, true)\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\tif(innerHTML[a]){\r\n\t\t\t\t\t\t\tvar textNode = document.createTextNode(innerHTML[a]);\r\n\t\t\t\t\t\t\tparent.insertBefore(textNode, nextSibling);\r\n\r\n\t\t\t\t\t\t\t// Get new start flag\r\n\t\t\t\t\t\t\tif(a + 1 < indexes.length)\r\n\t\t\t\t\t\t\t\taddressStart = $.getSelector(textNode, true);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Merge boundary address\r\n\t\t\t\t\tArray.prototype.push.apply(addressed, commentFlag);\r\n\t\t\t\t\tif(nodes[i].textContent === ''){\r\n\t\t\t\t\t\tnodes[i].remove();\r\n\t\t\t\t\t\tfor (var a = 0; a < commentFlag.length; a++) {\r\n\t\t\t\t\t\t\tvar ref = commentFlag[a].address;\r\n\t\t\t\t\t\t\tref[ref.length - 1]--;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse if(nodes[i].textContent.search(/{{%=[0-9]+/) === -1)\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Check if it's only model value\r\n\t\t\t\tindexes = [];\r\n\t\t\t\tinnerHTML = nodes[i].textContent.replace(/{{%=([0-9]+)/gm, function(full, match){\r\n\t\t\t\t\tindexes.push(Number(match));\r\n\t\t\t\t\treturn '';\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif(innerHTML === '' && indexes.length === 1)\r\n\t\t\t\t\ttemp.direct = indexes[0];\r\n\t\t\t\telse{\r\n\t\t\t\t\ttemp.value = nodes[i].textContent;\r\n\t\t\t\t\ttemp.parse_index = indexes;\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttemp.address = $.getSelector(nodes[i], true);\r\n\t\t\t}\r\n\r\n\t\t\taddressed.push(temp);\r\n\t\t}\r\n\r\n\t\tvar modelReference = findModelProperty();\r\n\t\tvar keys = Object.keys(modelReference);\r\n\t\tvar asArray = [];\r\n\t\tfor (var i = 0; i < keys.length; i++) {\r\n\t\t\tasArray.push([keys[i], keys[i].split('.')]);\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\thtml:copy,\r\n\t\t\tparse:preParsed,\r\n\t\t\taddresses:addressed,\r\n\t\t\tmodelReference:modelReference,\r\n\t\t\tmodelRef_array:asArray\r\n\t\t};\r\n\t}\r\n\r\n\tvar enclosedHTMLParse = false;\r\n\tvar excludes = ['HTML','HEAD','STYLE','LINK','META','SCRIPT','OBJECT','IFRAME'];\r\n\tself.queuePreprocess = function(targetNode, extracting){\r\n\t\tvar childNodes = (targetNode || document.body).childNodes;\r\n\r\n\t\tvar temp = [];\r\n\t\tfor (var i = childNodes.length - 1; i >= 0; i--) {\r\n\t\t\tvar currentNode = childNodes[i];\r\n\r\n\t\t\tif(extracting === void 0 && excludes.indexOf(currentNode.nodeName) !== -1)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tif(currentNode.nodeType === 1){ // Tag\r\n\t\t\t\tif(enclosedHTMLParse === true) continue;\r\n\t\t\t\tvar attrs = currentNode.attributes;\r\n\r\n\t\t\t\t// Skip element and it's childs that already bound to prevent vulnerability\r\n\t\t\t\tif(attrs['sf-bind-key'] || attrs['sf-repeat-this'] || attrs['sf-bind-list']) continue;\r\n\r\n\t\t\t\tfor (var a = 0; a < attrs.length; a++) {\r\n\t\t\t\t\tif(attrs[a].value.indexOf('{{') !== -1){\r\n\t\t\t\t\t\ttemp.push(currentNode);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tArray.prototype.push.apply(temp, self.queuePreprocess(currentNode, extracting));\r\n\t\t\t}\r\n\r\n\t\t\telse if(currentNode.nodeType === 3){ // Text\r\n\t\t\t\tif(currentNode.textContent.length === 0){\r\n\t\t\t\t\tcurrentNode.remove();\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// The scan is from bottom to first index\r\n\t\t\t\tvar enclosing = currentNode.textContent.indexOf('{[');\r\n\t\t\t\tif(enclosing !== -1)\r\n\t\t\t\t\tenclosedHTMLParse = false;\r\n\t\t\t\telse if(enclosedHTMLParse === true)\r\n\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\t// Start enclosed if closing pattern was found\r\n\t\t\t\tvar enclosed = currentNode.textContent.indexOf(']}');\r\n\t\t\t\tif(enclosed !== -1 && (enclosing === -1 || enclosing > enclosed)){ // avoid {[ ... ]}\r\n\t\t\t\t\tenclosedHTMLParse = true; // when ]} ... \r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(currentNode.nodeValue.indexOf('{{') !== -1){\r\n\t\t\t\t\tif(extracting === void 0){\r\n\t\t\t\t\t\ttemp.push(currentNode.parentNode);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\ttemp.push(currentNode);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn temp;\r\n\t}\r\n\r\n\tself.parsePreprocess = function(nodes, queued){\r\n\t\tfor (var a = 0; a < nodes.length; a++) {\r\n\t\t\t// Get reference for debugging\r\n\t\t\tvar current = processingElement = nodes[a];\r\n\r\n\t\t\tvar modelElement = sf.controller.modelElement(current);\r\n\t\t\tif(modelElement === null)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tvar model = modelElement.sf$component === void 0 ? modelElement.getAttribute('sf-controller') : modelElement.sf$component;\r\n\r\n\t\t\tif(queued !== void 0)\r\n\t\t\t\tcurrent.classList.remove('sf-dom-queued');\r\n\r\n\t\t\t// Check if it's component\r\n\t\t\tif(self.root[model] === void 0 && sf.component.registered[model])\r\n\t\t\t\tmodel = sf.component.new(model, modelElement);\r\n\r\n\t\t\tvar modelRef = self.root[model] || root_(model);\r\n\r\n\t\t\t// Double check if the child element already bound to prevent vulnerability\r\n\t\t\tif(/sf-bind-key|sf-bind-list/.test(current.innerHTML)){\r\n\t\t\t\tconsole.error(\"Can't parse element that already bound\");\r\n\t\t\t\tconsole.log(processingElement.cloneNode(true));\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif(current.hasAttribute('sf-bind-ignore') === false)\r\n\t\t\t\tself.bindElement(current);\r\n\t\t\telse{\r\n\t\t\t\tvar temp = uniqueDataParser(current.innerHTML, modelRef, false, model);\r\n\t\t\t\tcurrent.innerHTML = dataParser(temp, modelRef, false, model);\r\n\t\t\t\tvar attrs = current.attributes;\r\n\t\t\t\tfor (var i = 0; i < attrs.length; i++) {\r\n\t\t\t\t\tif(attrs[i].value.indexOf('{{') !== -1){\r\n\t\t\t\t\t\tvar attr = attrs[i];\r\n\t\t\t\t\t\tattr.value = dataParser(attr.value, modelRef, false, model);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tfunction initBindingInformation(modelRef){\r\n\t\tif(modelRef.sf$bindedKey !== void 0)\r\n\t\t\treturn;\r\n\r\n\t\t// Element binding data\r\n\t\tObject.defineProperty(modelRef, 'sf$bindedKey', {\r\n\t\t\tconfigurable: true,\r\n\t\t\tenumerable:false,\r\n\t\t\twritable:true,\r\n\t\t\tvalue:{}\r\n\t\t});\r\n\t}\r\n})();","// DOM Controller on loaded app\r\nsf.controller = new function(){\r\n\tvar self = this;\r\n\tself.pending = {};\r\n\tself.active = {};\r\n\r\n\tself.for = function(name, func){\r\n\t\tif(sf.component.registered[name]){\r\n\t\t\tsf.component.registered[name][1] = func;\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tself.pending[name] = func;\r\n\t}\r\n\r\n\tself.modelScope = function(element, func){\r\n\t\tvar model = sf.controller.modelName(element);\r\n\r\n\t\tif(!model)\r\n\t\t\tthrow 'model or controller was not found';\r\n\r\n\t\tvar bindedList = element.getAttribute('sf-bind-list');\r\n\t\tif(!bindedList){\r\n\t\t\tvar parentEl = $.parent(element, '[sf-bind-list]');\r\n\t\t\tif(parentEl !== null)\r\n\t\t\t\tbindedList = parentEl.getAttribute('sf-bind-list');\r\n\t\t}\r\n\t\telse var parentEl = element;\r\n\r\n\t\tif(!bindedList){\r\n\t\t\tif(func) return func(sf.model.root[model], -1);\r\n\t\t\telse return sf.model.root[model];\r\n\t\t}\r\n\r\n\t\t// Find index\r\n\t\tvar bindedListIndex = 0;\r\n\t\tif(bindedList)\r\n\t\t\tbindedListIndex = $.prevAll(parentEl, '[sf-bind-list]').length;\r\n\r\n\t\tif(func) return func(sf.model.root[model][bindedList], bindedListIndex);\r\n\t\telse return sf.model.root[model][bindedList][bindedListIndex];\r\n\t}\r\n\r\n\tself.modelElement = function(element){\r\n\t\tif(element.nodeType === 1 && element.hasAttribute('sf-controller') === true)\r\n\t\t\treturn element;\r\n\r\n\t\treturn $.parent(element, '[sf-controller]');\r\n\t}\r\n\r\n\tself.modelName = function(element){\r\n\t\tvar name = self.modelElement(element);\r\n\t\tif(name === null){\r\n\t\t\tconsole.error(\"Can't find any controller for\", element);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tname = name.sf$component === void 0 ? name.getAttribute('sf-controller') : name.sf$component;\r\n\r\n\t\t// Initialize it first\r\n\t\tif(name !== void 0 && !self.active[name])\r\n\t\t\tself.run(name);\r\n\r\n\t\treturn name;\r\n\t}\r\n\r\n\tvar listenSFClick = function(e){\r\n\t\tvar element = e.target;\r\n\t\tvar script = element.getAttribute('sf-click');\r\n\r\n\t\tif(!script){\r\n\t\t\telement = $.parent(element, '[sf-click]');\r\n\t\t\tscript = element.getAttribute('sf-click');\r\n\t\t}\r\n\r\n\t\tvar model = $.parent(element, '[sf-controller]');\r\n\t\tmodel = model.sf$component === void 0? model.getAttribute('sf-controller') : model;\r\n\r\n\t\tif(!sf.model.root[model])\r\n\t\t\tthrow \"Couldn't find model for \"+model+\" that was called from sf-click\";\r\n\r\n\t\tvar modelKeys = sf.model.modelKeys(sf.model.root[model]).join('|');\r\n\t\tscript = avoidQuotes(script, function(script_){\r\n\t\t\treturn script_.replace(RegExp(sf.regex.strictVar+'('+modelKeys+')\\\\b', 'g'), function(full, matched){\r\n\t\t\t\treturn '_modelScope.'+matched;\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tscript = script.split('(');\r\n\r\n\t\tvar method = script[0];\r\n\t\tvar method_ = method;\r\n\r\n\t\t// Get method reference\r\n\t\ttry{\r\n\t\t\tmethod = eval(method);\r\n\t\t} catch(e) {\r\n\t\t\tmethod = false;\r\n\t\t}\r\n\r\n\t\tif(!method){\r\n\t\t\tconsole.error(\"Error on sf-click for model: \" + model + ' [Cannot call `'+method_+'`]\\n', element);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Take the argument list\r\n\t\tscript.shift();\r\n\t\tscript = script.join('(');\r\n\t\tscript = script.split(')');\r\n\t\tscript.pop();\r\n\t\tscript = script.join('(');\r\n\r\n\t\t// Turn argument as array\r\n\t\tif(script.length !== 0){\r\n\t\t\t// Replace `this` to `element`\r\n\t\t\tscript = eval(('['+script+']').replace(/,this|\\[this/g, function(found){\r\n\t\t\t\treturn found[0] + 'element';\r\n\t\t\t}));\r\n\t\t}\r\n\t\tif(!script)\r\n\t\t\tscript = [];\r\n\r\n\t\ttry{\r\n\t\t\tmethod.apply(element, script);\r\n\t\t\te.preventDefault();\r\n\t\t} catch(e) {\r\n\t\t\tconsole.error(\"Error on sf-click for model: \" + model + '\\n', element, '\\n', e);\r\n\t\t}\r\n\t}\r\n\r\n\tself.run = function(name, func){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.run(name, func);\r\n\t\t\t});\r\n\r\n\t\tif(sf.component.registered[name])\r\n\t\t\treturn console.error(\"'\"+name+\"' is registered as a component\");\r\n\r\n\t\tif(self.pending[name]){\r\n\t\t\tif(!sf.model.root[name])\r\n\t\t\t\tsf.model.root[name] = {};\r\n\r\n\t\t\tself.pending[name](sf.model.root[name], root_);\r\n\t\t\tself.active[name] = true;\r\n\t\t\tdelete self.pending[name];\r\n\t\t}\r\n\r\n\t\tif(sf.model.root[name] === void 0)\r\n\t\t\tsf.model.root[name] = {};\r\n\r\n\t\tif(func)\r\n\t\t\tfunc(sf.model.root[name], root_);\r\n\t}\r\n\r\n\tself.init = function(parent){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.init(name);\r\n\t\t\t});\r\n\r\n\t\tvar temp = $('[sf-controller]', parent || document.body);\r\n\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\tself.run(temp[i].sf$component === void 0? temp[i].getAttribute('sf-controller') : temp[i].sf$component);\r\n\t\t}\r\n\t}\r\n\r\n\t// Create listener for sf-click\r\n\tdocument.addEventListener('DOMContentLoaded', function(){\r\n\t\t$.on(document.body, 'click', '[sf-click]', listenSFClick);\r\n\t}, {capture:true, once:true});\r\n}\r\n\r\nvar root_ = function(scope){\r\n\tif(sf.component.registered[scope]){\r\n\t\tvar available = [];\r\n\t\tvar component = sf.component.available[scope];\r\n\t\tif(component !== void 0){\r\n\t\t\tfor (var i = 0; i < component.length; i++) {\r\n\t\t\t\tavailable.push(sf.model.root[component[i]]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn available;\r\n\t}\r\n\r\n\tif(!sf.model.root[scope])\r\n\t\tsf.model.root[scope] = {};\r\n\r\n\treturn sf.model.root[scope];\r\n}","/*\r\n Special Thanks to Vladimir Kharlampidi\r\n https://github.com/nolimits4web/\r\n*/\r\n\r\nvar globals = {};\r\nvar jsonpRequests = 0;\r\nfunction Request(requestOptions) {\r\n var globalsNoCallbacks = Object.assign({}, globals);\r\n ('beforeCreate beforeOpen beforeSend error complete success statusCode').split(' ').forEach(function (callbackName) {\r\n delete globalsNoCallbacks[callbackName];\r\n });\r\n var defaults = Object.assign({\r\n url: window.location.toString(),\r\n method: 'GET',\r\n data: false,\r\n async: true,\r\n cache: true,\r\n user: '',\r\n password: '',\r\n headers: {},\r\n xhrFields: {},\r\n statusCode: {},\r\n processData: true,\r\n dataType: 'text',\r\n contentType: 'application/x-www-form-urlencoded',\r\n timeout: 0,\r\n }, globalsNoCallbacks);\r\n var options = Object.assign({}, defaults, requestOptions);\r\n var proceedRequest;\r\n // Function to run XHR callbacks and events\r\n function fireCallback(callbackName) {\r\n var data = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n data[_i - 1] = arguments[_i];\r\n }\r\n /*\r\n Callbacks:\r\n beforeCreate (options),\r\n beforeOpen (xhr, options),\r\n beforeSend (xhr, options),\r\n error (xhr, status),\r\n complete (xhr, stautus),\r\n success (response, status, xhr),\r\n statusCode ()\r\n */\r\n var globalCallbackValue;\r\n var optionCallbackValue;\r\n if (globals[callbackName]) {\r\n globalCallbackValue = globals[callbackName].apply(globals, data);\r\n }\r\n if (options[callbackName]) {\r\n optionCallbackValue = options[callbackName].apply(options, data);\r\n }\r\n if (typeof globalCallbackValue !== 'boolean')\r\n globalCallbackValue = true;\r\n if (typeof optionCallbackValue !== 'boolean')\r\n optionCallbackValue = true;\r\n return (globalCallbackValue && optionCallbackValue);\r\n }\r\n // Before create callback\r\n proceedRequest = fireCallback('beforeCreate', options);\r\n if (proceedRequest === false)\r\n return void 0;\r\n // For jQuery guys\r\n if (options.type)\r\n options.method = options.type;\r\n // Parameters Prefix\r\n var paramsPrefix = options.url.indexOf('?') >= 0 ? '&' : '?';\r\n // UC method\r\n var method = options.method.toUpperCase();\r\n // Data to modify GET URL\r\n if ((method === 'GET' || method === 'HEAD' || method === 'OPTIONS' || method === 'DELETE') && options.data) {\r\n var stringData = void 0;\r\n if (typeof options.data === 'string') {\r\n // Should be key=value string\r\n if (options.data.indexOf('?') >= 0)\r\n stringData = options.data.split('?')[1];\r\n else\r\n stringData = options.data;\r\n }\r\n else {\r\n // Should be key=value object\r\n stringData = serializeQuery(options.data);\r\n }\r\n if (stringData.length) {\r\n options.url += paramsPrefix + stringData;\r\n if (paramsPrefix === '?')\r\n paramsPrefix = '&';\r\n }\r\n }\r\n // JSONP\r\n if (options.dataType === 'json' && options.url.indexOf('callback=') >= 0) {\r\n var callbackName_1 = \"jsonp_\" + (Date.now() + ((jsonpRequests += 1)));\r\n var abortTimeout_1;\r\n var callbackSplit = options.url.split('callback=');\r\n var requestUrl = callbackSplit[0] + \"callback=\" + callbackName_1;\r\n if (callbackSplit[1].indexOf('&') >= 0) {\r\n var addVars = callbackSplit[1].split('&').filter(function (el) { return el.indexOf('=') > 0; }).join('&');\r\n if (addVars.length > 0)\r\n requestUrl += \"&\" + addVars;\r\n }\r\n // Create script\r\n var script_1 = document.createElement('script');\r\n script_1.type = 'text/javascript';\r\n script_1.onerror = function onerror() {\r\n clearTimeout(abortTimeout_1);\r\n fireCallback('error', null, 'scripterror');\r\n fireCallback('complete', null, 'scripterror');\r\n };\r\n script_1.src = requestUrl;\r\n // Handler\r\n window[callbackName_1] = function jsonpCallback(data) {\r\n clearTimeout(abortTimeout_1);\r\n fireCallback('success', data);\r\n script_1.parentNode.removeChild(script_1);\r\n script_1 = null;\r\n delete window[callbackName_1];\r\n };\r\n document.querySelector('head').appendChild(script_1);\r\n if (options.timeout > 0) {\r\n abortTimeout_1 = setTimeout(function () {\r\n script_1.parentNode.removeChild(script_1);\r\n script_1 = null;\r\n fireCallback('error', null, 'timeout');\r\n }, options.timeout);\r\n }\r\n return void 0;\r\n }\r\n // Cache for GET/HEAD requests\r\n if (method === 'GET' || method === 'HEAD' || method === 'OPTIONS' || method === 'DELETE') {\r\n if (options.cache === false) {\r\n options.url += paramsPrefix + \"_nocache\" + Date.now();\r\n }\r\n }\r\n // Create XHR\r\n var xhr = new XMLHttpRequest();\r\n // Save Request URL\r\n xhr.requestUrl = options.url;\r\n xhr.requestParameters = options;\r\n // Before open callback\r\n proceedRequest = fireCallback('beforeOpen', xhr, options);\r\n if (proceedRequest === false)\r\n return xhr;\r\n // Open XHR\r\n xhr.open(method, options.url, options.async, options.user, options.password);\r\n // Create POST Data\r\n var postData = null;\r\n if ((method === 'POST' || method === 'PUT' || method === 'PATCH') && options.data) {\r\n if (options.processData) {\r\n var postDataInstances = [ArrayBuffer, Blob, Document, FormData];\r\n // Post Data\r\n if (postDataInstances.indexOf(options.data.constructor) >= 0) {\r\n postData = options.data;\r\n }\r\n else {\r\n // POST Headers\r\n var boundary = \"---------------------------\" + Date.now().toString(16);\r\n if (options.contentType === 'multipart/form-data') {\r\n xhr.setRequestHeader('Content-Type', \"multipart/form-data; boundary=\" + boundary);\r\n }\r\n else {\r\n xhr.setRequestHeader('Content-Type', options.contentType);\r\n }\r\n postData = '';\r\n var data = serializeQuery(options.data);\r\n if (options.contentType === 'multipart/form-data') {\r\n data = data.split('&');\r\n var newData = [];\r\n for (var i = 0; i < data.length; i += 1) {\r\n newData.push(\"Content-Disposition: form-data; name=\\\"\" + data[i].split('=')[0] + \"\\\"\\r\\n\\r\\n\" + data[i].split('=')[1] + \"\\r\\n\");\r\n }\r\n postData = \"--\" + boundary + \"\\r\\n\" + newData.join(\"--\" + boundary + \"\\r\\n\") + \"--\" + boundary + \"--\\r\\n\";\r\n }\r\n else if (options.contentType === 'application/json') {\r\n postData = JSON.stringify(options.data);\r\n }\r\n else {\r\n postData = data;\r\n }\r\n }\r\n }\r\n else {\r\n postData = options.data;\r\n xhr.setRequestHeader('Content-Type', options.contentType);\r\n }\r\n }\r\n // Additional headers\r\n if (options.headers) {\r\n Object.keys(options.headers).forEach(function (headerName) {\r\n xhr.setRequestHeader(headerName, options.headers[headerName]);\r\n });\r\n }\r\n // Check for crossDomain\r\n if (typeof options.crossDomain === 'void 0') {\r\n // eslint-disable-next-line\r\n options.crossDomain = /^([\\w-]+:)?\\/\\/([^\\/]+)/.test(options.url) && RegExp.$2 !== window.location.host;\r\n }\r\n if (!options.crossDomain) {\r\n xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\r\n }\r\n if (options.xhrFields) {\r\n Object.assign(xhr, options.xhrFields);\r\n }\r\n var xhrTimeout;\r\n // Handle XHR\r\n xhr.onload = function onload() {\r\n if (xhrTimeout)\r\n clearTimeout(xhrTimeout);\r\n if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {\r\n var responseData = void 0;\r\n if (options.dataType === 'json') {\r\n var parseError = void 0;\r\n try {\r\n responseData = JSON.parse(xhr.responseText);\r\n }\r\n catch (err) {\r\n parseError = true;\r\n }\r\n if (!parseError) {\r\n fireCallback('success', responseData, xhr.status, xhr);\r\n }\r\n else {\r\n fireCallback('error', xhr, 'parseerror');\r\n }\r\n }\r\n else {\r\n responseData = xhr.responseType === 'text' || xhr.responseType === '' ? xhr.responseText : xhr.response;\r\n fireCallback('success', responseData, xhr.status, xhr);\r\n }\r\n }\r\n else {\r\n fireCallback('error', xhr, xhr.status);\r\n }\r\n if (options.statusCode) {\r\n if (globals.statusCode && globals.statusCode[xhr.status])\r\n globals.statusCode[xhr.status](xhr);\r\n if (options.statusCode[xhr.status])\r\n options.statusCode[xhr.status](xhr);\r\n }\r\n fireCallback('complete', xhr, xhr.status);\r\n };\r\n xhr.onerror = function onerror() {\r\n if (xhrTimeout)\r\n clearTimeout(xhrTimeout);\r\n fireCallback('error', xhr, xhr.status);\r\n fireCallback('complete', xhr, 'error');\r\n };\r\n // Timeout\r\n if (options.timeout > 0) {\r\n xhr.onabort = function onabort() {\r\n if (xhrTimeout)\r\n clearTimeout(xhrTimeout);\r\n };\r\n xhrTimeout = setTimeout(function () {\r\n xhr.abort();\r\n fireCallback('error', xhr, 'timeout');\r\n fireCallback('complete', xhr, 'timeout');\r\n }, options.timeout);\r\n }\r\n // Ajax start callback\r\n proceedRequest = fireCallback('beforeSend', xhr, options);\r\n if (proceedRequest === false)\r\n return xhr;\r\n // Send XHR\r\n xhr.send(postData);\r\n // Return XHR object\r\n return xhr;\r\n}\r\nfunction RequestShortcut(method) {\r\n var args = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n args[_i - 1] = arguments[_i];\r\n }\r\n var _a = [], url = _a[0], data = _a[1], success = _a[2], error = _a[3], dataType = _a[4];\r\n if (typeof args[1] === 'function') {\r\n url = args[0], success = args[1], error = args[2], dataType = args[3];\r\n }\r\n else {\r\n url = args[0], data = args[1], success = args[2], error = args[3], dataType = args[4];\r\n }\r\n [success, error].forEach(function (callback) {\r\n if (typeof callback === 'string') {\r\n dataType = callback;\r\n if (callback === success)\r\n success = void 0;\r\n else\r\n error = void 0;\r\n }\r\n });\r\n dataType = dataType || (method === 'json' || method === 'postJSON' ? 'json' : void 0);\r\n var requestOptions = {\r\n url: url,\r\n method: method === 'post' || method === 'postJSON' ? 'POST' : 'GET',\r\n data: data,\r\n success: success,\r\n error: error,\r\n dataType: dataType,\r\n };\r\n if (method === 'postJSON') {\r\n Object.assign(requestOptions, {\r\n contentType: 'application/json',\r\n processData: false,\r\n crossDomain: true,\r\n data: typeof data === 'string' ? data : JSON.stringify(data),\r\n });\r\n }\r\n return Request(requestOptions);\r\n}\r\nObject.assign(Request, {\r\n get: function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n return RequestShortcut.apply(void 0, ['get'].concat(args));\r\n },\r\n post: function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n return RequestShortcut.apply(void 0, ['post'].concat(args));\r\n },\r\n json: function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n return RequestShortcut.apply(void 0, ['json'].concat(args));\r\n },\r\n getJSON: function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n return RequestShortcut.apply(void 0, ['json'].concat(args));\r\n },\r\n postJSON: function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n return RequestShortcut.apply(void 0, ['postJSON'].concat(args));\r\n },\r\n});\r\nRequest.setup = function setup(options) {\r\n if (options.type && !options.method) {\r\n Object.assign(options, { method: options.type });\r\n }\r\n Object.assign(globals, options);\r\n};\r\nfunction serializeQuery(params, prefix) {\r\n var key = Object.keys(params);\r\n for (var i = 0; i < key.length; i++) {\r\n var value = params[key[i]];\r\n if (params.constructor === Array)\r\n key[i] += prefix + \"[]\";\r\n else if (params.constructor === Object)\r\n key[i] = (prefix ? prefix + \"[\" + key[i] + \"]\" : key[i]);\r\n\r\n if (typeof value === 'object')\r\n key[i] = serializeQuery(value, key[i]);\r\n else\r\n key[i] = key[i] + \"=\" + encodeURIComponent(value);\r\n }\r\n return key.join('&');\r\n}\r\n$.ajax = sf.ajax = Request;","return sf;\r\n\r\n// ===== Module End =====\r\n})));","sf.router = new function(){\r\n\tvar self = this;\r\n\tself.loading = false;\r\n\tself.enabled = false;\r\n\tself.pauseRenderOnTransition = false;\r\n\tself.currentPage = [];\r\n\tvar initialized = false;\r\n\tvar lazyRouting = false;\r\n\tvar currentRouterURL = '';\r\n\r\n\t// Should be called if not using lazy page load\r\n\tself.init = function(targetNode){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.init();\r\n\t\t\t});\r\n\r\n\t\t// Run 'before' event for new page view\r\n\t\tvar temp = $('[sf-controller], [sf-page]', targetNode);\r\n\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\tif(temp[i].hasAttribute('sf-controller') === true)\r\n\t\t\t\tsf.controller.run(temp[i].getAttribute('sf-controller'));\r\n\t\t\t\r\n\t\t\tif(temp[i].getAttribute('sf-page')){\r\n\t\t\t\tvar name = temp[i].getAttribute('sf-page');\r\n\t\t\t\tbeforeEvent(name);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tinitialized = true;\r\n\t\tcurrentRouterURL = window.location.pathname;\r\n\t}\r\n\r\n\tfunction popstateListener(event) {\r\n\t\t// Don't continue if the last routing was error\r\n\t\tif(routingError){\r\n\t\t\troutingError = false;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\troutingBack = true;\r\n\t\tself.goto(window.location.pathname);\r\n\t}\r\n\r\n\tself.enable = function(status){\r\n\t\tif(status === void 0) status = true;\r\n\t\tif(self.enabled === status) return;\r\n\t\tself.enabled = status;\r\n\r\n\t\tif(status === true){\r\n\t\t\t// Create listener for link click\r\n\t\t\t$.on(document.body, 'click', 'a[href]', self.load);\r\n\r\n\t\t\t// Create listener when navigate backward\r\n\t\t\twindow.addEventListener('popstate', popstateListener, false);\r\n\t\t}\r\n\t\telse{\r\n\t\t\t$.off(document.body, 'click', 'a[href]', self.load);\r\n\t\t\twindow.removeEventListener('popstate', popstateListener, false);\r\n\t\t}\r\n\t}\r\n\r\n\tvar before = {};\r\n\t// Set index with number if you want to replace old function\r\n\tself.before = function(name, func, index){\r\n\t\tif(!before[name])\r\n\t\t\tbefore[name] = [];\r\n\r\n\t\tif(index === void 0){\r\n\t\t\tif(before[name].indexOf(func) === -1)\r\n\t\t\t\tbefore[name].push(func);\r\n\t\t}\r\n\t\telse\r\n\t\t\tbefore[name][index] = func;\r\n\t}\r\n\r\n\tvar after = {};\r\n\t// Set index with number if you want to replace old function\r\n\tself.after = function(name, func, index){\r\n\t\tif(!after[name])\r\n\t\t\tafter[name] = [];\r\n\r\n\t\tif(index === void 0){\r\n\t\t\tif(after[name].indexOf(func) === -1)\r\n\t\t\t\tafter[name].push(func);\r\n\t\t}\r\n\t\telse\r\n\t\t\tafter[name][index] = func;\r\n\t}\r\n\r\n\t// Running 'before' new page going to be displayed\r\n\tvar beforeEvent = function(name){\r\n\t\tif(self.currentPage.indexOf(name) === -1)\r\n\t\t\tself.currentPage.push(name);\r\n\r\n\t\tif(before[name]){\r\n\t\t\tfor (var i = 0; i < before[name].length; i++) {\r\n\t\t\t\tbefore[name][i](sf.model);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Running 'after' old page going to be removed\r\n\tvar afterEvent = function(name){\r\n\t\tif(self.currentPage.indexOf(name) === -1)\r\n\t\t\tself.currentPage.splice(self.currentPage.indexOf(name), 1);\r\n\r\n\t\tif(after[name]){\r\n\t\t\tfor (var i = 0; i < after[name].length; i++) {\r\n\t\t\t\tafter[name][i](sf.model);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tvar onEvent = {\r\n\t\t'loading':[],\r\n\t\t'loaded':[],\r\n\t\t'special':[],\r\n\t\t'error':[]\r\n\t};\r\n\tself.on = function(event, func){\r\n\t\tif(onEvent[event].indexOf(func) === -1)\r\n\t\t\tonEvent[event].push(func);\r\n\t}\r\n\r\n\tself.lazyViewPoint = {};\r\n\t/*\r\n\t\t{\r\n\t\t\toldURlPattern:{\r\n\t\t\t\tnewURLPattern:'.viewPoint'\r\n\t\t\t}\r\n\t\t}\r\n\t*/\r\n\r\n\tself.load = function(ev){\r\n\t\tif(self.enabled !== true) return;\r\n\r\n\t\tvar elem = ev.target;\r\n\t\tif(!elem.href) return;\r\n\r\n\t\tif(!history.pushState || elem.hasAttribute('sf-router-ignore'))\r\n\t\t\treturn;\r\n\r\n\t\t// Make sure it's from current origin\r\n\t\tvar path = elem.href.replace(window.location.origin, '');\r\n\t\tif(path.indexOf('//') !== -1)\r\n\t\t\treturn;\r\n\r\n\t\tev.preventDefault()\r\n\t\treturn !self.goto(path);\r\n\t}\r\n\r\n\tvar RouterLoading = false;\r\n\tvar routingBack = false;\r\n\tvar routingError = false;\r\n\tself.goto = function(path, data, method){\r\n\t\tif(!method) method = 'GET';\r\n else method = method.toUpperCase();\r\n\r\n\t\tif(!data) data = {};\r\n\r\n\t\tfor (var i = 0; i < onEvent['loading'].length; i++) {\r\n\t\t\tif(onEvent['loading'][i](path)) return;\r\n\t\t}\r\n\t\tvar oldPath = window.location.pathname;\r\n\t\tinitialized = false;\r\n\r\n\t\tif(RouterLoading) RouterLoading.abort();\r\n\t\tRouterLoading = $.ajax({\r\n\t\t\turl:window.location.origin + path,\r\n\t\t\tmethod:method,\r\n data:Object.assign(data, {\r\n _scarlets:'.dynamic.'\r\n }),\r\n\t\t\tsuccess:function(data){\r\n\t\t\t\tif(initialized) return;\r\n\t\t\t\tlazyRouting = true;\r\n\r\n\t\t\t\t// Run 'loaded' event\r\n\t\t\t\tRouterLoading = false;\r\n\r\n\t\t\t\t// Find special data\r\n\t\t\t\tvar regex = RegExp('', 'gm');\r\n\t\t\t\tvar special = regex.exec(data);\r\n\t\t\t\tif(special && special.length !== 1){\r\n\t\t\t\t\tspecial = special[1].split('--|&>').join('-->');\r\n\t\t\t\t\tspecial = JSON.parse(special);\r\n\r\n\t\t\t\t\tif(!isEmptyObject(special)){\r\n\t\t\t\t\t\tfor (var i = 0; i < onEvent['special'].length; i++) {\r\n\t\t\t\t\t\t\tif(onEvent['special'][i](special)) return;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar DOMReference = false;\r\n\t\t\t\tvar foundAction = function(ref){\r\n\t\t\t\t\tDOMReference = $.findOne(ref);\r\n\r\n\t\t\t\t\t// Run 'after' event for old page view\r\n\t\t\t\t\tvar last = $.findOne('[sf-page]', DOMReference);\r\n\t\t\t\t\tafterEvent(last ? last.getAttribute('sf-page') : '/');\r\n\r\n\t\t\t\t\t// Redefine title if exist\r\n\t\t\t\t\tif(special && special.title)\r\n\t\t\t\t\t\t$('head > title').innerHTML = special.title;\r\n\r\n\t\t\t\t\tfound = true;\r\n\t\t\t\t};\r\n\r\n\t\t\t\tvar found = false;\r\n\t\t\t\tfor(var oldURL in self.lazyViewPoint){\r\n\t\t\t\t\tif(currentRouterURL.indexOf(oldURL) !== -1){\r\n\t\t\t\t\t\tfor(var newURL in self.lazyViewPoint[oldURL]){\r\n\t\t\t\t\t\t\tif(currentRouterURL.indexOf(oldURL) !== -1){\r\n\t\t\t\t\t\t\t\tfoundAction(self.lazyViewPoint[oldURL][newURL]);\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif(found) break;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// When the view point was not found\r\n\t\t\t\tif(!found){\r\n\t\t\t\t\t// Use fallback if exist\r\n\t\t\t\t\tif(sf.router.lazyViewPoint[\"@default\"])\r\n\t\t\t\t\t\tfoundAction(sf.router.lazyViewPoint[\"@default\"]);\r\n\r\n\t\t\t\t\tif(!found){\r\n\t\t\t\t\t\tfor (var i = 0; i < onEvent['error'].length; i++) {\r\n\t\t\t\t\t\t\tonEvent['error'][i]('sf.router.lazyViewPoint[\"'+oldURL+'\"][\"'+newURL+'\"] was not found');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Run 'before' event for new page view\r\n\t\t\t\tif(!DOMReference) DOMReference = document.body;\r\n\t\t\t\tif(self.pauseRenderOnTransition)\r\n\t\t\t\t\tself.pauseRenderOnTransition.css('display', 'none');\r\n\r\n\t\t\t\t// Let page script running first, then update the data binding\r\n\t\t\t\tDOMReference.innerHTML = data;\r\n\r\n\t\t\t\t// Parse the DOM data binding\r\n\t\t\t\tsf.model.init(DOMReference);\r\n\r\n\t\t\t\t// Init template to model binding\r\n\t\t\t\tvar temp = $('[sf-page]', DOMReference);\r\n\t\t\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\t\t\tbeforeEvent(temp[i].getAttribute('sf-page'));\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(self.pauseRenderOnTransition)\r\n\t\t\t\t\tself.pauseRenderOnTransition.css('display', '');\r\n\r\n\t\t\t\trouterLoaded(currentRouterURL, path, DOMReference);\r\n\r\n\t\t\t\tinitialized = true;\r\n\t\t\t\tlazyRouting = false;\r\n\r\n\t\t\t\tcurrentRouterURL = path;\r\n\t\t\t\troutingError = false;\r\n\t\t\t},\r\n\t\t\terror:function(xhr, data){\r\n\t\t\t\troutingError = true;\r\n\t\t\t\tif(xhr.aborted) return;\r\n\r\n\t\t\t\tRouterLoading = false;\r\n\t\t\t\tfor (var i = 0; i < onEvent['error'].length; i++) {\r\n\t\t\t\t\tonEvent['error'][i](xhr.status, data);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Back on error\r\n\t\t\t\twindow.history.back();\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif(!routingBack)\r\n\t\t\twindow.history.pushState(null, \"\", path);\r\n\r\n\t\troutingBack = false;\r\n\t\treturn true;\r\n\t}\r\n\r\n\t// Trigger loaded event\r\n\tfunction routerLoaded(currentRouterURL, path, data){\r\n\t\tfor (var i = 0; i < onEvent['loaded'].length; i++) {\r\n\t\t\tonEvent['loaded'][i](currentRouterURL, path, data);\r\n\t\t}\r\n\t}\r\n};","sf.internal.virtual_scroll = new function(){\r\n\tvar self = this;\r\n\tvar styleInitialized = false;\r\n\tvar scrollingByScript = false;\r\n\r\n\t// before and after\r\n\tself.prepareCount = 4; // 4, 8, 12, 16, ...\r\n\r\n\tself.handle = function(list, targetNode, parentNode){\r\n\t\tif(!styleInitialized){\r\n\t\t\tinitStyles();\r\n\t\t\tstyleInitialized = true;\r\n\t\t}\r\n\r\n\t\tvar dynamicList = false;\r\n\t\tvar virtual = list.$virtual;\r\n\t\tvirtual.reset = function(reinitOnly){\r\n\t\t\tvirtual.DOMCursor = 0; // cursor of first element in DOM tree as a cursor\r\n\r\n\t\t\tvirtual.bounding.ceiling = -1;\r\n\t\t\tvirtual.bounding.floor = 0;\r\n\r\n\t\t\tvirtual.vCursor.ceiling = null; // for forward direction\r\n\t\t\tvirtual.vCursor.floor = virtual.dom.firstElementChild; // for backward direction\r\n\r\n\t\t\tvirtual.bounding.initial = virtual.dCursor.ceiling.offsetTop;\r\n\t\t\trefreshScrollBounding(0, virtual.bounding, list, parentNode);\r\n\t\t}\r\n\r\n\t\tvirtual.reinitCursor = function(){\r\n\t\t\tvirtual.vCursor.ceiling = virtual.dom.children[virtual.DOMCursor - 1] || null;\r\n\t\t\tvirtual.vCursor.floor = virtual.dom.children[virtual.DOMCursor] || null;\r\n\t\t}\r\n\r\n\t\tvirtual.reinitScroll = function(){\r\n\t\t\trefreshScrollBounding(virtual.DOMCursor, virtual.bounding, list, parentNode);\r\n\t\t}\r\n\r\n\t\tvirtual.elements = function(){\r\n\t\t\treturn obtainElements(list, parentNode);\r\n\t\t}\r\n\r\n\t\tvirtual.dCursor = { // DOM Cursor\r\n\t\t\tceiling:parentNode.querySelector('.virtual-spacer.ceiling'),\r\n\t\t\tfloor:parentNode.querySelector('.virtual-spacer.floor')\r\n\t\t};\r\n\r\n\t\tvirtual.bounding = {};\r\n\t\tvirtual.vCursor = {};\r\n\r\n\t\tvirtual.reset();\r\n\t\tvirtual.targetNode = parentNode;\r\n\t\tvirtual.scrollHeight = virtual.dCursor.floor.offsetTop - virtual.bounding.initial;\r\n\r\n\t\tvar scroller = parentNode;\r\n\t\tvirtual.destroy = function(){\r\n\t\t\t$.off(scroller, 'scroll');\r\n\t\t\t$.off(parentNode, 'mousedown mouseup');\r\n\t\t\tvirtual.dom.innerHTML = '';\r\n\t\t\toffElementResize(parentNode);\r\n\r\n\t\t\tdelete list.$virtual;\r\n\t\t}\r\n\r\n\t\tvirtual.resetViewport = function(){\r\n\t\t\tvirtual.visibleLength = Math.floor(scroller.clientHeight / virtual.scrollHeight);\r\n\t\t\tvirtual.preparedLength = virtual.visibleLength + self.prepareCount * 2;\r\n\r\n\t\t\tif(virtual.preparedLength < 18)\r\n\t\t\t\tvirtual.preparedLength = 18;\r\n\t\t}\r\n\r\n\t\tsetTimeout(function(){\r\n\t\t\tscroller = parentNode;\r\n\r\n\t\t\tvar length = parentNode.getAttribute('scroll-parent-index') || 0;\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\tscroller = scroller.parentElement;\r\n\t\t\t}\r\n\r\n\t\t\tvirtual.resetViewport();\r\n\r\n\t\t\tif(parentNode.classList.contains('sf-list-dynamic')){\r\n\t\t\t\tdynamicList = true;\r\n\t\t\t\tdynamicHeight(list, targetNode, parentNode, scroller);\r\n\t\t\t}\r\n\t\t\telse staticHeight(list, targetNode, parentNode, scroller);\r\n\t\t}, 500);\r\n\t}\r\n\r\n\t// Recommended for a list that have different element height\r\n\tfunction dynamicHeight(list, targetNode, parentNode, scroller){\r\n\t\tvar virtual = list.$virtual;\r\n\t\tvar ceiling = virtual.dCursor.ceiling;\r\n\t\tvar floor = virtual.dCursor.floor;\r\n\t\tvar vCursor = virtual.vCursor;\r\n\t\tvCursor.floor = virtual.dom.firstElementChild;\r\n\t\t\r\n\t\tvirtual.scrollTo = function(index){\r\n\t\t\tscrollTo(index, list, self.prepareCount, parentNode, scroller);\r\n\r\n\t\t\t// Reset virtual spacer height\r\n\t\t\tceilingHeight = 0;\r\n\t\t\tfloorHeight = 0;\r\n\t\t\tceiling.style.height = ceilingHeight+'px';\r\n\t\t\tfloor.style.height = floorHeight+'px';\r\n\t\t}\r\n\r\n\t\tvirtual.refresh = function(force){\r\n\t\t\trefresh(force, list, self.prepareCount, parentNode, scroller);\r\n\t\t\tfillViewport();\r\n\t\t}\r\n\r\n\t\t// Insert some element until reach visible height\r\n\t\tfillViewport();\r\n\r\n\t\tvirtual.visibleLength = parentNode.childElementCount - 2;\r\n\t\tvirtual.preparedLength = virtual.visibleLength + self.prepareCount * 2;\r\n\r\n\t\tfor (var i = 0; i < self.prepareCount; i++) {\r\n\t\t\tvar temp = vCursor.floor;\r\n\t\t\tif(temp === null) break;\r\n\r\n\t\t\tvCursor.floor = temp.nextElementSibling;\r\n\t\t\tfloor.insertAdjacentElement('beforeBegin', temp);\r\n\t\t}\r\n\t\tvirtual.DOMCursor = 0;\r\n\r\n\t\tvar ceilingHeight = 0;\r\n\t\tvar floorHeight = 0;\r\n\t\tfunction previousCeiling(){\r\n\t\t\tvar temp = null;\r\n\t\t\tvar resetCeiling = false;\r\n\r\n\t\t\t// Add some element on the ceiling\r\n\t\t\tfor (var i = 0; i < self.prepareCount; i++) {\r\n\t\t\t\tif(vCursor.floor === null)\r\n\t\t\t\t\ttemp = virtual.dom.lastElementChild;\r\n\t\t\t\telse\r\n\t\t\t\t\ttemp = vCursor.floor.previousElementSibling;\r\n\r\n\t\t\t\tif(temp === null) break;\r\n\t\t\t\tvCursor.ceiling = temp.previousElementSibling;\r\n\t\t\t\tvirtual.DOMCursor--;\r\n\r\n\t\t\t\tceiling.insertAdjacentElement('afterEnd', temp);\r\n\r\n\t\t\t\tif(ceilingHeight > 0)\r\n\t\t\t\t\tceilingHeight -= getAbsoluteHeight(temp);\r\n\r\n\t\t\t\tif(virtual.DOMCursor < self.prepareCount && !resetCeiling){\r\n\t\t\t\t\ti = 0;\r\n\t\t\t\t\tresetCeiling = true;\r\n\t\t\t\t\ttemp = null;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif(ceilingHeight < 0 || temp === null)\r\n\t\t\t\tceilingHeight = 0;\r\n\r\n\t\t\tvar length = parentNode.childElementCount - 2 - list.$virtual.preparedLength;\r\n\t\t\t// Remove some element on the floor\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\ttemp = floor.previousElementSibling;\r\n\t\t\t\tfloorHeight += getAbsoluteHeight(temp);\r\n\r\n\t\t\t\tif(vCursor.floor === null)\r\n\t\t\t\t\tvirtual.dom.insertAdjacentElement('beforeEnd', temp);\r\n\t\t\t\telse vCursor.floor.insertAdjacentElement('beforeBegin', temp);\r\n\r\n\t\t\t\tvCursor.floor = temp;\r\n\t\t\t}\r\n\r\n\t\t\tif(vCursor.floor === null)\r\n\t\t\t\tvCursor.ceiling = virtual.dom.lastElementChild;\r\n\t\t\telse \r\n\t\t\t\tvCursor.ceiling = vCursor.floor.previousElementSibling;\r\n\r\n\t\t\tceiling.style.height = ceilingHeight+'px';\r\n\t\t\tfloor.style.height = floorHeight+'px';\r\n\t\t}\r\n\r\n\t\tfunction fillViewport(){\r\n\t\t\t// Insert some element depend on prepared length\r\n\t\t\tvar length = virtual.preparedLength - (parentNode.childElementCount - 2);\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\tif(vCursor.ceiling === null)\r\n\t\t\t\t\ttemp = virtual.dom.firstElementChild;\r\n\t\t\t\telse\r\n\t\t\t\t\ttemp = vCursor.ceiling.nextElementSibling;\r\n\r\n\t\t\t\tif(temp === null) break;\r\n\t\t\t\tvCursor.floor = temp.nextElementSibling;\r\n\r\n\t\t\t\tfloor.insertAdjacentElement('beforeBegin', temp);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction nextFloor(){\r\n\t\t\tvar temp = null;\r\n\t\t\tfillViewport();\r\n\r\n\t\t\tif(vCursor.floor !== null){\r\n\t\t\t\tif(vCursor.ceiling === null)\r\n\t\t\t\t\tvCursor.ceiling = vCursor.floor.previousElementSibling;\r\n\r\n\t\t\t\t// Add extra element based on prepare count\r\n\t\t\t\tfor (var i = 0; i < self.prepareCount; i++) {\r\n\t\t\t\t\ttemp = vCursor.floor;\r\n\t\t\t\t\tif(temp === null) break;\r\n\r\n\t\t\t\t\tvCursor.floor = temp.nextElementSibling;\r\n\t\t\t\t\tfloor.insertAdjacentElement('beforeBegin', temp);\r\n\r\n\t\t\t\t\tif(floorHeight > 0)\r\n\t\t\t\t\t\tfloorHeight -= getAbsoluteHeight(temp);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif(floorHeight < 0 || temp === null)\r\n\t\t\t\tfloorHeight = 0;\r\n\r\n\t\t\t// Remove some element on the ceiling\r\n\t\t\tvar length = parentNode.childElementCount - 2 - list.$virtual.preparedLength;\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\ttemp = ceiling.nextElementSibling;\r\n\t\t\t\tceilingHeight += getAbsoluteHeight(temp);\r\n\t\t\t\tvirtual.DOMCursor++;\r\n\r\n\t\t\t\tif(vCursor.ceiling === null)\r\n\t\t\t\t\tvirtual.dom.insertAdjacentElement('afterBegin', temp);\r\n\t\t\t\telse vCursor.ceiling.insertAdjacentElement('afterEnd', temp);\r\n\r\n\t\t\t\tvCursor.ceiling = temp;\r\n\t\t\t}\r\n\r\n\t\t\tif(vCursor.ceiling === null)\r\n\t\t\t\tvCursor.floor = virtual.dom.firstElementChild;\r\n\t\t\telse \r\n\t\t\t\tvCursor.floor = vCursor.ceiling.nextElementSibling;\r\n\r\n\t\t\tceiling.style.height = ceilingHeight+'px';\r\n\t\t\tfloor.style.height = floorHeight+'px';\r\n\t\t}\r\n\r\n\t\tvar bounding = virtual.bounding;\r\n\t\trefreshScrollBounding(0, bounding, list, parentNode);\r\n\r\n\t\tif(virtual.callback_ !== void 0){\r\n\t\t\tvar callback_ = virtual.callback_;\r\n\t\t\tdelete virtual.callback_;\r\n\t\t}\r\n\r\n\t\tvar updating = false;\r\n\t\tfunction checkCursorPosition(){\r\n\t\t\tif(updating || scrollingByScript) return;\r\n\t\t\tupdating = true;\r\n\r\n\t\t\tif(scroller.scrollTop < bounding.ceiling){\r\n\t\t\t\t// console.log('back', bounding, scroller.scrollTop, virtual.DOMCursor);\r\n\t\t\t\tpreviousCeiling();\r\n\t\t\t\trefreshScrollBounding(virtual.DOMCursor, bounding, list, parentNode);\r\n\t\t\t\t// console.warn('back', bounding, scroller.scrollTop, virtual.DOMCursor);\r\n\t\t\t}\r\n\r\n\t\t\telse if(scroller.scrollTop > bounding.floor){\r\n\t\t\t\t// console.log('front', bounding, scroller.scrollTop, virtual.DOMCursor);\r\n\t\t\t\tnextFloor();\r\n\t\t\t\trefreshScrollBounding(virtual.DOMCursor, bounding, list, parentNode);\r\n\t\t\t\t// console.warn('front', bounding, scroller.scrollTop, virtual.DOMCursor);\r\n\t\t\t}\r\n\r\n\t\t\tif(virtual.callback !== void 0 && list.length !== 0){\r\n\t\t\t\tif(virtual.callback.hitFloor && virtual.vCursor.floor === null &&\r\n\t\t\t\t\tscroller.scrollTop + scroller.clientHeight === scroller.scrollHeight\r\n\t\t\t\t){\r\n\t\t\t\t\tvirtual.callback.hitFloor(virtual.DOMCursor);\r\n\t\t\t\t}\r\n\t\t\t\telse if(virtual.callback.hitCeiling && virtual.vCursor.ceiling === null && scroller.scrollTop === 0){\r\n\t\t\t\t\tvirtual.callback.hitCeiling(virtual.DOMCursor);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if(callback_ && callback_.ref[callback_.var]){\r\n\t\t\t\tvirtual.callback = callback_.ref[callback_.var];\r\n\t\t\t\tcallback_ = null;\r\n\t\t\t}\r\n\r\n\t\t\tupdating = false;\r\n\t\t}\r\n\r\n\t\t$.on(scroller, 'scroll', checkCursorPosition);\r\n\t\tonElementResize(parentNode, function(){\r\n\t\t\trefreshScrollBounding(virtual.DOMCursor, bounding, list, parentNode);\r\n\t\t});\r\n\t}\r\n\r\n\t// Recommended for a list that have similar element height\r\n\tfunction staticHeight(list, targetNode, parentNode, scroller){\r\n\t\tvar virtual = list.$virtual;\r\n\t\tvar ceiling = virtual.dCursor.ceiling;\r\n\t\tvar floor = virtual.dCursor.floor;\r\n\r\n\t\t// Insert visible element to dom tree\r\n\t\tvar insertCount = virtual.preparedLength <= list.length ? virtual.preparedLength : list.length;\r\n\t\tfor (var i = 0; i < insertCount; i++) {\r\n\t\t\tif(virtual.dom.firstElementChild === null)\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tfloor.insertAdjacentElement('beforeBegin', virtual.dom.firstElementChild);\r\n\t\t}\r\n\r\n\t\tvirtual.refreshVirtualSpacer = refreshVirtualSpacer;\r\n\r\n\t\tfunction refreshVirtualSpacer(cursor){\r\n\t\t\tif(cursor >= self.prepareCount){\r\n\t\t\t\tceiling.style.height = (cursor - self.prepareCount) * virtual.scrollHeight + 'px';\r\n\t\t\t\tfloor.style.height = (list.length - virtual.preparedLength - cursor) * virtual.scrollHeight + 'px';\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\tceiling.style.height = cursor * virtual.scrollHeight + 'px'; //'0px';\r\n\t\t\t\tvar count = (list.length - virtual.preparedLength);\r\n\t\t\t\tfloor.style.height = (count || 0) * virtual.scrollHeight + 'px';\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tvar bounding = virtual.bounding;\r\n\r\n\t\trefreshVirtualSpacer(0);\r\n\t\trefreshScrollBounding(self.prepareCount, bounding, list, parentNode);\r\n\t\tbounding.ceiling = -1;\r\n\r\n\t\tvirtual.offsetTo = function(index){\r\n\t\t\treturn index * virtual.scrollHeight + ceiling.offsetTop;\r\n\t\t}\r\n\r\n\t\tvar vCursor = virtual.vCursor;\r\n\t\tvCursor.floor = virtual.dom.firstElementChild;\r\n\t\tvirtual.scrollTo = function(index){\r\n\t\t\tscrollTo(index, list, self.prepareCount, parentNode, scroller);\r\n\t\t}\r\n\r\n\t\tvirtual.refresh = function(force){\r\n\t\t\trefresh(force, list, self.prepareCount, parentNode, scroller, checkCursorPosition, refreshVirtualSpacer);\r\n\t\t}\r\n\r\n\t\tif(virtual.callback_ !== void 0){\r\n\t\t\tvar callback_ = virtual.callback_;\r\n\t\t\tdelete virtual.callback_;\r\n\t\t}\r\n\r\n\t\tvar updating = false;\r\n\t\tvar fromCeiling = true;\r\n\t\tvar scrollFocused = false;\r\n\t\tfunction checkCursorPosition(){\r\n\t\t\tif(updating || scrollingByScript || scroller.scrollTop >= bounding.ceiling && scroller.scrollTop <= bounding.floor){\r\n\t\t\t\t// Fix chrome scroll anchoring bugs when scrolling at corner\r\n\t\t\t\tif(scrollFocused){\r\n\t\t\t\t\tif(scroller.scrollTop === 0 || scroller.scrollTop === scroller.scrollHeight - scroller.clientHeight){\r\n\t\t\t\t\t\tremoveUserScrollFocus(scroller);\r\n\t\t\t\t\t\tscrollFocused = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tvar cursor = Math.floor(scroller.scrollTop / virtual.scrollHeight);\r\n\t\t\tif(cursor + virtual.preparedLength > list.length)\r\n\t\t\t\tcursor = list.length - virtual.preparedLength;\r\n\r\n\t\t\tif(fromCeiling){\r\n\t\t\t\tif(cursor < self.prepareCount*2)\r\n\t\t\t\t\tcursor -= self.prepareCount;\r\n\r\n\t\t\t\t// Fix chrome scroll anchoring bugs\r\n\t\t\t\tif(scrollFocused){\r\n\t\t\t\t\tremoveUserScrollFocus(scroller);\r\n\t\t\t\t\tscrollFocused = false;\r\n\t\t\t\t}\r\n\t\t\t\tfromCeiling = false;\r\n\t\t\t}\r\n\r\n\t\t\tif(cursor < self.prepareCount){\r\n\t\t\t\tcursor = 0;\r\n\t\t\t\tfromCeiling = true;\r\n\t\t\t}\r\n\r\n\t\t\tupdating = true;\r\n\r\n\t\t\tvar changes = cursor - virtual.DOMCursor;\r\n\t\t\tif(cursor + changes >= list.length)\r\n\t\t\t\tchanges = cursor + changes - list.length;\r\n\r\n\t\t\tif(changes === 0){ // This should be fixed to improve performance and future bugs\r\n\t\t\t\t//console.warn(\"No changes (The scroll bounding is not correct)\");\r\n\t\t\t\tupdating = false;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tvirtual.DOMCursor = cursor;\r\n\r\n\t\t\t// console.log(cursor, changes, bounding.ceiling, bounding.floor, scroller.scrollTop);\r\n\t\t\tmoveElementCursor(changes, list);\r\n\t\t\trefreshVirtualSpacer(cursor);\r\n\t\t\trefreshScrollBounding(cursor, bounding, list, parentNode);\r\n\t\t\t// console.log('a', bounding.ceiling, bounding.floor, scroller.scrollTop);\r\n\r\n\t\t\tif(virtual.callback !== void 0 && list.length !== 0){\r\n\t\t\t\tif(virtual.callback.hitFloor && virtual.vCursor.floor === null){\r\n\t\t\t\t\tvirtual.callback.hitFloor(cursor);\r\n\t\t\t\t}\r\n\t\t\t\telse if(virtual.callback.hitCeiling && virtual.vCursor.ceiling === null){\r\n\t\t\t\t\tvirtual.callback.hitCeiling(cursor);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if(callback_ && callback_.ref[callback_.var]){\r\n\t\t\t\tvirtual.callback = callback_.ref[callback_.var];\r\n\t\t\t\tcallback_ = null;\r\n\t\t\t}\r\n\r\n\t\t\tupdating = false;\r\n\t\t}\r\n\r\n\t\t$.on(scroller, 'scroll', checkCursorPosition);\r\n\r\n\t\t// For preventing scroll jump if scrolling over than viewport\r\n\t\tif(scroller === parentNode && navigator.userAgent.indexOf('Chrom') !== -1){\r\n\t\t\t$.on(parentNode, 'mousedown', function(){\r\n\t\t\t\tscrollFocused = true;\r\n\t\t\t});\r\n\t\t\t$.on(parentNode, 'mouseup', function(){\r\n\t\t\t\tscrollFocused = false;\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tfunction refreshScrollBounding(cursor, bounding, list, parentNode){\r\n\t\tvar temp = Math.floor(self.prepareCount / 2); // half of element preparation\r\n\t\tif(cursor < self.prepareCount){\r\n\t\t\tbounding.ceiling = -1;\r\n\t\t\tbounding.floor = parentNode.children[self.prepareCount * 2 + 1];\r\n\r\n\t\t\tif(bounding.floor !== void 0)\r\n\t\t\t\tbounding.floor = bounding.floor.offsetTop;\r\n\t\t\telse bounding.floor = parentNode.lastElementChild.offsetTop + 1000;\r\n\r\n\t\t\tbounding.floor -= bounding.initial;\r\n\t\t\treturn;\r\n\t\t}\r\n\t\telse if(parentNode.children[temp + 1] !== void 0)\r\n\t\t\t\tbounding.ceiling = parentNode.children[temp + 1].offsetTop; // -2 element\r\n\r\n\t\tif(list.$virtual.preparedLength !== void 0 && cursor >= list.length - list.$virtual.preparedLength)\r\n\t\t\tbounding.floor = list.$virtual.dCursor.floor.offsetTop + list.$virtual.scrollHeight*2;\r\n\t\telse{\r\n\t\t\tbounding.floor = parentNode.children[self.prepareCount + 3].offsetTop; // +2 element\r\n\r\n\t\t\tif(parentNode.hasAttribute('scroll-reduce-floor')){\r\n\t\t\t\tbounding.floor -= parentNode.getAttribute('scroll-reduce-floor');\r\n\t\t\t\tbounding.ceiling -= parentNode.getAttribute('scroll-reduce-floor');\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tbounding.ceiling -= bounding.initial;\r\n\t\tbounding.floor -= bounding.initial;// scrollHeight - clientHeight\r\n\t}\r\n\r\n\tfunction moveElementCursor(changes, list){\r\n\t\tvar vDOM = list.$virtual.dom;\r\n\t\tvar vCursor = list.$virtual.vCursor;\r\n\t\tvar dCursor = list.$virtual.dCursor;\r\n\r\n\t\tif(changes > 0){ // forward\r\n\t\t\tvar ref = 0;\r\n\r\n\t\t\t// Select from virtual ceiling cursor to Dom tree\r\n\t\t\tfor (var i = 0; i < changes; i++) { // vDom -> Dom tree\r\n\t\t\t\tif(vCursor.ceiling === null)\r\n\t\t\t\t\tref = vDOM.firstElementChild;\r\n\r\n\t\t\t\telse ref = vCursor.ceiling.nextElementSibling;\r\n\t\t\t\tif(ref === null) break;\r\n\t\t\t\tdCursor.floor.insertAdjacentElement('beforeBegin', ref);\r\n\t\t\t}\r\n\r\n\t\t\t// Move element on the ceiling to vDom\r\n\t\t\tfor (var i = changes; i > 0; i--) { // Dom tree -> vDom\r\n\t\t\t\tif(vCursor.ceiling === null){\r\n\t\t\t\t\tvCursor.ceiling = dCursor.ceiling.nextElementSibling;\r\n\t\t\t\t\tvDOM.insertAdjacentElement('afterBegin', vCursor.ceiling);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tref = dCursor.ceiling.nextElementSibling;\r\n\t\t\t\t\tvCursor.ceiling.insertAdjacentElement('afterEnd', ref);\r\n\t\t\t\t\tvCursor.ceiling = ref;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tvCursor.floor = vCursor.ceiling.nextElementSibling;\r\n\t\t}\r\n\t\telse if(changes < 0){ // backward\r\n\t\t\tvar ref = 0;\r\n\t\t\tchanges = -changes;\r\n\r\n\t\t\t// Select from virtual floor cursor to Dom tree\r\n\t\t\tfor (var i = 0; i < changes; i++) { // vDom -> Dom tree\r\n\t\t\t\tif(vCursor.floor === null)\r\n\t\t\t\t\tref = vDOM.lastElementChild;\r\n\r\n\t\t\t\telse ref = vCursor.floor.previousElementSibling;\r\n\t\t\t\tif(ref === null) break;\r\n\t\t\t\tdCursor.ceiling.insertAdjacentElement('afterEnd', ref);\r\n\t\t\t}\r\n\r\n\t\t\t// Move element on the floor to vDom\r\n\t\t\tfor (var i = 0; i < changes; i++) { // Dom tree -> vDom\r\n\t\t\t\tif(vCursor.floor === null){\r\n\t\t\t\t\tvCursor.floor = dCursor.floor.previousElementSibling;\r\n\t\t\t\t\tvDOM.insertAdjacentElement('beforeEnd', vCursor.floor);\r\n\t\t\t\t}\r\n\r\n\t\t\t\telse{\r\n\t\t\t\t\tref = dCursor.floor.previousElementSibling;\r\n\t\t\t\t\tvCursor.floor.insertAdjacentElement('beforeBegin', ref);\r\n\t\t\t\t\tvCursor.floor = ref;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tvCursor.ceiling = vCursor.floor.previousElementSibling;\r\n\t\t}\r\n\t}\r\n\r\n\tfunction scrollTo(index, list, prepareCount, parentNode, scroller){\r\n\t\tvar virtual = list.$virtual;\r\n\t\tvar reduce = 0;\r\n\r\n\t\tif(index >= list.length - virtual.preparedLength){\r\n\t\t\treduce -= prepareCount;\r\n\t\t\tindex = list.length - virtual.preparedLength;\r\n\t\t}\r\n\r\n\t\tif(index - virtual.DOMCursor === 0 || index >= list.length) return;\r\n\r\n\t\tscrollingByScript = true;\r\n\r\n\t\t// Already on DOM tree\r\n\t\tif((virtual.DOMCursor === 0 && index < prepareCount + prepareCount/2) ||\r\n\t\t\t(virtual.DOMCursor + prepareCount/2 > index\r\n\t\t\t&& virtual.DOMCursor + prepareCount < index))\r\n\t\t\tscroller.scrollTop = parentNode.children[index - virtual.DOMCursor + 1].offsetTop;\r\n\r\n\t\t// Move cursor\r\n\t\telse {\r\n\t\t\tvar temp = null;\r\n\t\t\tvar ceiling = virtual.dCursor.ceiling;\r\n\t\t\tvar floor = virtual.dCursor.floor;\r\n\t\t\tvar vCursor = virtual.vCursor;\r\n\r\n\t\t\t// DOM tree to virtual DOM\r\n\t\t\tvar length = parentNode.childElementCount - 2;\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\ttemp = ceiling.nextElementSibling;\r\n\r\n\t\t\t\tif(vCursor.floor === null){\r\n\t\t\t\t\tvirtual.dom.insertAdjacentElement('beforeEnd', temp);\r\n\r\n\t\t\t\t\tif(i === length-1)\r\n\t\t\t\t\t\tvCursor.floor = temp;\r\n\t\t\t\t}\r\n\t\t\t\telse vCursor.floor.insertAdjacentElement('beforeBegin', temp);\r\n\t\t\t}\r\n\r\n\t\t\tif(index >= prepareCount){\r\n\t\t\t\tif(index < list.length - virtual.preparedLength)\r\n\t\t\t\t\tindex -= prepareCount;\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\treduce = prepareCount - index;\r\n\t\t\t\tvirtual.DOMCursor = index = 0;\r\n\t\t\t}\r\n\r\n\t\t\tvar insertCount = virtual.preparedLength <= list.length ? virtual.preparedLength : list.length;\r\n\r\n\t\t\t// Virtual DOM to DOM tree\r\n\t\t\tfor (var i = 0; i < insertCount; i++) {\r\n\t\t\t\ttemp = virtual.dom.children[index];\r\n\t\t\t\tif(temp === void 0) break;\r\n\r\n\t\t\t\tfloor.insertAdjacentElement('beforeBegin', temp);\r\n\t\t\t}\r\n\t\t\tvirtual.DOMCursor = index;\r\n\r\n\t\t\tvCursor.floor = virtual.dom.children[index] || null;\r\n\t\t\tvCursor.ceiling = vCursor.floor ? vCursor.floor.previousElementSibling : null;\r\n\r\n\t\t\tif(list.$virtual.refreshVirtualSpacer)\r\n\t\t\t\tlist.$virtual.refreshVirtualSpacer(index);\r\n\r\n\t\t\trefreshScrollBounding(index, virtual.bounding, list, parentNode);\r\n\r\n\t\t\ttemp = parentNode.children[prepareCount - reduce + 1];\r\n\t\r\n\t\t\tif(temp !== void 0)\r\n\t\t\t\tscroller.scrollTop = temp.offsetTop - scroller.offsetTop;\r\n\t\t}\r\n\r\n\t\tscrollingByScript = false;\r\n\t}\r\n\r\n\tfunction removeUserScrollFocus(parentNode){\r\n\t\tparentNode.style.overflow = 'hidden';\r\n\t\tsetTimeout(function(){\r\n\t\t\tparentNode.style.overflow = '';\r\n\t\t}, 50);\r\n\t}\r\n\r\n\tfunction getAbsoluteHeight(el){\r\n\t var styles = window.getComputedStyle(el);\r\n\t var margin = parseInt(styles['marginTop']) + parseInt(styles['marginBottom']);\r\n\t return el.offsetHeight + margin || 0;\r\n\t}\r\n\r\n\tfunction obtainElements(list, parentNode){\r\n\t\tvar exist = [];\r\n\t\tvar temp = void 0;\r\n\r\n\t\tvar length = list.$virtual.DOMCursor;\r\n\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\ttemp = list.$virtual.dom.children[i];\r\n\t\t\tif(temp === void 0) break;\r\n\t\t\texist.push(temp);\r\n\t\t}\r\n\r\n\t\tlength = parentNode.childElementCount - 2;\r\n\t\tfor (var i = 1; i <= length; i++) {\r\n\t\t\ttemp = parentNode.children[i];\r\n\t\t\tif(temp === void 0) break;\r\n\t\t\texist.push(temp);\r\n\t\t}\r\n\t\t\r\n\t\t// Get elements length\r\n\t\tvar elementLength = list.$virtual.dom.childElementCount + length;\r\n\r\n\t\tlength = elementLength - length - list.$virtual.DOMCursor;\r\n\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\ttemp = list.$virtual.dom.children[list.$virtual.DOMCursor + i];\r\n\t\t\tif(temp === void 0) break;\r\n\t\t\texist.push(temp);\r\n\t\t}\r\n\r\n\t\treturn exist;\r\n\t}\r\n\r\n\tfunction refresh(force, list, prepareCount, parentNode, scroller, checkCursorPosition, refreshVirtualSpacer){\r\n\t\tvar cursor = list.$virtual.DOMCursor;\r\n\t\tvar additionalScroll = 0;\r\n\r\n\t\t// Find nearest cursor for current view position\r\n\t\tif(force){\r\n\t\t\tvar i = -1;\r\n\t\t\tvar length = list.$virtual.preparedLength;\r\n\r\n\t\t\tdo{\r\n\t\t\t\ti++;\r\n\t\t\t} while(i < length && parentNode.children[i].offsetTop < scroller.scrollTop);\r\n\r\n\t\t\tcursor = cursor + i;\r\n\t\t\tif(cursor > 0) cursor -= 1;\r\n\r\n\t\t\tadditionalScroll = scroller.scrollTop - parentNode.children[i].offsetTop;\r\n\t\t}\r\n\r\n\t\t// Force move cursor if element in the DOM tree was overloaded\r\n\t\tif(force || parentNode.childElementCount - 2 > list.$virtual.preparedLength){\r\n\t\t\tlist.$virtual.DOMCursor = list.length;\r\n\t\t\tvar moveTo = cursor;\r\n\t\t\tif(!force)\r\n\t\t\t\tmoveTo = cursor <= prepareCount ? cursor : (cursor + prepareCount);\r\n\r\n\t\t\tscrollTo(moveTo,\r\n\t\t\t\tlist,\r\n\t\t\t\tprepareCount,\r\n\t\t\t\tparentNode,\r\n\t\t\t\tscroller\r\n\t\t\t);\r\n\r\n\t\t\tscroller.scrollTop += additionalScroll;\r\n\t\t}\r\n\r\n\t\tif(refreshVirtualSpacer)\r\n\t\t\trefreshVirtualSpacer(cursor);\r\n\r\n\t\tif(checkCursorPosition)\r\n\t\t\tcheckCursorPosition();\r\n\r\n\t\trefreshScrollBounding(cursor, list.$virtual.bounding, list, parentNode);\r\n\t}\r\n\r\n\tvar _onElementResize = [];\r\n\tvar _onElementResize_timer = -1;\r\n\tfunction onElementResize(parentNode, callback){\r\n\t\tif(_onElementResize_timer === -1){\r\n\t\t\t_onElementResize_timer = setInterval(function(){\r\n\t\t\t\tvar temp = null;\r\n\t\t\t\tfor (var i = _onElementResize.length - 1; i >= 0; i--) {\r\n\t\t\t\t\ttemp = _onElementResize[i];\r\n\r\n\t\t\t\t\t// Check resize\r\n\t\t\t\t\tif(temp.element.scrollHeight === temp.height\r\n\t\t\t\t\t\t|| temp.element.scrollWidth === temp.width)\r\n\t\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\t\t// Check if it's removed from DOM\r\n\t\t\t\t\tif(temp.element.parentElement === null){\r\n\t\t\t\t\t\t_onElementResize.splice(i, 1);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\ttemp.callback();\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(_onElementResize.length === 0){\r\n\t\t\t\t\tclearInterval(_onElementResize_timer);\r\n\t\t\t\t\t_onElementResize_timer = -1;\r\n\t\t\t\t}\r\n\t\t\t}, 1000);\r\n\t\t}\r\n\r\n\t\t_onElementResize.push({\r\n\t\t\telement:parentNode,\r\n\t\t\tcallback:callback,\r\n\t\t\theight:parentNode.scrollHeight,\r\n\t\t\twidth:parentNode.scrollWidth\r\n\t\t});\r\n\t}\r\n\r\n\tfunction offElementResize(parentNode){\r\n\t\tfor (var i = _onElementResize.length - 1; i >= 0; i--) {\r\n\t\t\tif(_onElementResize[i].element === parentNode)\r\n\t\t\t\t_onElementResize.splice(i, 1);\r\n\t\t}\r\n\r\n\t\t// Interval will be cleared when the array is empty\r\n\t}\r\n\r\n\tfunction initStyles(){\r\n\t\tvar style = document.getElementById('sf-styles');\r\n\r\n\t\tif(!style){\r\n\t\t\tstyle = document.createElement('style');\r\n\t\t\tstyle.id = 'sf-styles';\r\n \tdocument.head.appendChild(style);\r\n\t\t}\r\n\r\n\t\tstyle.sheet.insertRule(\r\n\t\t'.sf-virtual-list .virtual-spacer{'+\r\n 'visibility: hidden;'+\r\n 'position: relative;'+\r\n 'height: 1px;'+\r\n 'transform-origin: 0 0;'+\r\n 'width: 1px;'+\r\n 'margin: 0;'+\r\n 'padding: 0;'+\r\n 'background: none;'+\r\n 'border: none;'+\r\n 'box-shadow: none;'+\r\n '}', style.sheet.cssRules.length);\r\n\t}\r\n};"]} \ No newline at end of file +{"version":3,"sources":["sf-a_init.js","sf-a_polyfill.js","sf-dom.js","sf-loader.js","sf-component.js","sf-model.js","sf-controller.js","sf-e-ajax.js","sf-z_end.js","sf-router.js","sf-virtual_scroll.js"],"names":["global","factory","exports","module","sf","window","this","document","internal","arguments","constructor","Function","loader","onFinish","apply","regex","getQuotes","validFunctionCall","strictVar","escapeHTML","uniqueDataParser","dataParser","allowedFunctionEval","avoidQuotes","str","func","temp","es","replace","full","push","length","i","isEmptyObject","obj","key","compareObject","obj1","obj2","hiddenProperty","property","value","Object","defineProperty","enumerable","configurable","deepProperty","path","capitalizeLetters","name","toUpperCase","slice","join","assign","target","varArgs","TypeError","to","index","nextSource","nextKey","prototype","hasOwnProperty","call","writable","Element","remove","CharacterData","DocumentType","forEach","item","parentNode","removeChild","matches","matchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","webkitMatchesSelector","s","ownerDocument","querySelectorAll","NodeList","callback","thisArg","location","origin","protocol","hostname","port","values","res","setPrototypeOf","proto","__proto__","Reflect","construct","Parent","args","Class","a","instance","bind","_setPrototypeOf","dom","selector","context","parseElement","String","$","self","findOne","querySelector","parent","element","closest","parentElement","prevAll","isNext","result","findNodes","nextSibling","previousSibling","nextAll","on","event","once","tempCallback","ev","addEventListener","capture","sf$eventListener","off","events","split","ref","removeEventListener","splice","animateCSS","animationName","duration","animationEnd","animation","OAnimation","MozAnimation","WebkitAnimation","t","style","webkitAnimationDuration","animationDuration","list","classList","add","setTimeout","emptyDOM","div","createElement","ul","tbody","tr","table","select","html","returnNode","tempDOM","indexOf","textContent","insertAdjacentHTML","escapeText","text","innerHTML","elements","documentElement","domReady","body","haveSymbol","getSelector","childIndexes","untilElement","names","id","test","unshift","tagName","e","array","substr","childNodes","loadedContent","totalContent","DOMWasLoaded","DOMReady","turnedOff","whenDOMReady","whenDOMLoaded","whenProgress","onProgress","f","css","rel","href","head","appendChild","js","type","async","src","console","warn","isQueued","domLoadEvent","model","queuePreprocess","domStateEvent","readyState","error","resourceWaitTimer","setInterval","waitResources","clearInterval","listener","controller","init","router","component","scope","registered","available","bases","for","extend","pending","defineComponent","base","outerHTML","triggerEvent","componentInit","newID","from","setAttribute","sf$component","sf$componentFrom","new","isCreated","retriggered","newElement","cloneNode","newObj","root","Array","n","firstElementChild","destroy","DOMNodeRemoved","HTMLElement","customElements","HTMLElement_wrap","Wrapper","getPrototypeOf","create","eval","define","err","root_","run","bindingEnabled","processingElement","trimIndentation","indent","trim","RegExp","bracketMatch","chackValidFunctionCall","localEval","script","_model_","_modelScope","_content_","tempScript","preventExecution","check_","exec","log","_result_","_evaled_","escapeEscapedQuote","unescapeEscapedQuote","elseIfHandle","else_","scopes","elseIf","elseValue","currentElement","previousElementSibling","getAttribute","modelName","$virtual","DOMCursor","modelKeys","modelRef","keys","templateParser_regex","REF_DIRECT","REF_IF","REF_EXEC","templateExec","parse","atIndex","parsed","data","if","templateParser","template","original","$item","addresses","changesReference","pendingInsert","current","address","nodeType","refA","direct","match","cRef","dynamicFlag","parse_index","startFlag","attributes","refB","isValueInput","attribute","removeAttribute","sf$elementReferences","tDOM","insertBefore","syntheticCache","sf$cache","cache","modelRef_array","syntheticTemplate","changes","modelReference","newData","checkRelatedChanges","parseIndex","found","haveChanges","ref_","sf$haveChilds","sf$childRoot","reverse","currentDOM","notExist","isEqualNode","replaceChild","mask","runEval","preParsedReference","scopeMask","itemMask","preParsed","lastParsedIndex","prepared","actual","temp_","matched","exist","charCodeAt","take","passVar","currentIndex","strDeclare","firstTime","JSON","stringify","check","VarPass_","VarPass","s1","obtained","val","findElse","pop","shift","condition","bindArray","propertyName","targetNode","editProperty","refreshTimer","parentChilds","children","isKeyed","contains","eventVar","processElement","options","other","count","vEndRange","preparedLength","spacer","lastElementChild","height","reset","clearTimeout","reinitScroll","overflow","vDOM","theParent","update","index_a","other_sibling","other_parent","oldChild","referenceNode","vCursor","floor","insertAdjacentElement","currentRemoved","startRemove","refreshVirtualSpacer","propertyProxy","subject","lastLength","reinitCursor","o","resetViewport","matchLeft","refresh","real","limit","callback_","var","virtual_scroll","handle","needle","elRef","getElement","process","content","parentNode_","elem","hardRefresh","softRefresh","virtualChilds","childElement","childElementCount","loopParser","method","items","extractPreprocess","sf$bindedKey","initBindingInformation","get","set","callInputListener","v2m","newValue1","newValue2","old","inputBoundRunning","inputTextBound","fromSFFramework","viewInputted","typeData","Number","newValue","sfModel","sfBounded","inputFilesBound","files","inputCheckBoxBound","checked","Boolean","inputSelectBound","multiple","selectedOptions","assignElementData","arrayValue","selected","checkbox","inputBoundRun","Event","dispatchEvent","triggerInputEvent","elementBoundChanges","oneWay","toLowerCase","modelToViewBinding","bindInput","modelScope","alreadyInitialized","queued","parsePreprocess","ceiling","after","nextElementSibling","before","hasAttribute","removeModelBinding","modelFrom","components","everyRemovedNodes","nodes","MutationObserver","observe","everyRecords","record","removedNodes","records","childList","subtree","bindedKey","getOwnPropertyDescriptor","elementBind","input","objValue","getAssigner","m2v","out","newValue3","dcBracket","bindElement","onChanges","properties","copy","addressed","addressAttributes","currentNode","attrs","indexes","addressStart","commentFlag","flag","createComment","textNode","createTextNode","search","extract","sort","b","checkList","full_","match_","findModelProperty","asArray","enclosedHTMLParse","excludes","extracting","nodeName","enclosing","enclosed","nodeValue","modelElement","attr","active","bindedList","parentEl","bindedListIndex","listenSFClick","script_","method_","preventDefault","globals","jsonpRequests","Request","requestOptions","globalsNoCallbacks","callbackName","defaults","url","toString","user","password","headers","xhrFields","statusCode","processData","dataType","contentType","timeout","fireCallback","globalCallbackValue","optionCallbackValue","_i","paramsPrefix","stringData","serializeQuery","abortTimeout_1","callbackName_1","Date","now","callbackSplit","requestUrl","addVars","filter","el","script_1","onerror","xhr","XMLHttpRequest","requestParameters","open","xhrTimeout","postData","ArrayBuffer","Blob","Document","FormData","boundary","setRequestHeader","headerName","crossDomain","$2","host","onload","status","responseData","parseError","responseText","responseType","response","onabort","abort","send","RequestShortcut","_a","success","params","prefix","encodeURIComponent","concat","post","json","getJSON","postJSON","setup","ajax","loading","enabled","pauseRenderOnTransition","currentPage","initialized","currentRouterURL","popstateListener","routingError","routingBack","goto","pathname","beforeEvent","enable","load","onEvent","loaded","special","lazyViewPoint","history","pushState","RouterLoading","_scarlets","DOMReference","foundAction","last","afterEvent","title","oldURL","newURL","routerLoaded","aborted","back","styleInitialized","scrollingByScript","refreshScrollBounding","cursor","bounding","Math","prepareCount","offsetTop","initial","dCursor","scrollHeight","scrollTo","scroller","virtual","reduce","scrollTop","insertCount","removeUserScrollFocus","getAbsoluteHeight","styles","getComputedStyle","margin","parseInt","offsetHeight","force","checkCursorPosition","additionalScroll","moveTo","getElementById","sheet","insertRule","cssRules","initStyles","reinitOnly","elementLength","obtainElements","_onElementResize","offElementResize","visibleLength","clientHeight","ceilingHeight","floorHeight","fillViewport","updating","resetCeiling","previousCeiling","nextFloor","hitFloor","hitCeiling","_onElementResize_timer","scrollWidth","width","onElementResize","dynamicHeight","offsetTo","fromCeiling","scrollFocused","moveElementCursor","navigator","userAgent","staticHeight"],"mappings":"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","file":"scarletsframe.min.js","sourcesContent":["(function(global, factory){\r\n if(typeof exports === 'object' && typeof module !== 'void 0') module.exports = factory(global);\r\n else global.sf = factory(global);\r\n}(typeof window !== \"void 0\" ? window : this, (function(window){'use strict';\r\nif(typeof document === void 0)\r\n\tdocument = window.document;\r\n// ===== Module Init =====\r\nvar internal = {};\r\n\r\nvar sf = function(){\r\n\tif(arguments[0].constructor === Function){\r\n\t\treturn sf.loader.onFinish.apply(null, arguments);\r\n\t}\r\n};\r\n\r\nsf.internal = {};\r\nsf.regex = {\r\n\tgetQuotes:/(['\"])[\\s\\S]*?[^\\\\]\\1/g,\r\n\tvalidFunctionCall:/[a-zA-Z0-9 \\]\\$\\)]/,\r\n\tstrictVar:'(?=\\\\b[^.]|^|\\\\n| +|\\\\t|\\\\W )',\r\n\tescapeHTML:/(?!&#.*?;)[\\u00A0-\\u9999<>\\&]/gm,\r\n\r\n\tuniqueDataParser:/{{((@|#[\\w])[\\s\\S]*?)}}/g,\r\n\tdataParser:/{{([^@%][\\s\\S]*?)}}/g,\r\n};\r\n\r\nvar allowedFunctionEval = [':', 'for', 'if', 'while', '_content_.take', 'console.log'];\r\n\r\nfunction avoidQuotes(str, func){\r\n\tvar temp = [];\r\n\tvar es = '<%$@>';\r\n\tstr = str.replace(sf.regex.getQuotes, function(full){\r\n\t\ttemp.push(full);\r\n\t\treturn es+(temp.length-1)+es;\r\n\t});\r\n\tstr = func(str);\r\n\tfor (var i = 0; i < temp.length; i++) {\r\n\t\tstr = str.replace(es+i+es, temp[i]);\r\n\t}\r\n\treturn str;\r\n}\r\n\r\nfunction isEmptyObject(obj){\r\n\tfor(var key in obj){\r\n\t\treturn false;\r\n\t}\r\n\treturn true\r\n}\r\n\r\nfunction compareObject(obj1, obj2){\r\n\tif(!obj1 || !obj2)\r\n\t\treturn false;\r\n\r\n\tfor(var i in obj1){\r\n\t\tif(typeof obj1[i] !== 'object' && obj1[i] !== obj2[i])\r\n\t\t\treturn false;\r\n\t}\r\n\treturn true;\r\n}\r\n\r\nfunction hiddenProperty(obj, property, value){\r\n\tObject.defineProperty(obj, property, {\r\n\t\tenumerable: false,\r\n\t\tconfigurable: true,\r\n\t\tvalue: value\r\n\t});\r\n}\r\n\r\nfunction deepProperty(obj, path){\r\n for(var i = 0; i < path.length; i++){\r\n obj = obj[path[i]];\r\n if(obj === void 0) return obj;\r\n }\r\n return obj;\r\n}\r\n\r\nfunction capitalizeLetters(name){\r\n\tfor (var i = 0; i < name.length; i++) {\r\n\t\tname[i] = name[i][0].toUpperCase() + name[i].slice(1);\r\n\t}\r\n\treturn name.join('');\r\n}","// ==== ES5 Polyfill ====\r\nif(typeof Object.assign != 'function'){\r\n Object.defineProperty(Object, \"assign\", {\r\n value: function assign(target, varArgs) {\r\n 'use strict';\r\n if (target == null)\r\n throw new TypeError('Cannot convert void 0 or null to object');\r\n var to = Object(target);\r\n for (var index = 1; index < arguments.length; index++) {\r\n var nextSource = arguments[index];\r\n if (nextSource != null) {\r\n for (var nextKey in nextSource) {\r\n if (Object.prototype.hasOwnProperty.call(nextSource, nextKey))\r\n to[nextKey] = nextSource[nextKey];\r\n }\r\n }\r\n }\r\n return to;\r\n },\r\n writable: true,\r\n configurable: true\r\n });\r\n}\r\n\r\nif(Element.prototype.remove === void 0 || CharacterData.prototype.remove === void 0 || DocumentType.prototype.remove === void 0){\r\n (function (arr) {\r\n arr.forEach(function (item) {\r\n if (item.hasOwnProperty('remove')) {\r\n return;\r\n }\r\n Object.defineProperty(item, 'remove', {\r\n configurable: true,\r\n enumerable: true,\r\n writable: true,\r\n value: function remove() {\r\n if (this.parentNode !== null)\r\n this.parentNode.removeChild(this);\r\n }\r\n });\r\n });\r\n })([Element.prototype, CharacterData.prototype, DocumentType.prototype]);\r\n}\r\n\r\nif(!Element.prototype.matches){\r\n Element.prototype.matches = (Element.prototype).matchesSelector ||\r\n (Element.prototype).mozMatchesSelector || (Element.prototype).msMatchesSelector ||\r\n (Element.prototype).oMatchesSelector || (Element.prototype).webkitMatchesSelector ||\r\n function (s) {\r\n var matches = (this.document || this.ownerDocument).querySelectorAll(s),\r\n i = matches.length;\r\n while (--i >= 0 && matches.item(i) !== this){}\r\n return i > -1;\r\n };\r\n}\r\n\r\nif(!NodeList.prototype.forEach){\r\n NodeList.prototype.forEach = function (callback, thisArg) {\r\n thisArg = thisArg || window;\r\n for (var i = 0; i < this.length; i++) {\r\n callback.call(thisArg, this[i], i, this);\r\n }\r\n };\r\n}\r\n\r\nif(!window.location.origin)\r\n window.location.origin = window.location.protocol + \"//\" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');\r\n\r\nif(!Object.values)\r\n Object.values = function(obj){\r\n var res = [];\r\n for (var i in obj) {\r\n if (obj.hasOwnProperty(i)) {\r\n res.push(obj[i]);\r\n }\r\n }\r\n return res;\r\n }\r\n\r\nif(Object.setPrototypeOf === void 0)\r\n Object.setPrototypeOf = function(obj, proto) {\r\n obj.__proto__ = proto;\r\n return obj; \r\n }\r\n\r\nif(typeof Reflect === 'undefined'){\r\n Reflect = {};\r\n Reflect.construct = function(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; };\r\n}","sf.dom = function(selector, context){\r\n\tif(selector[0] === '<') return sf.dom.parseElement(selector);\r\n\tif(selector.constructor !== String) return selector;\r\n\r\n\tif(context) return context.querySelectorAll(selector);\r\n\treturn document.querySelectorAll(selector);\r\n}\r\n\r\nvar $ = sf.dom; // Shortcut\r\n\r\n;(function(){\r\n\tvar self = sf.dom;\r\n\r\n\tself.findOne = function(selector, context){\r\n\t\tif(context !== void 0) return context.querySelector(selector);\r\n\t\treturn document.querySelector(selector);\r\n\t}\r\n\r\n\tself.parent = function(element, selector){\r\n\t\tif(element.closest) return element.closest(selector);\r\n\r\n\t\tdo {\r\n\t\t\tif(element.matches(selector) === true)\r\n\t\t\t\treturn element;\r\n\r\n\t\t\telement = element.parentElement;\r\n\t\t} while (element !== null);\r\n\r\n\t\treturn null;\r\n\t}\r\n\r\n\tself.prevAll = function(element, selector, isNext){\r\n\t\tvar result = [];\r\n\t\tvar findNodes = selector === null || selector.constructor !== String ? true : false;\r\n\r\n\t\t// Skip current element\r\n\t\telement = isNext ? element.nextSibling : element.previousSibling;\r\n\t\twhile (element !== null) {\r\n\t\t\tif(findNodes === false && element.matches(selector) === true)\r\n\t\t\t\tresult.push(element);\r\n\t\t\telse{\r\n\t\t\t\tif(element === selector)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tresult.push(element);\r\n\t\t\t}\r\n\r\n\t\t\tif(isNext)\r\n\t\t\t\telement = element.nextSibling;\r\n\t\t\telse\r\n\t\t\t\telement = element.previousSibling;\r\n\t\t}\r\n\r\n\t\treturn result;\r\n\t}\r\n\r\n\t// Shorcut\r\n\tself.nextAll = function(element, selector){\r\n\t\treturn self.prevAll(element, selector, true);\r\n\t}\r\n\r\n\t/**\r\n\t * Listen to an event\r\n\t * @param Node \t\t\telement \tparent element\r\n\t * @param string \t\t\tevent \tevent name\r\n\t * @param function|string selector callback function or selector\r\n\t * @param function\t\t\tcallback callback function\r\n\t * @param boolean\t\t\tonce \tcall once\r\n\t * @return null\r\n\t */\r\n\tself.on = function(element, event, selector, callback, once){\r\n\t\tif(typeof element === 'string'){\r\n\t\t\telement = document;\r\n\t\t\tcallback = selector;\r\n\t\t\tselector = event;\r\n\t\t\tevent = element;\r\n\t\t}\r\n\r\n\t\tif(typeof selector === 'function'){\r\n\t\t\tcallback = selector;\r\n\t\t\tselector = null;\r\n\t\t}\r\n\r\n\t\tif(selector){\r\n\t\t\tvar tempCallback = callback;\r\n\t\t\tcallback = function(ev){\r\n\t\t\t\tif(self.parent(ev.target, selector) !== null)\r\n\t\t\t\t\ttempCallback(ev);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tcallback.selector = selector;\r\n\t\tcallback.once = once;\r\n\t\telement.addEventListener(event, callback, {capture:true, once:once === true});\r\n\r\n\t\t// Save event listener\r\n\t\tif(element.sf$eventListener === void 0)\r\n\t\t\telement.sf$eventListener = {};\r\n\r\n\t\tif(element.sf$eventListener[event] === void 0)\r\n\t\t\telement.sf$eventListener[event] = [];\r\n\r\n\t\telement.sf$eventListener[event].push(callback);\r\n\t}\r\n\r\n\t// Shorcut\r\n\tself.once = function(element, event, selector, callback){\r\n\t\tself.on(element, event, selector, callback, true);\r\n\t}\r\n\r\n\t/**\r\n\t * Remove event listener\r\n\t * @param Node \telement \tparent element\r\n\t * @param string \tevent \tevent name\r\n\t * @param string \tselector selector\r\n\t * @return null\r\n\t */\r\n\tself.off = function(element, event, selector){\r\n\t\t// Remove all event\r\n\t\tif(event === void 0){\r\n\t\t\tif(element.sf$eventListener === void 0)\r\n\t\t\t\treturn;\r\n\r\n\t\t\tvar events = element.sf$eventListener[event];\r\n\t\t\tfor (var i = 0; i < events.length; i++) {\r\n\t\t\t\tself.off(element, events[i]);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar events = event.split(' ');\r\n\t\tif(events.length !== 1){\r\n\t\t\tfor (var i = 0; i < events.length; i++) {\r\n\t\t\t\tself.off(element, events[i]);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Remove listener\r\n\t\tif(element.sf$eventListener === void 0)\r\n\t\t\treturn;\r\n\r\n\t\tvar ref = element.sf$eventListener;\r\n\t\tif(ref !== void 0 && ref[event] !== void 0){\r\n\t\t\tfor (var i = ref[event].length - 1; i >= 0; i--) {\r\n\t\t\t\tif(selector && ref[event][i].selector !== selector)\r\n\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\telement.removeEventListener(event, ref[event].splice(i, 1), true);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tself.animateCSS = function(element, animationName, callback, duration) {\r\n\t\tvar animationEnd = {\r\n\t\t\tanimation: 'animationend',\r\n\t\t\tOAnimation: 'oAnimationEnd',\r\n\t\t\tMozAnimation: 'mozAnimationEnd',\r\n\t\t\tWebkitAnimation: 'webkitAnimationEnd',\r\n\t\t};\r\n\r\n\t\tfor (var t in animationEnd){\r\n\t\t\tif(element.style[t] !== void 0){\r\n\t\t\t\tanimationEnd = animationEnd[t];\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif(duration){\r\n\t\t\telement.style.webkitAnimationDuration = duration+'s';\r\n\t\t\telement.style.animationDuration = duration+'s';\r\n\t\t}\r\n\r\n\t\tvar list = ('animated ' + animationName).split(' ');\r\n\t\telement.classList.add.apply(element.classList, list);\r\n\t\t$.once(element, animationEnd, function(){\r\n\t\t\telement.classList.remove.apply(element.classList, list);\r\n\t\t\t\r\n\t\t\tif(duration) setTimeout(function(){\r\n\t\t\t\telement.style.webkitAnimationDuration = duration+'s';\r\n\t\t\t\telement.style.animationDuration = duration+'s';\r\n\t\t\t}, 1);\r\n\r\n\t\t\tif(typeof callback === 'function') callback();\r\n\t\t});\r\n\t}\r\n\r\n\tvar emptyDOM = {\r\n\t\tdiv:document.createElement('div'),\r\n\t\tul:document.createElement('ul'),\r\n\t\ttbody:document.createElement('tbody'),\r\n\t\ttr:document.createElement('tr'),\r\n\t\ttable:document.createElement('table'),\r\n\t\tselect:document.createElement('select'),\r\n\t};\r\n\tself.parseElement = function(html, returnNode){\r\n\t\tvar result = [];\r\n\t\tvar tempDOM = emptyDOM.div;\r\n\r\n if(html.indexOf('?,./ ]/;\r\n\tself.getSelector = function(element, childIndexes, untilElement){\r\n\t\tvar names = [];\r\n\t\tif(untilElement === void 0) untilElement = documentElement;\r\n\r\n\t\tvar previousSibling = childIndexes ? 'previousSibling' : 'previousElementSibling';\r\n\r\n\t\twhile(element.parentNode !== null){\r\n\t\t\tif(element.id && !haveSymbol.test(element.id)){\r\n\t\t\t\tnames.unshift('#'+element.id);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\tif(element === untilElement){\r\n\t\t\t\t\tif(childIndexes === void 0)\r\n\t\t\t\t\t\tnames.unshift(element.tagName);\r\n\t\t\t\t\telse names.unshift(0);\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tvar e = element;\r\n\t\t\t\t\tvar i = childIndexes ? 0 : 1;\r\n\r\n\t\t\t\t\twhile(e[previousSibling]){\r\n\t\t\t\t\t\te = e[previousSibling];\r\n\t\t\t\t\t\ti++;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif(childIndexes)\r\n\t\t\t\t\t\tnames.unshift(i);\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tnames.unshift(\":nth-child(\"+i+\")\");\r\n\t\t\t\t}\r\n\r\n\t\t\t\telement = element.parentNode;\r\n\t\t\t\tif(element === null)\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif(childIndexes)\r\n\t\t\treturn names;\r\n\t\treturn names.join(\" > \");\r\n\t}\r\n\r\n\tself.childIndexes = function(array, context){\r\n\t\tvar element = context || documentElement;\r\n\t\tvar i = 1;\r\n\r\n\t\tif(array[0].constructor === String && element.id !== array[0].substr(1))\r\n\t\t\telement = element.querySelector(array[0]);\r\n\r\n\t\telse if(array.length === 1)\r\n\t\t\treturn element;\r\n\r\n\t\tfor (i = i; i < array.length; i++) {\r\n\t\t\telement = element.childNodes.item(array[i]);\r\n\r\n\t\t\tif(element === null)\r\n\t\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\treturn element;\r\n\t}\r\n\r\n})();","sf.loader = new function(){\r\n\tvar self = this;\r\n\tself.loadedContent = 0;\r\n\tself.totalContent = 0;\r\n\tself.DOMWasLoaded = false;\r\n\tself.DOMReady = false;\r\n\tself.turnedOff = true;\r\n\r\n\tvar whenDOMReady = [];\r\n\tvar whenDOMLoaded = [];\r\n\tvar whenProgress = [];\r\n\r\n\tself.off = function(){\r\n\t\tself.turnedOff = true;\r\n\t}\r\n\r\n\t// Make event listener\r\n\tself.onFinish = function(func){\r\n\t\tif(self.DOMWasLoaded) return func();\r\n\t\tif(whenDOMLoaded.indexOf(func) !== -1) return;\r\n\t\twhenDOMLoaded.push(func);\r\n\t}\r\n\tself.domReady = function(func){\r\n\t\tif(self.DOMReady) return func();\r\n\t\tif(whenDOMReady.indexOf(func) !== -1) return;\r\n\t\twhenDOMReady.push(func);\r\n\t}\r\n\tself.onProgress = function(func){\r\n\t\tif(self.DOMWasLoaded) return func(self.loadedContent, self.totalContent);\r\n\t\tif(whenProgress.indexOf(func) !== -1) return;\r\n\t\twhenProgress.push(func);\r\n\t}\r\n\r\n\tself.f = function(element){\r\n\t\tself.loadedContent++;\r\n\t\tfor (var i = 0; i < whenProgress.length; i++) {\r\n\t\t\twhenProgress[i](self.loadedContent, self.totalContent);\r\n\t\t}\r\n\t}\r\n\r\n\tself.css = function(list){\r\n\t\tif(self.DOMWasLoaded){\r\n\t\t\t// check if some list was loaded\r\n\t\t\tfor (var i = list.length - 1; i >= 0; i--) {\r\n\t\t\t\tif($('link[href*=\"'+list[i]+'\"]').length !== 0)\r\n\t\t\t\t\tlist.splice(i, 1);\r\n\t\t\t}\r\n\t\t\tif(list.length === 0) return;\r\n\t\t}\r\n\t\tself.turnedOff = false;\r\n\r\n\t\tself.totalContent = self.totalContent + list.length;\r\n\t\tfor(var i = 0; i < list.length; i++){\r\n\t\t\tvar s = document.createElement('link');\r\n\t s.rel = 'stylesheet';\r\n\t s.href = list[i];\r\n\t s.addEventListener('load', sf.loader.f, {once:true});\r\n\t s.addEventListener('error', sf.loader.f, {once:true});\r\n\t document.head.appendChild(s);\r\n\t\t}\r\n\t}\r\n\r\n\tself.js = function(list){\r\n\t\tif(self.DOMWasLoaded){\r\n\t\t\t// check if some list was loaded\r\n\t\t\tfor (var i = list.length - 1; i >= 0; i--) {\r\n\t\t\t\tif($('script[src*=\"'+list[i]+'\"]').length !== 0)\r\n\t\t\t\t\tlist.splice(i, 1);\r\n\t\t\t}\r\n\t\t\tif(list.length === 0) return;\r\n\t\t}\r\n\t\tself.turnedOff = false;\r\n\r\n\t\tself.totalContent = self.totalContent + list.length;\r\n\t\tfor(var i = 0; i < list.length; i++){\r\n\t\t\tvar s = document.createElement('script');\r\n\t s.type = \"text/javascript\";\r\n\t s.async = true;\r\n\t s.src = list[i];\r\n\t s.addEventListener('load', sf.loader.f, {once:true});\r\n\t s.addEventListener('error', sf.loader.f, {once:true});\r\n\t document.head.appendChild(s);\r\n\t\t}\r\n\t}\r\n\r\n\tsetTimeout(function(){\r\n\t\tif(self.totalContent === 0 && !self.turnedOff){\r\n\t\t\tself.loadedContent = self.totalContent = 1;\r\n\t\t\tconsole.warn(\"If you don't use content loader feature, please turn it off with `sf.loader.off()`\");\r\n\t\t}\r\n\t}, 10000);\r\n\r\n\r\n\tvar isQueued = false;\r\n\tvar lastState = '';\r\n\tdocument.addEventListener(\"load\", function domLoadEvent(event){\r\n\t\t// Add processing class to queued element\r\n\t\tif(isQueued === false && document.body){\r\n\t\t\tdocument.removeEventListener('load', domLoadEvent, true);\r\n\r\n\t\t\tisQueued = sf.model.queuePreprocess(document.body);\r\n\r\n\t\t\tfor (var i = 0; i < isQueued.length; i++) {\r\n\t\t\t\tisQueued[i].classList.add('sf-dom-queued');\r\n\t\t\t}\r\n\r\n\t\t\tif(isQueued.length === 0) isQueued = false;\r\n\r\n\t\t\tif(lastState === 'loading'){\r\n\t\t\t\tvar repeatedList = $('[sf-repeat-this]', document.body);\r\n\t\t\t\tfor (var i = 0; i < repeatedList.length; i++) {\r\n\t\t\t\t\trepeatedList[i].classList.add('sf-dom-queued');\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Find images\r\n\t\t\t\tvar temp = $('img:not(onload)[src]');\r\n\t\t\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\t\t\tsf.loader.totalContent++;\r\n\t\t\t\t\ttemp[i].addEventListener('load', sf.loader.f, {once:true});\r\n\t\t\t\t\ttemp[i].addEventListener('error', sf.loader.f, {once:true});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}, true);\r\n\r\n\tdocument.addEventListener('readystatechange', function domStateEvent(){\r\n\t\tif(document.readyState === 'interactive' || document.readyState === 'complete'){\r\n\t\t\tif(self.DOMReady === false){\r\n\t\t\t\tself.DOMReady = true;\r\n\t\t\t\tfor (var i = 0; i < whenDOMReady.length; i++) {\r\n\t\t\t\t\ttry{\r\n\t\t\t\t\t\twhenDOMReady[i]();\r\n\t\t\t\t\t} catch(e) {\r\n\t\t\t\t\t\tconsole.error(e);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif(isQueued === false)\r\n\t\t\t\tisQueued = sf.model.queuePreprocess(document.body);\r\n\r\n\t\t\tresourceWaitTimer = setInterval(waitResources, 100);\r\n\t\t\tdocument.removeEventListener('readystatechange', domStateEvent, true);\r\n\t\t}\r\n\t}, true);\r\n\r\n\tvar resourceWaitTimer = -1;\r\n\tfunction waitResources(){\r\n\t\tif(self.turnedOff === false && self.loadedContent < self.totalContent)\r\n\t\t\treturn;\r\n\r\n\t\tclearInterval(resourceWaitTimer);\r\n\r\n\t\tvar listener = sf.dom('script, link, img');\r\n\t\tfor (var i = 0; i < listener.length; i++) {\r\n\t\t\tlistener[i].removeEventListener('error', sf.loader.f);\r\n\t\t\tlistener[i].removeEventListener('load', sf.loader.f);\r\n\t\t}\r\n\r\n\t\tself.DOMWasLoaded = true;\r\n\t\tfor (var i = 0; i < whenDOMLoaded.length; i++) {\r\n\t\t\ttry{\r\n\t\t\t\twhenDOMLoaded[i]();\r\n\t\t\t} catch(e){\r\n\t\t\t\tconsole.error(e);\r\n\t\t\t}\r\n\t\t}\r\n\t\twhenProgress.splice(0);\r\n\t\twhenDOMReady.splice(0);\r\n\t\twhenDOMLoaded.splice(0);\r\n\t\twhenDOMReady = whenDOMLoaded = null;\r\n\r\n\t\t// Last init\r\n\t\tsf.controller.init();\r\n\t\tsf.model.init(document.body, isQueued);\r\n\t\tsf.router.init();\r\n\r\n\t\tisQueued = null;\r\n\t}\r\n}\r\nsf.prototype.constructor = sf.loader.onFinish;","sf.component = new function(){\r\n\tvar self = this;\r\n\tvar scope = internal.component = {};\r\n\tself.registered = {};\r\n\tself.available = {};\r\n\r\n\tvar bases = {};\r\n\tvar events = {};\r\n\r\n\tself.for = function(name, func, extend){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.for(name, func);\r\n\t\t\t});\r\n\r\n\t\tif(self.registered[name] === void 0)\r\n\t\t\tself.registered[name] = [func, sf.controller.pending[name], 0, false, extend];\r\n\t\tself.registered[name][0] = func;\r\n\t\tdelete sf.controller.pending[name];\r\n\r\n\t\tdefineComponent(name);\r\n\t}\r\n\r\n\tself.event = function(name, func){\r\n\t\tevents[name] = func;\r\n\t}\r\n\r\n\tself.base = function(name, func){\r\n\t\tbases[name] = func;\r\n\t}\r\n\r\n\tself.html = function(name, outerHTML){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.html(name, outerHTML);\r\n\t\t\t});\r\n\r\n\t\tif(self.registered[name] === void 0)\r\n\t\t\tself.registered[name] = [false, false, 0, false];\r\n\r\n\t\tvar temp = $.parseElement(outerHTML);\r\n\t\tif(temp.length === 1){\r\n\t\t\tself.registered[name][3] = temp[0];\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar tempDOM = document.createElement('div');\r\n\t\ttempDOM.tempDOM = true;\r\n\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\ttempDOM.appendChild(temp[i]);\r\n\t\t}\r\n\t\tself.registered[name][3] = tempDOM;\r\n\t}\r\n\r\n\tscope.triggerEvent = function(name, event, obj){\r\n\t\tif(events[name] === void 0 || events[name][event] === void 0)\r\n\t\t\treturn;\r\n\r\n\t\tevents[name][event](obj, event);\r\n\t}\r\n\r\n\tvar tempDOM = document.createElement('div');\r\n\tself.new = function(name, element, isCreated, retriggered){\r\n\t\tif(isCreated === true){\r\n\t\t\tif(sf.loader.DOMWasLoaded === false)\r\n\t\t\t\treturn sf(function(){\r\n\t\t\t\t\tself.new(name, element, isCreated);\r\n\t\t\t\t});\r\n\t\t\tif(self.registered[name][3] === false)\r\n\t\t\t\treturn setTimeout(function(){\r\n\t\t\t\t\tself.new(name, element, isCreated, true);\r\n\t\t\t\t}, 0);\r\n\t\t}\r\n\r\n\t\tif(element === void 0)\r\n\t\t\treturn new window['$'+capitalizeLetters(name.split('-'))];\r\n\r\n\t\tvar newElement = element === void 0;\r\n\t\tif(element === void 0){\r\n\t\t\tif(self.registered[name][3] === false){\r\n\t\t\t\tconsole.error(\"HTML content for '\"+name+\"' was not defined\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\telement = self.registered[name][3].cloneNode(true);\r\n\t\t}\r\n\r\n\t\tvar newID = name+'@'+(self.registered[name][2]++);\r\n\r\n\t\tif(self.available[name] === void 0)\r\n\t\t\tself.available[name] = [];\r\n\r\n\t\tself.available[name].push(newID);\r\n\r\n\t\tvar newObj = sf.model.root[newID] = {};\r\n\t\tself.registered[name][0](newObj, sf.model);\r\n\r\n\t\tvar extend = self.registered[name][4];\r\n\t\tif(extend !== void 0){\r\n\t\t\tif(extend.constructor === Array){\r\n\t\t\t\tfor (var i = 0; i < extend.length; i++) {\r\n\t\t\t\t\tif(bases[extend[i]] === void 0)\r\n\t\t\t\t\t\treturn console.error(\"'\"+extend[i]+\"' base is not found\");\r\n\t\t\t\t\tbases[extend[i]](newObj, sf.model);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\tif(bases[extend] === void 0)\r\n\t\t\t\t\treturn console.error(\"'\"+extend+\"' base is not found\");\r\n\t\t\t\tbases[extend](newObj, sf.model);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif(self.registered[name][1])\r\n\t\t\tself.registered[name][1](newObj, sf.model);\r\n\r\n\t\tscope.triggerEvent(name, 'created', newObj);\r\n\r\n\t\tif(newElement !== true && isCreated !== true){\r\n\t\t\tcomponentInit(element, newID, name);\r\n\t\t\telement.model = sf.model.root[newID];\r\n\t\t\treturn newID;\r\n\t\t}\r\n\r\n\t\tvar temp = self.registered[name][3];\r\n\t\tif(temp.tempDOM === true){\r\n\t\t\ttemp = temp.cloneNode(true).childNodes;\r\n\t\t\tfor (var i = 0, n = temp.length; i < n; i++) {\r\n\t\t\t\telement.appendChild(temp[0]);\r\n\t\t\t}\r\n\t\t}\r\n\t\telse element.appendChild(temp.cloneNode(true));\r\n\r\n\t\tif(element.parentNode === null){\r\n\t\t\t// Wrap to temporary vDOM\r\n\t\t\ttempDOM.appendChild(element);\r\n\t\t\tcomponentInit(element, newID, name);\r\n\t\t\tsf.model.init(element);\r\n\t\t\telement = tempDOM.firstElementChild;\r\n\t\t\telement.remove();\r\n\t\t}\r\n\t\telse if(isCreated === true){\r\n\t\t\tcomponentInit(element, newID, name);\r\n\t\t\tsf.model.init(element);\r\n\t\t}\r\n\r\n\t\telement.model = sf.model.root[newID];\r\n\t\telement.destroy = function(){\r\n\t\t\tif(this.parentElement === null)\r\n\t\t\t\tinternal.model.DOMNodeRemoved(this);\r\n\t\t\telse this.remove();\r\n\t\t}\r\n\t\treturn element;\r\n\t}\r\n\r\n\tfunction componentInit(element, newID, from){\r\n\t\telement.setAttribute('sf-controller', '');\r\n\t\telement.sf$component = newID;\r\n\t\telement.sf$componentFrom = from;\r\n\t}\r\n\r\n\tvar HTMLElement = window.HTMLElement;\r\n\tvar customElements = window.customElements;\r\n\r\n\tvar HTMLElement_wrap = (function(Class){\r\n\t\tfunction Wrapper(){\r\n\t\t\treturn Reflect.construct(Class, arguments, Object.getPrototypeOf(this).constructor);\r\n\t\t}\r\n\t\tWrapper.prototype = Object.create(Class.prototype, {constructor:{value: Wrapper, enumerable: false, writable: true, configurable: true}}); \r\n\t\treturn Object.setPrototypeOf(Wrapper, Class);\r\n\t})(HTMLElement);\r\n\r\n\t// name = 'tag-name'\r\n\tfunction defineComponent(name){\r\n\t\tname = name.replace(/[^\\w-]+/g, '');\r\n\t\tvar tagName = name;\r\n\t\tname = name.split('-');\r\n\t\tif(name.length === 1)\r\n\t\t\treturn console.error(\"Please use '-' when defining component tags\");\r\n\r\n\t\tname = capitalizeLetters(name);\r\n\t\tvar func = eval(\"function \"+name+\"(){var he = HTMLElement_wrap.call(this);self.new(tagName, he, true);return he}\"+name);\r\n\t\tfunc.prototype = Object.create(HTMLElement.prototype);\r\n\t\tfunc.prototype.constructor = func;\r\n\t\tfunc.__proto__ = HTMLElement;\r\n\r\n\t\t// func.prototype.connectedCallback = function(){};\r\n\r\n\t\ttry{\r\n\t\t customElements.define(tagName, func);\r\n\t\t}catch(err){console.error(e)}\r\n\r\n\t\twindow['$'+name] = func;\r\n\t}\r\n};","// Data save and HTML content binding\r\nsf.model = function(scope){\r\n\tif(sf.component.registered[scope] !== void 0)\r\n\t\treturn root_(scope);\r\n\r\n\tif(!sf.model.root[scope])\r\n\t\tsf.model.root[scope] = {};\r\n\r\n\tif(sf.controller.pending[scope])\r\n\t\tsf.controller.run(scope);\r\n\r\n\treturn sf.model.root[scope];\r\n};\r\n\r\n(function(){\r\n\tvar self = sf.model;\r\n\tvar scope = internal.model = {};\r\n\tvar bindingEnabled = false;\r\n\tself.root = {};\r\n\r\n\tvar processingElement = null;\r\n\r\n\t// For debugging, normalize indentation\r\n\tfunction trimIndentation(text){\r\n\t\tvar indent = text.split(\"\\n\", 3);\r\n\t\tif(indent[0][0] !== ' ' || indent[0][0] !== \"\\t\")\r\n\t\t\tindent = indent[1];\r\n\t\telse indent = indent[0];\r\n\r\n\t\tif(indent === void 0) return text;\r\n\t\tindent = indent.length - indent.trim().length;\r\n\t\tif(indent === 0) return text;\r\n\t\treturn text.replace(RegExp('^([\\\\t ]{'+indent+'})', 'gm'), '');\r\n\t}\r\n\r\n\t// Secured evaluation\r\n\tvar bracketMatch = RegExp('([\\\\w.]*?[\\\\S\\\\s])\\\\('+sf.regex.avoidQuotes, 'g');\r\n\tvar chackValidFunctionCall = sf.regex.validFunctionCall;\r\n\tvar localEval = function(script, _model_, _modelScope, _content_){\r\n\t\t\"use strict\";\r\n\r\n\t\t// ==== Security check ====\r\n\t\tvar tempScript = script;\r\n\r\n\t\t// Remove all inner quotes\r\n\t\ttempScript = tempScript.replace(sf.regex.getQuotes, '\"Quotes\"');\r\n\r\n\t\t// Prevent vulnerability by remove bracket to avoid a function call\r\n\t\tvar preventExecution = false;\r\n\t\tvar check_ = null;\r\n\t\twhile((check_ = bracketMatch.exec(tempScript)) !== null){\r\n\t\t\tcheck_[1] = check_[1].trim();\r\n\r\n\t\t\tif(allowedFunctionEval.indexOf(check_[1]) === -1 &&\r\n\t\t\t\tcheck_[1].split('.')[0] !== '_modelScope' &&\r\n\t\t\t\tchackValidFunctionCall.test(check_[1][check_[1].length-1])\r\n\t\t\t){\r\n\t\t\t\tpreventExecution = check_[1];\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif(preventExecution){\r\n\t\t\tconsole.error(\"Trying to executing unrecognized function (\"+preventExecution+\")\");\r\n\t\t\tconsole.log(trimIndentation(processingElement.outerHTML).trim());\r\n\t\t\t//console.log(tempScript);\r\n\t\t\treturn '#DOMError';\r\n\t\t}\r\n\t\t// ==== Security check ended ====\r\n\t\r\n\t\tvar _result_ = '';\r\n\t\ttry{\r\n\t\t\tif(/@return /.test(script) === true){\r\n\t\t\t\tvar _evaled_ = eval('(function(){'+script.split('@return ').join('return ')+'})()');\r\n\t\t\t\treturn _result_ + _evaled_;\r\n\t\t\t}\r\n\t\t\telse var _evaled_ = eval(script);\r\n\t\t} catch(e){\r\n\t\t\tconsole.error(e);\r\n\t\t\tconsole.log(trimIndentation(processingElement.outerHTML).trim());\r\n\t\t\t//console.log(tempScript);\r\n\t\t\treturn '#DOMError';\r\n\t\t}\r\n\r\n\t\tif(_result_ !== '') return _result_;\r\n\t\treturn _evaled_;\r\n\t}\r\n\r\n\t// Find an index for the element on the list\r\n\tself.index = function(element){\r\n\t\tvar i = -1;\r\n\t\tvar tagName = element.tagName;\r\n\t\tvar currentElement = element;\r\n\r\n\t\twhile(element !== null) {\r\n\t\t\tif(element.tagName === tagName)\r\n\t\t\t\ti++;\r\n\r\n\t\t\telement = element.previousElementSibling;\r\n\t\t}\r\n\r\n\t\tvar list = currentElement.getAttribute('sf-bind-list');\r\n\t\tif(!list) return i;\r\n\r\n\t\tvar ref = self.root[sf.controller.modelName(currentElement)][list];\r\n\t\tif(!ref.$virtual) return i;\r\n\r\n\t\treturn i + ref.$virtual.DOMCursor - 1;\r\n\t}\r\n\r\n\t// Declare model for the name with a function\r\n\tself.for = function(name, func){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.for(name, func);\r\n\t\t\t});\r\n\t\t\r\n\t\tfunc(self(name), self);\r\n\t}\r\n\r\n\t// Get property of the model\r\n\tself.modelKeys = function(modelRef){\r\n\t\tvar keys = Object.keys(modelRef);\r\n\t\tfor (var i = keys.length - 1; i >= 0; i--) {\r\n\t\t\tif(keys[i].indexOf('$') !== -1)\r\n\t\t\t\tkeys.splice(i, 1);\r\n\t\t}\r\n\t\treturn keys;\r\n\t}\r\n\r\n\t// Escape the escaped quote\r\n\tfunction escapeEscapedQuote(text){\r\n\t\treturn text.split('\\\\\"').join('\\\\$%*').split(\"\\\\'\").join('\\\\%$*');\r\n\t}\r\n\r\n\tfunction unescapeEscapedQuote(text){\r\n\t\treturn text.split('\\\\$%*').join('\\\\\"').split('\\\\%$*').join(\"\\\\'\");\r\n\t}\r\n\r\n\tfunction elseIfHandle(else_, scopes){\r\n\t\tvar elseIf = else_.elseIf;\r\n\r\n\t\t// Else if\r\n\t\tfor (var i = 0; i < elseIf.length; i++) {\r\n\t\t\t// Check the condition\r\n\t\t\tscopes[0] = elseIf[i][0];\r\n\t\t\tif(!localEval.apply(self.root, scopes))\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\t// Get the value\r\n\t\t\tscopes[0] = elseIf[i][1];\r\n\t\t\treturn localEval.apply(self.root, scopes);\r\n\t\t}\r\n\r\n\t\t// Else\r\n\t\tif(else_.elseValue === null)\r\n\t\t\treturn '';\r\n\r\n\t\tscopes[0] = else_.elseValue;\r\n\t\treturn localEval.apply(self.root, scopes);\r\n\t}\r\n\r\n\t// ==== Template parser ====\r\n\tvar templateParser_regex = /{{%=([0-9]+)/gm;\r\n\tvar REF_DIRECT = 0, REF_IF = 1, REF_EXEC = 2;\r\n\tvar templateExec = function(parse, item, atIndex){\r\n\t\tvar parsed = {};\r\n\r\n\t\t// Get or evaluate static or dynamic data\r\n\t\tfor (var i = 0; i < parse.length; i++) {\r\n\t\t\tif(atIndex !== void 0 && atIndex.indexOf(i) === -1)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tvar ref = parse[i];\r\n\t\t\tref.data[1] = item;\r\n\r\n\t\t\t// Direct evaluation type\r\n\t\t\tif(ref.type === REF_DIRECT || ref.type === REF_EXEC)\r\n\t\t\t\tparsed[i] = {type:ref.type, data:localEval.apply(self.root, ref.data)};\r\n\r\n\t\t\t// Conditional type\r\n\t\t\telse if(ref.type === REF_IF){\r\n\t\t\t\tvar scopes = ref.data;\r\n\t\t\t\tparsed[i] = {type:ref.type, data:''};\r\n\t\t\t\tscopes[0] = ref.if[0];\r\n\r\n\t\t\t\t// If condition was not meet\r\n\t\t\t\tif(!localEval.apply(self.root, scopes)){\r\n\t\t\t\t\tparsed[i].data = elseIfHandle(ref, scopes);\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tscopes[0] = ref.if[1];\r\n\t\t\t\tparsed[i].data = localEval.apply(self.root, scopes);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn parsed;\r\n\t}\r\n\r\n\tvar templateParser = function(template, item, original){\r\n\t\tif(template.constructor !== Object){\r\n\t\t\tvar html = template.cloneNode(true);\r\n\t\t\thtml.model.$item = item;\r\n\t\t\treturn html;\r\n\t\t}\r\n\r\n\t\tvar html = original === true ? template.html : template.html.cloneNode(true);\r\n\t\tvar addresses = template.addresses;\r\n\t\tvar parsed = templateExec(template.parse, item);\r\n\r\n\t\t// Save model item reference to node\r\n\t\thtml.model = item;\r\n\r\n\t\tvar changesReference = [];\r\n\t\tvar pendingInsert = [];\r\n\r\n\t\t// Find element where the data belongs to\r\n\t\tfor (var i = 0; i < addresses.length; i++) {\r\n\t\t\tvar ref = addresses[i];\r\n\t\t\tvar current = $.childIndexes(ref.address, html);\r\n\r\n\t\t\t// Modify element attributes\r\n\t\t\tif(ref.nodeType === 1){\r\n\t\t\t\tvar refA = ref.attributes;\r\n\t\t\t\tfor(var a = 0; a < refA.length; a++){\r\n\t\t\t\t\tvar refB = refA[a];\r\n\r\n\t\t\t\t\tvar isValueInput = (refB.name === 'value' && (current.tagName === 'TEXTAREA' ||\r\n\t\t\t\t\t\t(current.tagName === 'INPUT' && /checkbox|radio|hidden/.test(current.type) === false)\r\n\t\t\t\t\t));\r\n\r\n\t\t\t\t\tchangesReference.push({\r\n\t\t\t\t\t\tattribute:isValueInput === true ? current : current.attributes[refB.name],\r\n\t\t\t\t\t\tref:refB\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tif(refB.direct !== void 0){\r\n\t\t\t\t\t\tif(refB.name === 'value' && isValueInput === true){\r\n\t\t\t\t\t\t\tcurrent.value = parsed[refB.direct].data;\r\n\t\t\t\t\t\t\tcurrent.removeAttribute('value');\r\n\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tcurrent.setAttribute(refB.name, parsed[refB.direct].data);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Below is used for multiple data\r\n\t\t\t\t\tif(refB.name === 'value' && isValueInput === true){\r\n\t\t\t\t\t\tvar temp = current.value;\r\n\t\t\t\t\t\tcurrent.removeAttribute('value');\r\n\t\t\t\t\t\tcurrent.value = temp;\r\n\t\t\t\t\t\trefB = current;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse refB = current.attributes[refB.name];\r\n\r\n\t\t\t\t\trefB.value = refB.value.replace(templateParser_regex, function(full, match){\r\n\t\t\t\t\t\treturn parsed[match].data;\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Replace text node\r\n\t\t\tif(ref.nodeType === 3){\r\n\t\t\t\tvar refA = current;\r\n\r\n\t\t\t\tchangesReference.push({\r\n\t\t\t\t\ttextContent:refA,\r\n\t\t\t\t\tref:ref\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif(ref.direct !== void 0){\r\n\t\t\t\t\trefA.textContent = parsed[ref.direct].data;\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Below is used for multiple/dynamic data\r\n\t\t\t\trefA.textContent = refA.textContent.replace(templateParser_regex, function(full, match){\r\n\t\t\t\t\treturn parsed[match].data;\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Replace dynamic node\r\n\t\t\tif(ref.nodeType === -1){\r\n\t\t\t\tvar cRef = {\r\n\t\t\t\t\tdynamicFlag:current,\r\n\t\t\t\t\tdirect:ref.parse_index,\r\n\t\t\t\t\tparentNode:current.parentNode,\r\n\t\t\t\t\tstartFlag:ref.startFlag && $.childIndexes(ref.startFlag, html)\r\n\t\t\t\t};\r\n\t\t\t\tchangesReference.push(cRef);\r\n\r\n\t\t\t\t// Pending element insert to take other element reference\r\n\t\t\t\tpendingInsert.push(cRef);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Save reference to element\r\n\t\thtml.sf$elementReferences = changesReference;\r\n\t\t// html.sf$modelParsed = parsed;\r\n\r\n\t\t// Run the pending element\r\n\t\tfor (var i = 0; i < pendingInsert.length; i++) {\r\n\t\t\tvar ref = pendingInsert[i];\r\n\t\t\tvar tDOM = $.parseElement(parsed[ref.direct].data, true);\r\n\t\t\tfor (var a = 0; a < tDOM.length; a++) {\r\n\t\t\t\tref.parentNode.insertBefore(tDOM[a], ref.dynamicFlag);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn html;\r\n\t}\r\n\r\n\tfunction syntheticCache(element, template, item){\r\n\t\tif(element.sf$cache === void 0)\r\n\t\t\telement.sf$cache = {};\r\n\r\n\t\tvar cache = element.sf$cache;\r\n\t\tvar modelRef_array = template.modelRef_array;\r\n\r\n\t\tfor (var i = 0; i < modelRef_array.length; i++) {\r\n\t\t\tvar ref = modelRef_array[i];\r\n\t\t\tcache[ref[0]] = deepProperty(item, ref[1]);\r\n\t\t}\r\n\t}\r\n\r\n\tfunction syntheticTemplate(element, template, property, item){\r\n\t\tvar cache = element.sf$cache;\r\n\t\tvar modelRef_array = template.modelRef_array;\r\n\r\n\t\tif(property !== void 0){\r\n\t\t\tvar changes = template.modelReference[property];\r\n\t\t\tif(changes === void 0 || changes.length === 0){\r\n\t\t\t\tconsole.error(\"Failed to run syntheticTemplate because property '\"+property+\"' is not observed\");\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\r\n\t\t\tif(cache)\r\n\t\t\t\tfor (var i = 0; i < modelRef_array.length; i++) {\r\n\t\t\t\t\tvar ref = modelRef_array[i];\r\n\t\t\t\t\tif(ref[0] !== property) continue;\r\n\r\n\t\t\t\t\tvar newData = deepProperty(item, ref[1]);\r\n\r\n\t\t\t\t\t// Check if data was different\r\n\t\t\t\t\tif(cache[ref[0]] !== newData)\r\n\t\t\t\t\t\tcache[ref[0]] = newData;\r\n\t\t\t\t}\r\n\t\t}\r\n\t\telse{\r\n\t\t\tvar changes = [];\r\n\t\t\tfor (var i = 0; i < modelRef_array.length; i++) {\r\n\t\t\t\tvar ref = modelRef_array[i];\r\n\t\t\t\tif(cache === void 0){\r\n\t\t\t\t\tArray.prototype.push.apply(changes, template.modelReference[ref[0]]);\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t\tvar newData = deepProperty(item, ref[1]);\r\n\r\n\t\t\t\t// Check if data was different\r\n\t\t\t\tif(cache[ref[0]] !== newData){\r\n\t\t\t\t\tArray.prototype.push.apply(changes, template.modelReference[ref[0]]);\r\n\t\t\t\t\tcache[ref[0]] = newData;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif(changes.length === 0) return false;\r\n\t\t}\r\n\r\n\t\tvar parsed = templateExec(template.parse, item, changes);\r\n\t\tfunction checkRelatedChanges(parseIndex){\r\n\t\t\tvar found = false;\r\n\t\t\tfor (var i = 0; i < parseIndex.length; i++) {\r\n\t\t\t\tif(changes.indexOf(parseIndex[i]) !== -1){\r\n\t\t\t\t\tfound = true;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif(found === false)\r\n\t\t\t\treturn false;\r\n\r\n\t\t\t// Prepare all required data\r\n\t\t\tchanges = [];\r\n\t\t\tfor (var i = 0; i < parseIndex.length; i++) {\r\n\t\t\t\tif(parsed[parseIndex[i]] === void 0){\r\n\t\t\t\t\tchanges.push(parseIndex[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tObject.assign(parsed, templateExec(template.parse, item, changes));\r\n\t\t\treturn true;\r\n\t\t}\r\n\r\n\t\tvar changesReference = element.sf$elementReferences;\r\n\t\tvar haveChanges = false;\r\n\t\tfor (var i = 0; i < changesReference.length; i++) {\r\n\t\t\tvar cRef = changesReference[i];\r\n\r\n\t\t\tif(cRef.dynamicFlag !== void 0){ // Dynamic data\r\n\t\t\t\tif(parsed[cRef.direct] !== void 0){\r\n\t\t\t\t\tvar tDOM = $.parseElement(parsed[cRef.direct].data, true).reverse();\r\n\t\t\t\t\tvar currentDOM = $.prevAll(cRef.dynamicFlag, cRef.startFlag);\r\n\t\t\t\t\tvar notExist = false;\r\n\r\n\t\t\t\t\t// Replace if exist, skip if similar\r\n\t\t\t\t\tfor (var a = 0; a < tDOM.length; a++) {\r\n\t\t\t\t\t\tif(currentDOM[a] === void 0){\r\n\t\t\t\t\t\t\tnotExist = true;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif(currentDOM[a].isEqualNode(tDOM[a]) === false)\r\n\t\t\t\t\t\t\tcRef.parentNode.replaceChild(tDOM[a], currentDOM[a]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add if not exist\r\n\t\t\t\t\tif(notExist){\r\n\t\t\t\t\t\tfor (var a = 0; a < tDOM.length; a++)\r\n\t\t\t\t\t\t\tcRef.parentNode.insertBefore(tDOM[a], cRef.dynamicFlag);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Remove if over index\r\n\t\t\t\t\telse{\r\n\t\t\t\t\t\tfor (var a = tDOM.length; a < currentDOM.length; a++) {\r\n\t\t\t\t\t\t\tcurrentDOM[a].remove();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\thaveChanges = true;\r\n\t\t\t\t}\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tif(cRef.textContent !== void 0){ // Text only\r\n\t\t\t\tif(cRef.ref.parse_index !== void 0){ // Multiple\r\n\t\t\t\t\tif(checkRelatedChanges(cRef.ref.parse_index) === true){\r\n\t\t\t\t\t\tvar temp = cRef.ref.value.replace(templateParser_regex, function(full, match){\r\n\t\t\t\t\t\t\treturn parsed[match].data;\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\tif(cRef.textContent.textContent === temp) continue;\r\n\t\t\t\t\t\tcRef.textContent.textContent = temp;\r\n\r\n\t\t\t\t\t\thaveChanges = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Direct value\r\n\t\t\t\telse if(parsed[cRef.ref.direct]){\r\n\t\t\t\t\tvar value = parsed[cRef.ref.direct].data;\r\n\t\t\t\t\tif(cRef.textContent.textContent === value) continue;\r\n\r\n\t\t\t\t\tvar ref_ = cRef.textContent;\r\n\t\t\t\t\t// Remove old element if exist\r\n\t\t\t\t\tif(ref_.sf$haveChilds === true){\r\n\t\t\t\t\t\twhile(ref_.previousSibling && ref_.previousSibling.sf$childRoot === ref_){\r\n\t\t\t\t\t\t\tref_.previousSibling.remove();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tref_.textContent = value;\r\n\t\t\t\t\thaveChanges = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if(cRef.attribute !== void 0){ // Attributes\r\n\t\t\t\tif(cRef.ref.parse_index !== void 0){ // Multiple\r\n\t\t\t\t\tif(checkRelatedChanges(cRef.ref.parse_index) === true){\r\n\t\t\t\t\t\tvar temp = cRef.ref.value.replace(templateParser_regex, function(full, match){\r\n\t\t\t\t\t\t\treturn parsed[match].data;\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\tif(cRef.attribute.value === temp) continue;\r\n\t\t\t\t\t\tcRef.attribute.value = temp;\r\n\r\n\t\t\t\t\t\thaveChanges = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Direct value\r\n\t\t\t\telse if(parsed[cRef.ref.direct]){\r\n\t\t\t\t\tvar value = parsed[cRef.ref.direct].data;\r\n\t\t\t\t\tif(cRef.attribute.value === value) continue;\r\n\t\t\t\t\tcRef.attribute.value = value;\r\n\r\n\t\t\t\t\thaveChanges = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn haveChanges;\r\n\t}\r\n\r\n\t// For contributor of this library\r\n\t// Please be careful when you're passing the eval argument\r\n\tvar dataParser = function(html, _model_, mask, scope, runEval, preParsedReference){\r\n\t\tvar _modelScope = self.root[scope];\r\n\t\tif(!runEval) runEval = '';\r\n\r\n\t\t// Don't match text inside quote, or object keys\r\n\t\tvar scopeMask = RegExp(sf.regex.strictVar+'('+self.modelKeys(_modelScope).join('|')+')\\\\b', 'g');\r\n\r\n\t\tif(mask)\r\n\t\t\tvar itemMask = RegExp(sf.regex.strictVar+mask+'\\\\.\\\\b', 'g');\r\n\r\n\t\tbindingEnabled = true;\r\n\r\n\t\tif(runEval === '#noEval'){\r\n\t\t\tvar preParsed = [];\r\n\t\t\tvar lastParsedIndex = preParsedReference.length;\r\n\t\t}\r\n\r\n\t\tvar prepared = html.replace(sf.regex.dataParser, function(actual, temp){\r\n\t\t\ttemp = avoidQuotes(temp, function(temp_){\r\n\t\t\t\t// Unescape HTML\r\n\t\t\t\ttemp = temp.split('&').join('&').split('<').join('<').split('>').join('>');\r\n\r\n\t\t\t\t// Mask item variable\r\n\t\t\t\tif(mask)\r\n\t\t\t\t\ttemp_ = temp_.replace(itemMask, function(matched){\r\n\t\t\t\t\t\treturn '_model_.'+matched[0].slice(1);\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t// Mask model for variable\r\n\t\t\t\treturn temp_.replace(scopeMask, function(full, matched){\r\n\t\t\t\t\treturn '_modelScope.'+matched;\r\n\t\t\t\t});\r\n\t\t\t}).split('_model_._modelScope.').join('_model_.');\r\n\r\n\t\t\t// Evaluate\r\n\t\t\tif(runEval === '#noEval'){\r\n\t\t\t\ttemp = temp.trim();\r\n\r\n\t\t\t\t// Simplicity similar\r\n\t\t\t\tvar exist = preParsed.indexOf(temp);\r\n\r\n\t\t\t\tif(exist === -1){\r\n\t\t\t\t\tpreParsed.push(temp);\r\n\t\t\t\t\tpreParsedReference.push({type:REF_DIRECT, data:[temp, _model_, _modelScope]});\r\n\t\t\t\t\treturn '{{%=' + (preParsed.length + lastParsedIndex - 1);\r\n\t\t\t\t}\r\n\t\t\t\treturn '{{%=' + (exist + lastParsedIndex);\r\n\t\t\t}\r\n\r\n\t\t\ttemp = '' + localEval.apply(self.root, [runEval + temp, _model_, _modelScope]);\r\n\r\n\t\t\treturn temp.replace(sf.regex.escapeHTML, function(i) {\r\n\t\t return '&#'+i.charCodeAt(0)+';';\r\n\t\t });\r\n\t\t});\r\n\r\n\t\tif(runEval === '#noEval'){\r\n\t\t\t// Clear memory before return\r\n\t\t\tpreParsed = _modelScope = _model_ = mask = scope = runEval = scopeMask = itemMask = html = null;\r\n\t\t\tsetTimeout(function(){prepared = null}, 1);\r\n\t\t}\r\n\t\treturn prepared;\r\n\t}\r\n\r\n\t// Dynamic data parser\r\n\tvar uniqueDataParser = function(html, _model_, mask, scope, runEval){\r\n\t\t// Get prepared html content\r\n\t\tvar _content_ = {\r\n\t\t\tlength:0,\r\n\t\t\ttake:function(passVar, currentIndex){\r\n\t\t\t\tif(passVar === null)\r\n\t\t\t\t\treturn dataParser(this[currentIndex], _model_, mask, scope);\r\n\r\n\t\t\t\t// Use strict mode and prepare for new variables\r\n\t\t\t\tvar strDeclare = '\"use strict\";var ';\r\n\t\t\t\tvar firstTime = true;\r\n\r\n\t\t\t\t// Declare new variable\r\n\t\t\t\tfor(var key in passVar){\r\n\t\t\t\t\tif(typeof passVar[key] === 'string')\r\n\t\t\t\t\t\tpassVar[key] = '\"'+passVar[key].split('\"').join('\\\\\"')+'\"';\r\n\t\t\t\t\telse if(typeof passVar[key] === 'object')\r\n\t\t\t\t\t\tpassVar[key] = JSON.stringify(passVar[key]);\r\n\r\n\t\t\t\t\tif(!firstTime)\r\n\t\t\t\t\t\tstrDeclare += ',';\r\n\r\n\t\t\t\t\tstrDeclare += key + ' = ' + passVar[key];\r\n\t\t\t\t\tfirstTime = false;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Remove var because no variable are being passed\r\n\t\t\t\tif(firstTime === true)\r\n\t\t\t\t\tstrDeclare = strDeclare.replace('var ', '');\r\n\r\n\t\t\t\t// Escape function call for addional security eval protection\r\n\t\t\t\tstrDeclare = strDeclare.split('(').join('(').split(')').join(')');\r\n\r\n\t\t\t\t// Pass to static data parser for another HTML data\r\n\t\t\t\treturn dataParser(this[currentIndex], _model_, mask, scope, strDeclare + ';');\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\t// Build script preparation\r\n\t\thtml = html.replace(/{\\[([\\s\\S]*?)\\]}/g, function(full, matched){\r\n\t\t\tif(/{{.*?}}/.test(matched) === false)\r\n\t\t\t\treturn \"_result_ += '\"+matched.split(\"'\").join(\"\\\\'\")+\"'\";\r\n\r\n\t\t\t_content_[_content_.length] = matched;\r\n\t\t\t_content_.length++;\r\n\t\t\treturn '_result_ += _content_.take(&VarPass&, '+(_content_.length - 1)+');';\r\n\t\t});\r\n\r\n\t\tvar _modelScope = self.root[scope];\r\n\r\n\t\t// Don't match text inside quote, or object keys\r\n\t\tvar scopeMask = RegExp(sf.regex.strictVar+'('+self.modelKeys(_modelScope).join('|')+')\\\\b', 'g');\r\n\r\n\t\tif(mask)\r\n\t\t\tvar itemMask = RegExp(sf.regex.strictVar+mask+'\\\\.\\\\b', 'g');\r\n\r\n\t\tif(runEval === '#noEval')\r\n\t\t\tvar preParsedReference = [];\r\n\r\n\t\tvar prepared = html.replace(sf.regex.uniqueDataParser, function(actual, temp){\r\n\t\t\ttemp = avoidQuotes(temp, function(temp_){\r\n\t\t\t\t// Unescape HTML\r\n\t\t\t\ttemp_ = temp_.split('&').join('&').split('<').join('<').split('>').join('>');\r\n\r\n\t\t\t\t// Mask item variable\r\n\t\t\t\tif(mask)\r\n\t\t\t\t\ttemp_ = temp_.replace(itemMask, function(matched){\r\n\t\t\t\t\t\treturn '_model_.'+matched[0].slice(1);\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t// Mask model for variable\r\n\t\t\t\treturn temp_.replace(scopeMask, function(full, matched){\r\n\t\t\t\t\treturn '_modelScope.'+matched;\r\n\t\t\t\t});\r\n\t\t\t}).split('_model_._modelScope.').join('_model_.');\r\n\r\n\t\t\tvar result = '';\r\n\t\t\tvar check = false;\r\n\r\n\t\t\t// Get defined variables\r\n\t\t\tvar VarPass_ = /(var|let)([\\w,\\s]+)(?=\\s(?==|in|of))/g;\r\n\t\t\tvar VarPass = [];\r\n\t\t\tvar s1 = null;\r\n\t\t\twhile((s1 = VarPass_.exec(temp)) !== null){\r\n\t\t\t\tVarPass.push(s1[2]);\r\n\t\t\t}\r\n\r\n\t\t\tif(_model_ === null && runEval === '#noEval')\r\n\t\t\t\tVarPass.push('_model_');\r\n\r\n\t\t\tif(VarPass.length !== 0){\r\n\t\t\t\tvar obtained = [];\r\n\t\t\t\tfor (var i = 0; i < VarPass.length; i++) {\r\n\t\t\t\t\tVarPass[i].replace(/([\\n\\t\\r]| )+/g, '').split(',').forEach(function(val){\r\n\t\t\t\t\t\tobtained.push(val);\r\n\t\t\t\t\t});\r\n\t\t\t\t};\r\n\t\t\t\tVarPass = obtained;\r\n\t\t\t\tfor (var i = 0; i < VarPass.length; i++) {\r\n\t\t\t\t\tVarPass[i] += ':(typeof '+VarPass[i]+'!==\"void 0\"?'+VarPass[i]+':void 0)';\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(VarPass.length === 0)\r\n\t\t\t\t\tVarPass = 'null';\r\n\t\t\t\telse VarPass = '{'+VarPass.join(',')+'}';\r\n\t\t\t\ttemp = temp.split('&VarPass&').join(VarPass);\r\n\t\t\t}\r\n\t\t\telse temp = temp.split('&VarPass&').join('null');\r\n\r\n\t\t\tcheck = temp.split('@if ');\r\n\t\t\tif(check.length !== 1){\r\n\t\t\t\tcheck = check[1].split(':');\r\n\r\n\t\t\t\t// {if, elseIf:([if, value], ...), elseValue}\r\n\t\t\t\tvar findElse = function(text){\r\n\t\t\t\t\ttext = text.join(':');\r\n\t\t\t\t\tvar else_ = null;\r\n\r\n\t\t\t\t\t// Split elseIf\r\n\t\t\t\t\ttext = text.split('@elseif ');\r\n\r\n\t\t\t\t\t// Get else value\r\n\t\t\t\t\tvar else_ = text[text.length - 1].split('@else');\r\n\t\t\t\t\tif(else_.length === 2){\r\n\t\t\t\t\t\ttext[text.length - 1] = else_[0];\r\n\t\t\t\t\t\telse_ = else_.pop();\r\n\t\t\t\t\t\telse_ = else_.substr(else_.indexOf(':') + 1);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse else_ = null;\r\n\r\n\t\t\t\t\tvar obj = {\r\n\t\t\t\t\t\tif:text.shift(),\r\n\t\t\t\t\t\telseIf:[],\r\n\t\t\t\t\t\telseValue:else_\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\t\t// Separate condition script and value\r\n\t\t\t\t\tfor (var i = 0; i < text.length; i++) {\r\n\t\t\t\t\t\tvar val = text[i].split(':');\r\n\t\t\t\t\t\tobj.elseIf.push([val.shift(), val.join(':')]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn obj;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(runEval === '#noEval'){\r\n\t\t\t\t\tvar condition = check.shift();\r\n\t\t\t\t\tvar elseIf = findElse(check);\r\n\t\t\t\t\telseIf.type = REF_IF;\r\n\t\t\t\t\telseIf.data = [null, _model_, _modelScope, _content_];\r\n\r\n\t\t\t\t\t// Trim Data\r\n\t\t\t\t\telseIf.if = [condition.trim(), elseIf.if.trim()];\r\n\t\t\t\t\tif(elseIf.elseValue !== null)\r\n\t\t\t\t\t\telseIf.elseValue = elseIf.elseValue.trim();\r\n\r\n\t\t\t\t\tfor (var i = 0; i < elseIf.elseIf.length; i++) {\r\n\t\t\t\t\t\telseIf.elseIf[i][0] = elseIf.elseIf[i][0].trim();\r\n\t\t\t\t\t\telseIf.elseIf[i][1] = elseIf.elseIf[i][1].trim();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Push data\r\n\t\t\t\t\tpreParsedReference.push(elseIf);\r\n\t\t\t\t\treturn '{{%%=' + (preParsedReference.length - 1);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar scopes = [check[0], _model_, _modelScope, _content_];\r\n\r\n\t\t\t\t// If condition was not meet\r\n\t\t\t\tif(!localEval.apply(self.root, scopes)){\r\n\t\t\t\t\tcheck.shift();\r\n\t\t\t\t\treturn elseIfHandle(findElse(check), scopes);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcheck.shift();\r\n\t\t\t\tscopes[0] = check.join(':');\r\n\r\n\t\t\t\treturn localEval.apply(self.root, scopes);\r\n\t\t\t}\r\n\r\n\t\t\t// Warning! Avoid unencoded user inputted content\r\n\t\t\t// And always check/remove closing ']}' in user content\r\n\t\t\t// Any function call will be removed for addional security\r\n\t\t\tcheck = temp.split('@exec');\r\n\t\t\tif(check.length !== 1){\r\n\t\t\t\tvar scopes = [check[1], _model_, _modelScope, _content_];\r\n\r\n\t\t\t\tif(runEval === '#noEval'){\r\n\t\t\t\t\tpreParsedReference.push({type:REF_EXEC, data:scopes});\r\n\t\t\t\t\treturn '{{%%=' + (preParsedReference.length - 1);\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttemp = localEval.apply(self.root, scopes);\r\n\t\t\t\treturn temp;\r\n\t\t\t}\r\n\t\t\treturn '';\r\n\t\t});\r\n\r\n\t\tif(runEval === '#noEval'){\r\n\t\t\t// Clear memory before return\r\n\t\t\t_modelScope = runEval = scopeMask = itemMask = html = null;\r\n\t\t\tsetTimeout(function(){prepared = null}, 1);\r\n\t\t\treturn [prepared, preParsedReference, _content_];\r\n\t\t}\r\n\r\n\t\treturn prepared;\r\n\t}\r\n\r\n\tvar bindArray = function(template, list, mask, modelName, propertyName, targetNode, parentNode, tempDOM){\r\n\t\tvar editProperty = ['pop', 'push', 'splice', 'shift', 'unshift', 'swap', 'move', 'replace', 'softRefresh', 'hardRefresh'];\r\n\t\tvar refreshTimer = -1;\r\n\t\tvar parentChilds = parentNode.children;\r\n\t\tvar isKeyed = parentNode.classList.contains('sf-keyed-list');\r\n\r\n\t\t// Update callback\r\n\t\tvar modelRef = self.root[modelName];\r\n\t\tvar eventVar = 'on$'+propertyName;\r\n\t\tvar callback = modelRef[eventVar];\r\n\r\n\t\tvar processElement = function(index, options, other, count){\r\n\t\t\t// Find boundary for inserting to virtual DOM\r\n\t\t\tif(list.$virtual){\r\n\t\t\t\tvar vStartRange = list.$virtual.DOMCursor;\r\n\t\t\t\tvar vEndRange = vStartRange + list.$virtual.preparedLength;\r\n\t\t\t}\r\n\r\n\t\t\tif(options === 'clear'){\r\n\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\tvar spacer = [parentNode.firstElementChild, parentNode.lastElementChild];\r\n\r\n\t\t\t\tparentNode.textContent = '';\r\n\r\n\t\t\t\tif(list.$virtual){\r\n\t\t\t\t\tparentNode.appendChild(spacer[0]);\r\n\t\t\t\t\tparentNode.appendChild(spacer[1]);\r\n\t\t\t\t\tlist.$virtual.dom.textContent = '';\r\n\t\t\t\t\tspacer[1].style.height = \r\n\t\t\t\t\tspacer[0].style.height = 0;\r\n\t\t\t\t\tlist.$virtual.reset(true);\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Avoid multiple refresh by set a timer\r\n\t\t\tif(list.$virtual){\r\n\t\t\t\tvar exist = list.$virtual.elements();\r\n\r\n\t\t\t\tclearTimeout(refreshTimer);\r\n\t\t\t\trefreshTimer = setTimeout(function(){\r\n\t\t\t\t\tlist.$virtual.reinitScroll();\r\n\t\t\t\t}, 100);\r\n\t\t\t}\r\n\t\t\telse exist = parentChilds;\r\n\r\n\t\t\t// Hard refresh - Append element\r\n\t\t\tif(options === 'hardRefresh'){\r\n\t\t\t\t// Clear siblings after the index\r\n\t\t\t\tfor (var i = index; i < exist.length; i++) {\r\n\t\t\t\t\texist[i].remove();\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\tvar vCursor = list.$virtual.vCursor;\r\n\r\n\t\t\t\tfor (var i = index; i < list.length; i++) {\r\n\t\t\t\t\tvar temp = templateParser(template, list[i]);\r\n\t\t\t\t\tif(list.$virtual){\r\n\t\t\t\t\t\tif(vCursor.floor === null && i < vEndRange)\r\n\t\t\t\t\t\t\tparentNode.insertBefore(temp, parentNode.lastElementChild);\r\n\t\t\t\t\t\telse list.$virtual.dom.appendChild(temp);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse parentNode.appendChild(temp);\r\n\r\n\t\t\t\t\tif(isKeyed === false)\r\n\t\t\t\t\t\tsyntheticCache(temp, template, list[i]);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(list.$virtual && list.$virtual.refreshVirtualSpacer)\r\n\t\t\t\t\tlist.$virtual.refreshVirtualSpacer(list.$virtual.DOMCursor);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif(callback === void 0)\r\n\t\t\t\tcallback = modelRef[eventVar];\r\n\r\n\t\t\tif(options === 'swap' || options === 'move'){\r\n\t\t\t\tif(options === 'move'){\r\n\t\t\t\t\tvar overflow = list.length - index - count;\r\n\t\t\t\t\tif(overflow < 0)\r\n\t\t\t\t\t\tcount += overflow;\r\n\r\n\t\t\t\t\t// Move to virtual DOM\r\n\t\t\t\t\tvar vDOM = document.createElement('div');\r\n\t\t\t\t\tfor (var i = 0; i < count; i++) {\r\n\t\t\t\t\t\tvDOM.appendChild(exist[index + i]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tvar nextSibling = exist[other] || null;\r\n\t\t\t\t\tvar theParent = nextSibling && nextSibling.parentNode;\r\n\r\n\t\t\t\t\tif(theParent === false){\r\n\t\t\t\t\t\tif(list.$virtual && list.length >= vEndRange)\r\n\t\t\t\t\t\t\ttheParent = list.$virtual.dom;\r\n\t\t\t\t\t\telse theParent = parentNode;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Move to defined index\r\n\t\t\t\t\tfor (var i = 0; i < count; i++) {\r\n\t\t\t\t\t\ttheParent.insertBefore(vDOM.firstElementChild, nextSibling);\r\n\r\n\t\t\t\t\t\tif(callback !== void 0 && callback.update)\r\n\t\t\t\t\t\t\tcallback.update(exist[index + i], 'move');\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(index > other){\r\n\t\t\t\t\tvar index_a = exist[other];\r\n\t\t\t\t\tother = exist[index];\r\n\t\t\t\t\tindex = index_a;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tindex = exist[index];\r\n\t\t\t\t\tother = exist[other];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar other_sibling = other.nextSibling;\r\n\t\t\t\tvar other_parent = other.parentNode;\r\n\t index.parentNode.insertBefore(other, index.nextSibling);\r\n\t other_parent.insertBefore(index, other_sibling);\r\n\r\n\t\t\t\tif(callback !== void 0 && callback.update){\r\n\t\t\t\t\tcallback.update(exist[other], 'swap');\r\n\t\t\t\t\tcallback.update(exist[index], 'swap');\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Clear unused element if current array < last array\r\n\t\t\tif(options === 'removeRange'){\r\n\t\t\t\tfor (var i = index; i < other; i++) {\r\n\t\t\t\t\texist[i].remove();\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Remove\r\n\t\t\tif(options === 'remove'){\r\n\t\t\t\tif(exist[index]){\r\n\t\t\t\t\tvar currentRemoved = false;\r\n\t\t\t\t\tvar startRemove = function(){\r\n\t\t\t\t\t\tif(currentRemoved) return;\r\n\t\t\t\t\t\tcurrentRemoved = true;\r\n\r\n\t\t\t\t\t\texist[index].remove();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif(callback !== void 0 && callback.remove){\r\n\t\t\t\t\t\t// Auto remove if return false\r\n\t\t\t\t\t\tif(!callback.remove(exist[index], startRemove))\r\n\t\t\t\t\t\t\tstartRemove();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Auto remove if no callback\r\n\t\t\t\t\telse startRemove();\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Update\r\n\t\t\telse if(options === 'update'){\r\n\t\t\t\tif(index === void 0){\r\n\t\t\t\t\tindex = 0;\r\n\t\t\t\t\tother = list.length;\r\n\t\t\t\t}\r\n\t\t\t\telse if(other === void 0) other = index + 1;\r\n\t\t\t\telse if(other < 0) other = list.length + other;\r\n\t\t\t\telse other += index;\r\n\r\n\t\t\t\t// Trim length\r\n\t\t\t\tvar overflow = list.length - other;\r\n\t\t\t\tif(overflow < 0) other = other + overflow;\r\n\r\n\t\t\t\tfor (var i = index; i < other; i++) {\r\n\t\t\t\t\tvar oldChild = exist[i];\r\n\t\t\t\t\tif(oldChild === void 0 || list[i] === void 0)\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tvar temp = templateParser(template, list[i]);\r\n\t\t\t\t\tif(isKeyed === false)\r\n\t\t\t\t\t\tsyntheticCache(temp, template, list[i]);\r\n\r\n\t\t\t\t\tif(list.$virtual){\r\n\t\t\t\t\t\toldChild.parentNode.replaceChild(temp, oldChild);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tparentNode.replaceChild(temp, oldChild);\r\n\t\t\t\t\tif(callback !== void 0 && callback.update)\r\n\t\t\t\t\t\tcallback.update(temp, 'replace');\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tvar item = list[index];\r\n\t\t\tif(item === void 0) return;\r\n\r\n\t\t\tvar temp = templateParser(template, item);\r\n\t\t\tif(isKeyed === false)\r\n\t\t\t\tsyntheticCache(temp, template, item);\r\n\r\n\t\t\t// Create\r\n\t\t\tif(options === 'insertAfter'){\r\n\t\t\t\tif(exist.length === 0)\r\n\t\t\t\t\tparentNode.insertBefore(temp, parentNode.lastElementChild);\r\n\t\t\t\telse{\r\n\t\t\t\t\tvar referenceNode = exist[index - 1];\r\n\t\t\t\t\treferenceNode.parentNode.insertBefore(temp, referenceNode.nextSibling);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(callback !== void 0 && callback.create)\r\n\t\t\t\t\tcallback.create(temp);\r\n\t\t\t}\r\n\t\t\telse if(options === 'prepend'){\r\n\t\t\t\tvar referenceNode = exist[0];\r\n\t\t\t\tif(referenceNode !== void 0){\r\n\t\t\t\t\treferenceNode.parentNode.insertBefore(temp, referenceNode);\r\n\r\n\t\t\t\t\tif(callback !== void 0 && callback.create)\r\n\t\t\t\t\t\tcallback.create(temp);\r\n\t\t\t\t}\r\n\t\t\t\telse options = 'append';\r\n\t\t\t}\r\n\t\t\tif(options === 'append'){\r\n\t\t\t\tif(list.$virtual){\r\n\t\t\t\t\tif(index === 0) // Add before virtual scroller\r\n\t\t\t\t\t\tparentNode.insertBefore(temp, parentNode.lastElementChild);\r\n\t\t\t\t\telse if(index >= vEndRange){ // To virtual DOM\r\n\t\t\t\t\t\tif(list.$virtual.vCursor.floor === null)\r\n\t\t\t\t\t\t\tlist.$virtual.vCursor.floor = temp;\r\n\r\n\t\t\t\t\t\tlist.$virtual.dom.appendChild(temp);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse // To real DOM\r\n\t\t\t\t\t\texist[index-1].insertAdjacentElement('afterEnd', temp);\r\n\r\n\t\t\t\t\tif(callback !== void 0 && callback.create)\r\n\t\t\t\t\t\tcallback.create(temp);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tparentNode.appendChild(temp);\r\n\t\t\t\tif(callback !== void 0 && callback.create)\r\n\t\t\t\t\tcallback.create(temp);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tvar _double_zero = [0,0]; // For arguments\r\n\t\tvar propertyProxy = function(subject, name){\r\n\t\t\tObject.defineProperty(subject, name, {\r\n\t\t\t\tenumerable: false,\r\n\t\t\t\tconfigurable: true,\r\n\t\t\t\tvalue: function(){\r\n\t\t\t\t\tvar temp = void 0;\r\n\t\t\t\t\tvar lastLength = this.length;\r\n\r\n\t\t\t\t\tif(name === 'move'){\r\n\t\t\t\t\t\tvar from = arguments[0];\r\n\t\t\t\t\t\tvar to = arguments[1];\r\n\t\t\t\t\t\tif(from === to) return;\r\n\t\t\t\t\t\tvar count = arguments[2] || 1;\r\n\t\t\t\t\t\tprocessElement(from, 'move', to, count);\r\n\r\n\t\t\t\t\t\tvar temp = Array.prototype.splice.apply(this, [from, count]);\r\n\t\t\t\t\t\ttemp.unshift(to, 0);\r\n\t\t\t\t\t\tArray.prototype.splice.apply(this, temp);\r\n\r\n\t\t\t\t\t\t// Reset virtual ceiling and floor\r\n\t\t\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\t\t\tlist.$virtual.reinitCursor();\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif(name === 'swap'){\r\n\t\t\t\t\t\tvar i = arguments[0];\r\n\t\t\t\t\t\tvar o = arguments[1];\r\n\t\t\t\t\t\tif(i === o) return;\r\n\t\t\t\t\t\tprocessElement(i, 'swap', o);\r\n\t\t\t\t\t\tvar temp = this[i];\r\n\t\t\t\t\t\tthis[i] = this[o];\r\n\t\t\t\t\t\tthis[o] = temp;\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'replace'){\r\n\t\t\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\t\t\tlist.$virtual.resetViewport();\r\n\r\n\t\t\t\t\t\t// Check if item has same reference\r\n\t\t\t\t\t\tif(arguments[0].length >= lastLength && lastLength !== 0){\r\n\t\t\t\t\t\t\tvar matchLeft = lastLength;\r\n\t\t\t\t\t\t\tvar ref = arguments[0];\r\n\r\n\t\t\t\t\t\t\tfor (var i = 0; i < lastLength; i++) {\r\n\t\t\t\t\t\t\t\tif(ref[i] === this[i]){\r\n\t\t\t\t\t\t\t\t\tmatchLeft--;\r\n\t\t\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// Add new element at the end\r\n\t\t\t\t\t\t\tif(matchLeft === 0){\r\n\t\t\t\t\t\t\t\tif(ref.length === lastLength) return;\r\n\r\n\t\t\t\t\t\t\t\tvar temp = arguments[0].slice(lastLength);\r\n\t\t\t\t\t\t\t\ttemp.unshift(lastLength, 0);\r\n\t\t\t\t\t\t\t\tthis.splice.apply(this, temp);\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// Add new element at the middle\r\n\t\t\t\t\t\t\telse if(matchLeft !== lastLength){\r\n\t\t\t\t\t\t\t\tif(arguments[1] === true){\r\n\t\t\t\t\t\t\t\t\tvar temp = arguments[0].slice(i);\r\n\t\t\t\t\t\t\t\t\ttemp.unshift(i, lastLength - i);\r\n\t\t\t\t\t\t\t\t\tArray.prototype.splice.apply(this, temp);\r\n\r\n\t\t\t\t\t\t\t\t\tlist.refresh(i, lastLength);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Build from zero\r\n\t\t\t\t\t\tif(lastLength === 0){\r\n\t\t\t\t\t\t\tArray.prototype.push.apply(this, arguments[0]);\r\n\t\t\t\t\t\t\tprocessElement(0, 'hardRefresh');\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Clear all items and merge the new one\r\n\t\t\t\t\t\tvar temp = [0, lastLength];\r\n\t\t\t\t\t\tArray.prototype.push.apply(temp, arguments[0]);\r\n\t\t\t\t\t\tArray.prototype.splice.apply(this, temp);\r\n\r\n\t\t\t\t\t\t// Rebuild all element\r\n\t\t\t\t\t\tif(arguments[1] !== true || isKeyed){\r\n\t\t\t\t\t\t\tprocessElement(0, 'clear');\r\n\t\t\t\t\t\t\tprocessElement(0, 'hardRefresh');\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Reuse some element\r\n\t\t\t\t\t\telse{\r\n\t\t\t\t\t\t\t// Clear unused element if current array < last array\r\n\t\t\t\t\t\t\tif(this.length < lastLength)\r\n\t\t\t\t\t\t\t\tprocessElement(this.length, 'removeRange', lastLength);\r\n\r\n\t\t\t\t\t\t\t// And start refreshing\r\n\t\t\t\t\t\t\tlist.refresh(0, this.length);\r\n\r\n\t\t\t\t\t\t\tif(list.$virtual && list.$virtual.refreshVirtualSpacer)\r\n\t\t\t\t\t\t\t\tlist.$virtual.refreshVirtualSpacer(list.$virtual.DOMCursor);\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Reset virtual list\r\n\t\t\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\t\t\tlist.$virtual.reset();\r\n\r\n\t\t\t\t\t\treturn this;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'splice' && arguments[0] === 0 && arguments[1] === void 0){\r\n\t\t\t\t\t\tprocessElement(0, 'clear');\r\n\t\t\t\t\t\treturn Array.prototype.splice.apply(this, arguments);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif(Array.prototype[name])\r\n\t\t\t\t\t\ttemp = Array.prototype[name].apply(this, arguments);\r\n\r\n\t\t\t\t\tif(name === 'pop')\r\n\t\t\t\t\t\tprocessElement(this.length, 'remove');\r\n\r\n\t\t\t\t\telse if(name === 'push'){\r\n\t\t\t\t\t\tif(arguments.length === 1)\r\n\t\t\t\t\t\t\tprocessElement(lastLength, 'append');\r\n\t\t\t\t\t\telse{\r\n\t\t\t\t\t\t\tfor (var i = 0; i < arguments.length; i++) {\r\n\t\t\t\t\t\t\t\tprocessElement(lastLength + i, 'append');\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'shift'){\r\n\t\t\t\t\t\tprocessElement(0, 'remove');\r\n\r\n\t\t\t\t\t\tif(list.$virtual && list.$virtual.DOMCursor > 0){\r\n\t\t\t\t\t\t\tlist.$virtual.DOMCursor--;\r\n\t\t\t\t\t\t\tlist.$virtual.reinitCursor();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'splice'){\r\n\t\t\t\t\t\tif(arguments[0] === 0 && arguments[1] === void 0)\r\n\t\t\t\t\t\t\treturn temp;\r\n\r\n\t\t\t\t\t\t// Removing data\r\n\t\t\t\t\t\tvar real = arguments[0];\r\n\t\t\t\t\t\tif(real < 0) real = lastLength + real;\r\n\r\n\t\t\t\t\t\tvar limit = arguments[1];\r\n\t\t\t\t\t\tif(!limit && limit !== 0) limit = this.length;\r\n\r\n\t\t\t\t\t\tfor (var i = limit - 1; i >= 0; i--) {\r\n\t\t\t\t\t\t\tprocessElement(real + i, 'remove');\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif(list.$virtual && list.$virtual.DOMCursor >= real)\r\n\t\t\t\t\t\t\tlist.$virtual.DOMCursor = real - limit;\r\n\r\n\t\t\t\t\t\tif(arguments.length >= 3){ // Inserting data\r\n\t\t\t\t\t\t\tlimit = arguments.length - 2;\r\n\r\n\t\t\t\t\t\t\t// Trim the index if more than length\r\n\t\t\t\t\t\t\tif(real >= this.length)\r\n\t\t\t\t\t\t\t\treal = this.length - 1;\r\n\r\n\t\t\t\t\t\t\tfor (var i = 0; i < limit; i++) {\r\n\t\t\t\t\t\t\t\tprocessElement(real + i, 'insertAfter');\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tif(list.$virtual && list.$virtual.DOMCursor >= real)\r\n\t\t\t\t\t\t\t\tlist.$virtual.DOMCursor += limit;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'unshift'){\r\n\t\t\t\t\t\tif(arguments.length === 1)\r\n\t\t\t\t\t\t\tprocessElement(0, 'prepend');\r\n\t\t\t\t\t\telse{\r\n\t\t\t\t\t\t\tfor (var i = arguments.length - 1; i >= 0; i--) {\r\n\t\t\t\t\t\t\t\tprocessElement(i, 'prepend');\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif(list.$virtual && list.$virtual.DOMCursor !== 0){\r\n\t\t\t\t\t\t\tlist.$virtual.DOMCursor += arguments.length;\r\n\t\t\t\t\t\t\tlist.$virtual.reinitCursor();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'softRefresh'){\r\n\t\t\t\t\t\tprocessElement(arguments[0], 'update', arguments[1]);\r\n\r\n\t\t\t\t\t\tif(list.$virtual && list.$virtual.DOMCursor)\r\n\t\t\t\t\t\t\tlist.$virtual.reinitCursor();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\telse if(name === 'hardRefresh'){\r\n\t\t\t\t\t\tprocessElement(arguments[0] || 0, 'hardRefresh');\r\n\r\n\t\t\t\t\t\tif(list.$virtual)\r\n\t\t\t\t\t\t\tlist.$virtual.DOMCursor = arguments[0] || 0;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn temp;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tif(parentNode && parentNode.classList.contains('sf-virtual-list')){\r\n\t\t\tdelete list.$virtual;\r\n\t\t\tlist.$virtual = {};\r\n\r\n\t\t\t// Transfer virtual DOM\r\n\t\t\tlist.$virtual.dom = tempDOM;\r\n\t\t\tif(callback !== void 0)\r\n\t\t\t\tlist.$virtual.callback = callback;\r\n\t\t\telse list.$virtual.callback_ = {ref:modelRef, var:eventVar};\r\n\r\n\t\t\tparentNode.replaceChild(template.html, parentChilds[1]);\r\n\t\t\tsf.internal.virtual_scroll.handle(list, targetNode, parentNode);\r\n\t\t\ttemplate.html.remove();\r\n\t\t}\r\n\r\n\t\tfor (var i = 0; i < editProperty.length; i++) {\r\n\t\t\tpropertyProxy(list, editProperty[i]);\r\n\t\t}\r\n\r\n\t\t// Todo: Enable auto item binding\r\n\t\tif(false && list.auto !== false){\r\n\t\t\t// for (var i = 0; i < list.length; i++) {\r\n\t\t\t// \tlist[i]\r\n\t\t\t// }\r\n\t\t}\r\n\r\n\t\thiddenProperty(list, '$replace', function(index, key, needle, func){\r\n\t\t\tvar elRef = list.getElement(index).sf$elementReferences;\r\n\t\t\tvar process = template.modelReference[key];\r\n\t\t\tif(process === void 0){\r\n\t\t\t\tconsole.error(\"Can't found binding for '\"+key+\"'\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tfor (var i = 0; i < elRef.length; i++) {\r\n\t\t\t\tif(elRef[i].textContent === void 0 || elRef[i].ref.direct === void 0)\r\n\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\tif(process.indexOf(elRef[i].ref.direct) !== -1){\r\n\t\t\t\t\tvar ref = elRef[i].textContent;\r\n\t\t\t\t\tvar content = $.escapeText(list[index][key]).replace(needle, func);\r\n\r\n\t\t\t\t\t// Skip if nothing was changed\r\n\t\t\t\t\tif(list[index][key] === content) continue;\r\n\t\t\t\t\tref.textContent = ''; // Let this empty for later referencing\r\n\t\t\t\t\tref.sf$haveChilds = true;\r\n\t\t\t\t\tcontent = $.parseElement(content, true);\r\n\r\n\t\t\t\t\t// Remove old element if exist\r\n\t\t\t\t\twhile(ref.previousSibling && ref.previousSibling.sf$childRoot === ref){\r\n\t\t\t\t\t\tref.previousSibling.remove();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tvar parentNode_ = ref.parentNode;\r\n\t\t\t\t\tfor (var i = 0; i < content.length; i++) {\r\n\t\t\t\t\t\tcontent[i].sf$childRoot = ref;\r\n\t\t\t\t\t\tparentNode_.insertBefore(content[i], ref);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\thiddenProperty(list, 'refresh', function(index, length, property){\r\n\t\t\tif(index === void 0 || index.constructor === String){\r\n\t\t\t\tproperty = index;\r\n\t\t\t\tindex = 0;\r\n\t\t\t\tlength = list.length;\r\n\t\t\t}\r\n\t\t\telse if(length === void 0) length = index + 1;\r\n\t\t\telse if(length.constructor === String){\r\n\t\t\t\tproperty = length;\r\n\t\t\t\tlength = index + 1;\r\n\t\t\t}\r\n\t\t\telse if(length < 0) length = list.length + length;\r\n\t\t\telse length += index;\r\n\r\n\t\t\t// Trim length\r\n\t\t\tvar overflow = list.length - length;\r\n\t\t\tif(overflow < 0) length = length + overflow;\r\n\r\n\t\t\tfor (var i = index; i < length; i++) {\r\n\t\t\t\tvar elem = list.getElement(i);\r\n\r\n\t\t\t\t// Create element if not exist\r\n\t\t\t\tif(elem === void 0){\r\n\t\t\t\t\tlist.hardRefresh(i);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tif(isKeyed === true)\r\n\t\t\t\t\t\tlist.softRefresh(i);\r\n\t\t\t\t\telse if(syntheticTemplate(elem, template, property, list[i]) === false)\r\n\t\t\t\t\t\tcontinue; // Continue if no update\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(callback !== void 0 && callback.update)\r\n\t\t\t\t\tcallback.update(elem, 'replace');\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tvar virtualChilds = null;\r\n\t\tif(list.$virtual)\r\n\t\t\tvirtualChilds = list.$virtual.dom.children;\r\n\t\thiddenProperty(list, 'getElement', function(index){\r\n\t\t\tif(virtualChilds !== null){\r\n\t\t\t\tvar ret = void 0;\r\n\t\t\t\tif(index < list.$virtual.DOMCursor)\r\n\t\t\t\t\treturn virtualChilds[index];\r\n\t\t\t\telse {\r\n\t\t\t\t\tindex -= list.$virtual.DOMCursor;\r\n\t\t\t\t\tvar childElement = parentNode.childElementCount - 2;\r\n\r\n\t\t\t\t\tif(index < childElement)\r\n\t\t\t\t\t\treturn parentChilds[index + 1];\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn virtualChilds[index - childElement + list.$virtual.DOMCursor];\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn void 0;\r\n\t\t\t}\r\n\r\n\t\t\treturn parentChilds[index];\r\n\t\t});\r\n\t}\r\n\r\n\tvar loopParser = function(name, template, script, targetNode, parentNode){\r\n\t\tvar method = script.split(' in ');\r\n\t\tvar mask = method[0];\r\n\r\n\t\tvar items = root_(name)[method[1]];\r\n\t\tif(items === void 0)\r\n\t\t\titems = root_(name)[method[1]] = [];\r\n\r\n\t\ttemplate.setAttribute('sf-bind-list', method[1]);\r\n\r\n\t\t// Get reference for debugging\r\n\t\tprocessingElement = template;\r\n\t\ttemplate = self.extractPreprocess(template, mask, name);\r\n\r\n\t\tif(method.length === 2){\r\n\t\t\tvar isKeyed = parentNode.classList.contains('sf-keyed-list');\r\n\t\t\tvar tempDOM = document.createElement('div');\r\n\t\t\tvar modelRef = self.root[name];\r\n\r\n\t\t\tfor (var i = 0; i < items.length; i++) {\r\n\t\t\t\tvar elem = templateParser(template, items[i]);\r\n\t\t\t\ttempDOM.appendChild(elem);\r\n\r\n\t\t\t\tif(isKeyed === false)\r\n\t\t\t\t\tsyntheticCache(elem, template, items[i]);\r\n\t\t\t}\r\n\r\n\t\t\t// Enable element binding\r\n\t\t\tif(modelRef.sf$bindedKey === void 0)\r\n\t\t\t\tinitBindingInformation(modelRef);\r\n\r\n\t\t\tif(modelRef.sf$bindedKey[method[1]] === void 0)\r\n\t\t\t\tmodelRef.sf$bindedKey[method[1]] = null;\r\n\r\n\t\t\tObject.defineProperty(modelRef, method[1], {\r\n\t\t\t\tenumerable: true,\r\n\t\t\t\tconfigurable: true,\r\n\t\t\t\tget:function(){\r\n\t\t\t\t\treturn items;\r\n\t\t\t\t},\r\n\t\t\t\tset:function(val){\r\n\t\t\t\t\tif(val.length === 0)\r\n\t\t\t\t\t\treturn items.splice(0);\r\n\t\t\t\t\treturn items.replace(val, true);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tbindArray(template, items, mask, name, method[1], targetNode, parentNode, tempDOM);\r\n\r\n\t\t\t// Output to real DOM if not being used for virtual list\r\n\t\t\tif(items.$virtual === void 0){\r\n\t\t\t\tvar children = tempDOM.children;\r\n\t\t\t\tfor (var i = 0, n = children.length; i < n; i++) {\r\n\t\t\t\t\tparentNode.appendChild(children[0]);\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttempDOM.remove();\r\n\t\t\t\ttempDOM = null;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tvar callInputListener = function(model, property, value){\r\n\t\tvar callback = model['on$'+property];\r\n\t\tvar v2m = model['v2m$'+property];\r\n\t\tvar newValue1 = void 0; var newValue2 = void 0;\r\n\t\tif(callback !== void 0 || v2m !== void 0){\r\n\t\t\tvar old = model[property];\r\n\t\t\tif(old !== null && old !== void 0 && old.constructor === Array)\r\n\t\t\t\told = old.slice(0);\r\n\r\n\t\t\ttry{\r\n\t\t\t\tif(v2m !== void 0)\r\n\t\t\t\t\tnewValue1 = v2m(old, value);\r\n\r\n\t\t\t\tif(callback !== void 0)\r\n\t\t\t\t\tnewValue2 = callback(old, value);\r\n\t\t\t}catch(e){console.error(e)}\r\n\t\t}\r\n\t\treturn newValue2 !== void 0 ? newValue2 : newValue1;\r\n\t}\r\n\r\n\tvar inputBoundRunning = false;\r\n\tvar inputTextBound = function(e){\r\n\t\tif(e.fromSFFramework === true) return;\r\n\r\n\t\tinputBoundRunning = true;\r\n\t\tvar ref = e.target;\r\n\t\tref.viewInputted = true;\r\n\t\tvar value = ref.typeData === Number ? Number(ref.value) : ref.value;\r\n\t\tvar newValue = callInputListener(ref.sfModel, ref.sfBounded, value);\r\n\t\tif(newValue !== void 0)\r\n\t\t\tref.sfModel[ref.sfBounded] = newValue;\r\n\t\telse ref.sfModel[ref.sfBounded] = value;\r\n\t}\r\n\tvar inputFilesBound = function(e){\r\n\t\tif(e.fromSFFramework === true) return;\r\n\t\t\r\n\t\tvar ref = e.target;\r\n\t\tcallInputListener(ref.sfModel, ref.sfBounded, ref.files);\r\n\t\tref.sfModel[ref.sfBounded] = ref.files;\r\n\t}\r\n\r\n\tvar inputCheckBoxBound = function(e){\r\n\t\tif(e.fromSFFramework === true) return;\r\n\t\t\r\n\t\tinputBoundRunning = true;\r\n\t\tvar ref = e.target;\r\n\t\tref.viewInputted = true;\r\n\t\tvar value = ref.typeData === Number ? Number(ref.value) : ref.value;\r\n\t\tvar newValue = callInputListener(ref.sfModel, ref.sfBounded, value);\r\n\t\tif(newValue !== void 0)\r\n\t\t\tvalue = newValue;\r\n\r\n\t\tvar model = ref.sfModel;\r\n\t\tvar constructor = model[ref.sfBounded];\r\n\r\n\t\tif(constructor === Array){\r\n\t\t\tvar i = model[ref.sfBounded].indexOf(value);\r\n\r\n\t\t\tif(i === -1 && ref.checked === true)\r\n\t\t\t\tmodel[ref.sfBounded].push(value);\r\n\t\t\telse if(i !== -1 && ref.checked === false)\r\n\t\t\t\tmodel[ref.sfBounded].splice(i, 1);\r\n\t\t}\r\n\t\telse if(constructor === Boolean || ref.typeData === Boolean)\r\n\t\t\tmodel[ref.sfBounded] = ref.checked;\r\n\t\telse model[ref.sfBounded] = value;\r\n\t}\r\n\r\n\tvar inputSelectBound = function(e){\r\n\t\tif(e.fromSFFramework === true) return;\r\n\t\t\r\n\t\tinputBoundRunning = true;\r\n\t\tvar ref = e.target;\r\n\t\tref.viewInputted = true;\r\n\t\tvar typeData = ref.typeData;\r\n\t\tif(ref.multiple === true){\r\n\t\t\tvar temp = ref.selectedOptions;\r\n\t\t\tvar value = [];\r\n\t\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\t\tvalue.push(typeData === Number ? Number(temp[i].value) : temp[i].value);\r\n\t\t\t}\r\n\t\t}\r\n\t\telse value = typeData === Number ? Number(ref.selectedOptions[0].value) : ref.selectedOptions[0].value;\r\n\r\n\t\tvar newValue = callInputListener(ref.sfModel, ref.sfBounded, value);\r\n\t\tif(newValue !== void 0)\r\n\t\t\tref.sfModel[ref.sfBounded] = newValue;\r\n\t\telse ref.sfModel[ref.sfBounded] = value;\r\n\t}\r\n\r\n\tvar assignElementData = {\r\n\t\tselect:function(model, property, element){\r\n\t\t\tvar list = element.options;\r\n\t\t\tvar typeData = element.typeData;\r\n\t\t\tvar arrayValue = model[property].constructor === Array ? model[property] : false;\r\n\t\t\tfor (var i = 0, n = list.length; i < n; i++) {\r\n\t\t\t\tif(arrayValue === false){\r\n\t\t\t\t\tif(typeData === String)\r\n\t\t\t\t\t\tlist[i].selected = list[i].value === model[property];\r\n\t\t\t\t\telse list[i].selected = list[i].value == model[property];\r\n\t\t\t\t}\r\n\t\t\t\telse list[i].selected = arrayValue.indexOf(typeData === Number ? Number(list[i].value) : list[i].value) !== -1;\r\n\t\t\t}\r\n\t\t},\r\n\t\tcheckbox:function(model, property, element){\r\n\t\t\tif(model[property].constructor === Array)\r\n\t\t\t\telement.checked = model[property].indexOf(element.typeData === Number ? Number(element.value) : element.value) !== -1;\r\n\t\t\telse if(model[property].constructor === Boolean)\r\n\t\t\t\telement.checked = Boolean(model[property]);\r\n\t\t\telse{\r\n\t\t\t\tif(element.typeData === String)\r\n\t\t\t\t\telement.checked = element.value === model[property];\r\n\t\t\t\telse element.checked = element.value == model[property];\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tvar inputBoundRun = function(model, property, elements){\r\n\t\tif(inputBoundRunning === true)\r\n\t\t\treturn; // Avoid multiple assigment\r\n\r\n\t\tfor (var i = 0; i < elements.length; i++) {\r\n\t\t\tvar ev = new Event('change');\r\n\t\t\tev.fromSFFramework = true;\r\n\r\n\t\t\tif(elements.type === 1) // text\r\n\t\t\t\telements[i].value = model[property];\r\n\t\t\telse if(elements.type === 2) // select options\r\n\t\t\t\tassignElementData.select(model, property, elements[i]);\r\n\t\t\telse if(elements.type === 3) // radio\r\n\t\t\t\telements[i].checked = model[property] == elements[i].value;\r\n\t\t\telse if(elements.type === 4) // checkbox\r\n\t\t\t\tassignElementData.checkbox(model, property, elements[i]);\r\n\r\n\t\t\telements[i].dispatchEvent(ev);\r\n\t\t}\r\n\t}\r\n\r\n\tvar triggerInputEvent = function(e){\r\n\t\tif(e.fromSFFramework === true) return;\r\n\t\tif(e.target.viewInputted === true){\r\n\t\t\te.target.viewInputted = false;\r\n\t\t\treturn;\r\n\t\t}\r\n\t\te.target.dispatchEvent(new Event('input'));\r\n\t}\r\n\r\n\tvar elementBoundChanges = function(model, property, element, oneWay){\r\n\t\t// Enable multiple element binding\r\n\t\tif(model.sf$bindedKey === void 0)\r\n\t\t\tinitBindingInformation(model);\r\n\r\n\t\tvar type = 0;\r\n\t\tvar typeData = null;\r\n\t\tif(model[property] !== null && model[property] !== void 0)\r\n\t\t\ttypeData = model[property].constructor;\r\n\r\n\t\tvar assignedType = (element.getAttribute('typedata') || '').toLowerCase();\r\n\t\tif(assignedType === 'number')\r\n\t\t\ttypeData = Number;\r\n\r\n\t\telement.typeData = typeData;\r\n\t\t$.on(element, 'change', triggerInputEvent);\r\n\r\n\t\t// Bound value change\r\n\t\tif(element.tagName === 'TEXTAREA'){\r\n\t\t\t$.on(element, 'input', inputTextBound);\r\n\t\t\telement.value = model[property];\r\n\t\t\ttype = 1;\r\n\t\t}\r\n\r\n\t\telse if(element.selectedOptions !== void 0){\r\n\t\t\t$.on(element, 'input', inputSelectBound);\r\n\t\t\ttype = 2;\r\n\r\n\t\t\tassignElementData.select(model, property, element);\r\n\t\t}\r\n\r\n\t\telse{\r\n\t\t\tvar type = element.type.toLowerCase();\r\n\t\t\tif(type === 'radio'){\r\n\t\t\t\t$.on(element, 'input', inputTextBound);\r\n\t\t\t\ttype = 3;\r\n\r\n\t\t\t\telement.checked = model[property] == element.value;\r\n\t\t\t}\r\n\t\t\telse if(type === 'checkbox'){\r\n\t\t\t\t$.on(element, 'input', inputCheckBoxBound);\r\n\t\t\t\ttype = 4;\r\n\r\n\t\t\t\tassignElementData.checkbox(model, property, element);\r\n\t\t\t}\r\n\r\n\t\t\telse if(type === 'file'){\r\n\t\t\t\t$.on(element, 'input', inputFilesBound);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\telse{\r\n\t\t\t\t$.on(element, 'input', inputTextBound);\r\n\t\t\t\telement.value = model[property];\r\n\t\t\t\ttype = 1;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif(oneWay === true) return;\r\n\t\tmodelToViewBinding(model, property, inputBoundRun, element, type);\r\n\t}\r\n\r\n\tvar bindInput = function(targetNode){\r\n\t\tvar temp = $('input[sf-bound], textarea[sf-bound], select[sf-bound], input[sf-bind], textarea[sf-bind], select[sf-bind]', targetNode);\r\n\r\n\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\tvar element = temp[i];\r\n\t\t\tvar model = sf.controller.modelName(element);\r\n\t\t\tif(!model) return;\r\n\t\t\tvar modelScope = self.root[model];\r\n\r\n\t\t\tvar oneWay = false;\r\n\t\t\tvar propertyName = element.getAttribute('sf-bound');\r\n\t\t\tif(propertyName === null){\r\n\t\t\t\tpropertyName = element.getAttribute('sf-bind');\r\n\t\t\t\toneWay = true;\r\n\t\t\t}\r\n\t\t\tif(propertyName === \"\")\r\n\t\t\t\tpropertyName = element.getAttribute('name');\r\n\r\n\t\t\tif(propertyName === null){\r\n\t\t\t\tconsole.error(\"Property key to be bound wasn't be found\", element);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Get reference\r\n\t\t\tif(modelScope[propertyName] === void 0){\r\n\t\t\t\tconsole.error('Can\\'t get property \"'+propertyName+'\" on model \"' + model + '\"');\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\telement.sfBounded = propertyName;\r\n\t\t\telement.sfModel = modelScope;\r\n\t\t\tif(oneWay === false){\r\n\t\t\t\telement.setAttribute('sf-bounded', '');\r\n\t\t\t\telement.removeAttribute('sf-bound');\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\telement.setAttribute('sf-binded', '');\r\n\t\t\t\telement.removeAttribute('sf-bind');\r\n\t\t\t}\r\n\r\n\t\t\telementBoundChanges(modelScope, propertyName, element, oneWay);\r\n\t\t}\r\n\t}\r\n\r\n\tvar alreadyInitialized = false;\r\n\tself.init = function(targetNode, queued){\r\n\t\tif(alreadyInitialized && !targetNode) return;\r\n\t\talreadyInitialized = true;\r\n\t\tsetTimeout(function(){\r\n\t\t\talreadyInitialized = false;\r\n\t\t}, 50);\r\n\r\n\t\tif(!targetNode) targetNode = document.body;\r\n\r\n\t\tself.parsePreprocess(queued || self.queuePreprocess(targetNode), queued);\r\n\t\tbindInput(targetNode);\r\n\r\n\t\t// Find element for array binding\r\n\t\tvar temp = $('[sf-repeat-this]', targetNode);\r\n\t\tfor (var a = 0; a < temp.length; a++) {\r\n\t\t\tvar element = temp[a];\r\n\t\t\tvar parent = element.parentElement;\r\n\r\n\t\t\tif(queued !== void 0)\r\n\t\t\t\telement.classList.remove('sf-dom-queued');\r\n\r\n\t\t\tif(parent.classList.contains('sf-virtual-list')){\r\n\t\t\t\tvar ceiling = document.createElement(element.tagName);\r\n\t\t\t\tceiling.classList.add('virtual-spacer');\r\n\t\t\t\tvar floor = ceiling.cloneNode(true);\r\n\r\n\t\t\t\tceiling.classList.add('ceiling');\r\n\t\t\t\tparent.insertBefore(ceiling, parent.firstElementChild); // prepend\r\n\r\n\t\t\t\tfloor.classList.add('floor');\r\n\t\t\t\tparent.appendChild(floor); // append\r\n\t\t\t}\r\n\r\n\t\t\tvar after = element.nextElementSibling;\r\n\t\t\tif(after === null || element === after)\r\n\t\t\t\tafter = false;\r\n\r\n\t\t\tvar before = element.previousElementSibling;\r\n\t\t\tif(before === null || element === before)\r\n\t\t\t\tbefore = false;\r\n\r\n\t\t\tvar script = element.getAttribute('sf-repeat-this');\r\n\t\t\telement.removeAttribute('sf-repeat-this');\r\n\r\n\t\t\t// Check if the element was already bound to prevent vulnerability\r\n\t\t\tif(/sf-bind-key|sf-bind-list/.test(element.outerHTML))\r\n\t\t\t\tthrow \"Can't parse element that already bound\";\r\n\r\n\t\t\tvar controller = sf.controller.modelName(element);\r\n\t\t\tloopParser(controller, element, script, targetNode, parent);\r\n\t\t\telement.remove();\r\n\t\t}\r\n\t}\r\n\r\n\t// Reset model properties\r\n\t// Don't call if the removed element is TEXT or #comment\r\n\tvar DOMNodeRemoved = scope.DOMNodeRemoved = function(element){\r\n\t\tif(element.hasAttribute('sf-controller') !== false){\r\n\t\t\tvar modelName = element.sf$component === void 0 ? element.getAttribute('sf-controller') : element.sf$component;\r\n\r\n\t\t\tremoveModelBinding(modelName);\r\n\t\t\tif(element.sf$component !== void 0){\r\n\t\t\t\tvar modelFrom = element.sf$componentFrom;\r\n\t\t\t\tvar components = sf.component.available[modelFrom];\r\n\t\t\t\tcomponents.splice(components.indexOf(modelName), 1);\r\n\t\t\t\tinternal.component.triggerEvent(modelFrom, 'removed', self.root[modelName]);\r\n\t\t\t\tdelete self.root[modelName];\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar temp = $('[sf-controller]', element);\r\n\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\tDOMNodeRemoved(temp[i]);\r\n\t\t}\r\n\t}\r\n\r\n\tsf(function(){\r\n\t\tvar everyRemovedNodes = function(nodes){\r\n\t\t\tif(nodes.nodeType !== 1 || nodes.firstElementChild === null)\r\n\t\t\t\treturn;\r\n\r\n\t\t\tif(nodes.sf$elementReferences !== void 0) return;\r\n\t\t\tDOMNodeRemoved(nodes);\r\n\t\t}\r\n\r\n\t\tif(typeof MutationObserver === 'function' && MutationObserver.prototype.observe){\r\n\t\t\tvar everyRecords = function(record){\r\n\t\t\t\trecord.removedNodes.forEach(everyRemovedNodes);\r\n\t\t\t}\r\n\r\n\t\t\tvar observer = new MutationObserver(function(records){\r\n\t\t\t\tif(!bindingEnabled) return;\r\n\t\t\t\trecords.forEach(everyRecords);\r\n\t\t\t});\r\n\r\n\t\t\tobserver.observe(document.body, { childList: true, subtree: true });\r\n\t\t}\r\n\t\telse {\r\n\t\t\tdocument.body.addEventListener('DOMNodeRemoved', function(e){\r\n\t\t\t\tif(!bindingEnabled) return;\r\n\t\t\t\teveryRemovedNodes(e.target);\r\n\t\t\t});\r\n\t\t}\r\n\t});\r\n\r\n\tvar removeModelBinding = self.reset = function(modelName){\r\n\t\tvar ref = self.root[modelName];\r\n\t\tif(ref === void 0)\r\n\t\t\treturn;\r\n\r\n\t\tvar bindedKey = ref.sf$bindedKey;\r\n\t\tvar temp = null;\r\n\t\tfor(var key in bindedKey){\r\n\t\t\tdelete bindedKey[key];\r\n\r\n\t\t\tif(ref[key] === void 0 || ref[key] === null)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tif(ref[key].constructor === String ||\r\n\t\t\t\tref[key].constructor === Number ||\r\n\t\t\t\tref[key].constructor === Boolean\r\n\t\t\t){/* Ok */}\r\n\r\n\t\t\telse if(ref[key].constructor === Array){\r\n\t\t\t\tif(ref[key].$virtual){\r\n\t\t\t\t\tref[key].$virtual.destroy();\r\n\t\t\t\t\tdelete ref[key].$virtual;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Reset property without copying the array\r\n\t\t\t\ttemp = ref[key].splice('obtain');\r\n\t\t\t\tdelete ref[key];\r\n\t\t\t\tref[key] = temp;\r\n\t\t\t}\r\n\t\t\telse continue;\r\n\r\n\t\t\tif(Object.getOwnPropertyDescriptor(ref, key) === void 0)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\t// Reconfigure / Remove property descriptor\r\n\t\t\tvar temp = ref[key];\r\n\t\t\tdelete ref[key];\r\n\t\t\tref[key] = temp;\r\n\t\t}\r\n\t}\r\n\r\n\tfunction modelToViewBinding(model, propertyName, callback, elementBind, type){\r\n\t\t// Enable multiple element binding\r\n\t\tif(model.sf$bindedKey === void 0)\r\n\t\t\tinitBindingInformation(model);\r\n\r\n\t\tif(model.sf$bindedKey[propertyName] !== void 0){\r\n\t\t\tvar ref = model.sf$bindedKey[propertyName];\r\n\t\t\tif(ref.indexOf(callback) === -1)\r\n\t\t\t\tref.push(callback);\r\n\r\n\t\t\tif(elementBind !== void 0){\r\n\t\t\t\tif(ref.input === void 0){\r\n\t\t\t\t\tref.input = [elementBind];\r\n\t\t\t\t\tref.input.type = type;\r\n\t\t\t\t}\r\n\t\t\t\telse ref.input.push(elementBind);\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmodel.sf$bindedKey[propertyName] = [callback];\r\n\r\n\t\tif(elementBind !== void 0){\r\n\t\t\tvar ref = model.sf$bindedKey[propertyName];\r\n\t\t\tref.input = [elementBind];\r\n\t\t\tref.input.type = type;\r\n\t\t}\r\n\r\n\t\t// Proxy property\r\n\t\tif(Object.getOwnPropertyDescriptor(model, propertyName).set !== void 0)\r\n\t\t\treturn;\r\n\r\n\t\tvar objValue = model[propertyName]; // Object value\r\n\t\tObject.defineProperty(model, propertyName, {\r\n\t\t\tenumerable: true,\r\n\t\t\tconfigurable: true,\r\n\t\t\tget:function(getAssigner){\r\n\t\t\t\treturn objValue;\r\n\t\t\t},\r\n\t\t\tset:function(val){\r\n\t\t\t\tif(objValue !== val){\r\n\t\t\t\t\tvar m2v = model['m2v$'+propertyName];\r\n\t\t\t\t\tvar out = inputBoundRunning === false ? model['out$'+propertyName] : void 0;\r\n\t\t\t\t\tvar callback = inputBoundRunning === false ? model['on$'+propertyName] : void 0;\r\n\r\n\t\t\t\t\tif(callback !== void 0 || m2v !== void 0 || out !== void 0){\r\n\t\t\t\t\t\tvar newValue1 = void 0; var newValue2 = void 0; var newValue3 = void 0;\r\n\t\t\t\t\t\ttry{\r\n\t\t\t\t\t\t\tif(m2v !== void 0)\r\n\t\t\t\t\t\t\t\tnewValue1 = m2v(objValue, val);\r\n\r\n\t\t\t\t\t\t\tif(out !== void 0)\r\n\t\t\t\t\t\t\t\tnewValue2 = out(objValue, val);\r\n\r\n\t\t\t\t\t\t\tif(callback !== void 0)\r\n\t\t\t\t\t\t\t\tnewValue3 = callback(objValue, val);\r\n\t\t\t\t\t\t}catch(e){console.error(e)}\r\n\r\n\t\t\t\t\t\tobjValue = (newValue3 !== void 0 ? newValue3 : \r\n\t\t\t\t\t\t\t(newValue2 !== void 0 ? newValue2 : \r\n\t\t\t\t\t\t\t(newValue1 !== void 0 ? newValue1 : val)\r\n\t\t\t\t\t\t));\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse objValue = val;\r\n\r\n\t\t\t\t\tvar ref = model.sf$bindedKey[propertyName];\r\n\t\t\t\t\tfor (var i = 0; i < ref.length; i++) {\r\n\t\t\t\t\t\tif(inputBoundRun === ref[i]){\r\n\t\t\t\t\t\t\tif(inputBoundRunning !== true) // Avoid multiple assigment\r\n\t\t\t\t\t\t\t\tref[i](model, propertyName, ref.input);\r\n\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tref[i]();\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tinputBoundRunning = false;\r\n\t\t\t\treturn objValue;\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\tvar dcBracket = /{{[^#][\\s\\S]*?}}/;\r\n\tself.bindElement = function(element){\r\n\t\tvar modelName = sf.controller.modelName(element);\r\n\t\tvar model = self.root[modelName];\r\n\t\tif(!model) return console.error(\"Model for \"+modelName+\" was not found while binding:\", element);\r\n\r\n\t\tvar data = self.extractPreprocess(element, null, modelName);\r\n\t\ttemplateParser(data, model, true);\r\n\t\tdelete data.addresses;\r\n\t\telement.parentNode.replaceChild(data.html, element);\r\n\t\telement = data.html;\r\n\r\n\t\tvar onChanges = function(){\r\n\t\t\tif(syntheticTemplate(element, data, void 0, model) === false)\r\n\t\t\t\t0; //No update\r\n\t\t};\r\n\r\n\t\tvar properties = data.modelRef_array;\r\n\t\tfor (var i = 0; i < properties.length; i++) {\r\n\t\t\tvar propertyName = properties[i][0];\r\n\r\n\t\t\tif(model[propertyName] === void 0)\r\n\t\t\t\tmodel[propertyName] = '';\r\n\r\n\t\t\tmodelToViewBinding(model, propertyName, onChanges);\r\n\t\t}\r\n\t}\r\n\r\n\tself.extractPreprocess = function(targetNode, mask, name){\r\n\t\t// Check if it's component\r\n\t\tvar tagName = targetNode.tagName.toLowerCase();\r\n\t\tif(sf.component.registered[tagName] !== void 0){\r\n\t\t\ttargetNode.parentNode.classList.add('sf-keyed-list');\r\n\t\t\ttargetNode.textContent = '';\r\n\t\t\ttargetNode.remove();\r\n\t\t\treturn targetNode;\r\n\t\t}\r\n\r\n\t\tvar copy = targetNode.outerHTML;\r\n\r\n\t\t// Mask the referenced item\r\n\t\tif(mask !== null)\r\n\t\t\tcopy = copy.split('#'+mask).join('_model_');\r\n\r\n\t\t// Extract data to be parsed\r\n\t\tcopy = uniqueDataParser(copy, null, mask, name, '#noEval');\r\n\t\tvar preParsed = copy[1];\r\n\t\tvar _content_ = copy[2];\r\n\t\tcopy = dataParser(copy[0], null, mask, name, '#noEval', preParsed);\r\n\r\n\t\tfunction findModelProperty(){\r\n\t\t\tif(mask === null){\r\n\t\t\t\t// Get model keys and sort by text length, make sure the longer one is from first index to avoid wrong match\r\n\t\t\t\tvar extract = RegExp('('+self.modelKeys(self.root[name]).sort(function(a, b){\r\n\t\t\t\t\treturn b.length - a.length\r\n\t\t\t\t}).join('|')+')', 'g');\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t\tvar extract = RegExp('\\\\b(?:_model_|'+mask+')\\\\.([a-zA-Z0-9.[\\'\\\\]]+)(?:$|[^\\'\\\\]])', 'g');\r\n\t\t\tvar found = {};\r\n\r\n\t\t\tfor (var i = 0; i < preParsed.length; i++) {\r\n\t\t\t\tvar current = preParsed[i];\r\n\r\n\t\t\t\t// Text or attribute\r\n\t\t\t\tif(current.type === 0){\r\n\t\t\t\t\tcurrent.data[0].split('\"').join(\"'\").replace(extract, function(full, match){\r\n\t\t\t\t\t\tmatch = match.replace(/\\['(.*?)'\\]/g, function(full_, match_){\r\n\t\t\t\t\t\t\treturn '.'+match_;\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\tif(found[match] === void 0) found[match] = [i];\r\n\t\t\t\t\t\telse if(found[match].indexOf(i) === -1)\r\n\t\t\t\t\t\t\tfound[match].push(i);\r\n\t\t\t\t\t});\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Dynamic data\r\n\t\t\t\tif(current.type === 1){\r\n\t\t\t\t\tvar checkList = current.if.join(';');\r\n\r\n\t\t\t\t\tif(current.elseValue !== null)\r\n\t\t\t\t\t\tcheckList += ';' + current.elseValue;\r\n\r\n\t\t\t\t\tfor (var a = 0; a < current.elseIf.length; a++) {\r\n\t\t\t\t\t\tcheckList += current.elseIf[a].join(';');\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse if(current.type === 2)\r\n\t\t\t\t\tvar checkList = current.data[0];\r\n\r\n\t\t\t\tcheckList = checkList.replace(/_result_ \\+= _content_\\.take\\(.*?, ([0-9]+)\\);/g, function(full, match){\r\n\t\t\t\t\treturn _content_[match];\r\n\t\t\t\t});\r\n\r\n\t\t\t\tcheckList.split('\"').join(\"'\").replace(extract, function(full, match){\r\n\t\t\t\t\tmatch = match.replace(/\\['(.*?)'\\]/g, function(full_, match_){\r\n\t\t\t\t\t\treturn '.'+match_;\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tif(found[match] === void 0) found[match] = [i];\r\n\t\t\t\t\telse if(found[match].indexOf(i) === -1)\r\n\t\t\t\t\t\tfound[match].push(i);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\treturn found;\r\n\t\t}\r\n\r\n\t\t// Build element and start addressing\r\n\t\tcopy = $.parseElement(copy)[0];\r\n\t\tvar nodes = self.queuePreprocess(copy, true).reverse();\r\n\t\tvar addressed = [];\r\n\r\n\t\tfunction addressAttributes(currentNode){\r\n\t\t\tvar attrs = currentNode.attributes;\r\n\t\t\tvar keys = [];\r\n\t\t\tvar indexes = 0;\r\n\t\t\tfor (var a = 0; a < attrs.length; a++) {\r\n\t\t\t\tvar found = attrs[a].value.split('{{%=');\r\n\t\t\t\tif(found.length !== 1){\r\n\t\t\t\t\tif(attrs[a].name[0] === ':'){\r\n\t\t\t\t\t\tvar key = {\r\n\t\t\t\t\t\t\tname:attrs[a].name.split(':').join(''),\r\n\t\t\t\t\t\t\tvalue:attrs[a].value\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t\tcurrentNode.removeAttribute(attrs[a].name);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse var key = {\r\n\t\t\t\t\t\tname:attrs[a].name,\r\n\t\t\t\t\t\tvalue:attrs[a].value\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\t\tindexes = [];\r\n\t\t\t\t\tfound = key.value.replace(/{{%=([0-9]+)/g, function(full, match){\r\n\t\t\t\t\t\tindexes.push(Number(match));\r\n\t\t\t\t\t\treturn '';\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tif(found === '' && indexes.length === 1)\r\n\t\t\t\t\t\tkey.direct = indexes[0];\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tkey.parse_index = indexes;\r\n\r\n\t\t\t\t\tkeys.push(key);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn keys;\r\n\t\t}\r\n\r\n\t\tvar currentElement = addressAttributes(copy);\r\n\t\tif(currentElement.length !== 0)\r\n\t\t\taddressed.push({\r\n\t\t\t\tnodeType:1,\r\n\t\t\t\taddress:[0],\r\n\t\t\t\tattributes:currentElement\r\n\t\t\t});\r\n\r\n\t\tfor (var i = 0; i < nodes.length; i++) {\r\n\t\t\tvar temp = {\r\n\t\t\t\tnodeType:nodes[i].nodeType\r\n\t\t\t};\r\n\r\n\t\t\tif(temp.nodeType === 1){ // Element\r\n\t\t\t\ttemp.attributes = addressAttributes(nodes[i]);\r\n\t\t\t\ttemp.address = $.getSelector(nodes[i], true);\r\n\t\t\t}\r\n\r\n\t\t\telse if(temp.nodeType === 3){ // Text node\r\n\t\t\t\tvar innerHTML = nodes[i].textContent;\r\n\t\t\t\tvar indexes = [];\r\n\r\n\t\t\t\tinnerHTML.replace(/{{%%=([0-9]+)/gm, function(full, match){\r\n\t\t\t\t\tindexes.push(Number(match));\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// Check for dynamic mode\r\n\t\t\t\tif(indexes.length !== 0){\r\n\t\t\t\t\tinnerHTML = innerHTML.split(/{{%%=[0-9]+/gm);\r\n\t\t\t\t\tfor (var a = 0; a < innerHTML.length; a++) {\r\n\t\t\t\t\t\tinnerHTML[a] = trimIndentation(innerHTML[a]).trim();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tnodes[i].textContent = innerHTML.shift();\r\n\r\n\t\t\t\t\tvar parent = nodes[i].parentNode;\r\n\t\t\t\t\tvar nextSibling = nodes[i].nextSibling;\r\n\r\n\t\t\t\t\t// Dynamic boundary start\r\n\t\t\t\t\tvar addressStart = null;\r\n\t\t\t\t\tif(indexes.length !== 0 && nodes[i].textContent.length !== 0)\r\n\t\t\t\t\t\taddressStart = $.getSelector(nodes[i], true);\r\n\t\t\t\t\telse if(nodes[i].previousSibling !== null)\r\n\t\t\t\t\t\taddressStart = $.getSelector(nodes[i].previousSibling, true);\r\n\r\n\t\t\t\t\t// Find boundary ends\r\n\t\t\t\t\tvar commentFlag = [];\r\n\t\t\t\t\tfor(var a = 0; a < indexes.length; a++){\r\n\t\t\t\t\t\tvar flag = document.createComment('');\r\n\t\t\t\t\t\tparent.insertBefore(flag, nextSibling);\r\n\t\t\t\t\t\tcommentFlag.push({\r\n\t\t\t\t\t\t\tnodeType:-1,\r\n\t\t\t\t\t\t\tparse_index:indexes[a],\r\n\t\t\t\t\t\t\tstartFlag:addressStart,\r\n\t\t\t\t\t\t\taddress:$.getSelector(flag, true)\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\tif(innerHTML[a]){\r\n\t\t\t\t\t\t\tvar textNode = document.createTextNode(innerHTML[a]);\r\n\t\t\t\t\t\t\tparent.insertBefore(textNode, nextSibling);\r\n\r\n\t\t\t\t\t\t\t// Get new start flag\r\n\t\t\t\t\t\t\tif(a + 1 < indexes.length)\r\n\t\t\t\t\t\t\t\taddressStart = $.getSelector(textNode, true);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Merge boundary address\r\n\t\t\t\t\tArray.prototype.push.apply(addressed, commentFlag);\r\n\t\t\t\t\tif(nodes[i].textContent === ''){\r\n\t\t\t\t\t\tnodes[i].remove();\r\n\t\t\t\t\t\tfor (var a = 0; a < commentFlag.length; a++) {\r\n\t\t\t\t\t\t\tvar ref = commentFlag[a].address;\r\n\t\t\t\t\t\t\tref[ref.length - 1]--;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse if(nodes[i].textContent.search(/{{%=[0-9]+/) === -1)\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Check if it's only model value\r\n\t\t\t\tindexes = [];\r\n\t\t\t\tinnerHTML = nodes[i].textContent.replace(/{{%=([0-9]+)/gm, function(full, match){\r\n\t\t\t\t\tindexes.push(Number(match));\r\n\t\t\t\t\treturn '';\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif(innerHTML === '' && indexes.length === 1)\r\n\t\t\t\t\ttemp.direct = indexes[0];\r\n\t\t\t\telse{\r\n\t\t\t\t\ttemp.value = nodes[i].textContent;\r\n\t\t\t\t\ttemp.parse_index = indexes;\r\n\t\t\t\t}\r\n\r\n\t\t\t\ttemp.address = $.getSelector(nodes[i], true);\r\n\t\t\t}\r\n\r\n\t\t\taddressed.push(temp);\r\n\t\t}\r\n\r\n\t\tvar modelReference = findModelProperty();\r\n\t\tvar keys = Object.keys(modelReference);\r\n\t\tvar asArray = [];\r\n\t\tfor (var i = 0; i < keys.length; i++) {\r\n\t\t\tasArray.push([keys[i], keys[i].split('.')]);\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\thtml:copy,\r\n\t\t\tparse:preParsed,\r\n\t\t\taddresses:addressed,\r\n\t\t\tmodelReference:modelReference,\r\n\t\t\tmodelRef_array:asArray\r\n\t\t};\r\n\t}\r\n\r\n\tvar enclosedHTMLParse = false;\r\n\tvar excludes = ['HTML','HEAD','STYLE','LINK','META','SCRIPT','OBJECT','IFRAME'];\r\n\tself.queuePreprocess = function(targetNode, extracting){\r\n\t\tvar childNodes = (targetNode || document.body).childNodes;\r\n\r\n\t\tvar temp = [];\r\n\t\tfor (var i = childNodes.length - 1; i >= 0; i--) {\r\n\t\t\tvar currentNode = childNodes[i];\r\n\r\n\t\t\tif(extracting === void 0 && excludes.indexOf(currentNode.nodeName) !== -1)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tif(currentNode.nodeType === 1){ // Tag\r\n\t\t\t\tif(enclosedHTMLParse === true) continue;\r\n\t\t\t\tvar attrs = currentNode.attributes;\r\n\r\n\t\t\t\t// Skip element and it's childs that already bound to prevent vulnerability\r\n\t\t\t\tif(attrs['sf-bind-key'] || attrs['sf-repeat-this'] || attrs['sf-bind-list']) continue;\r\n\r\n\t\t\t\tfor (var a = 0; a < attrs.length; a++) {\r\n\t\t\t\t\tif(attrs[a].value.indexOf('{{') !== -1){\r\n\t\t\t\t\t\ttemp.push(currentNode);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tArray.prototype.push.apply(temp, self.queuePreprocess(currentNode, extracting));\r\n\t\t\t}\r\n\r\n\t\t\telse if(currentNode.nodeType === 3){ // Text\r\n\t\t\t\tif(currentNode.textContent.length === 0){\r\n\t\t\t\t\tcurrentNode.remove();\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// The scan is from bottom to first index\r\n\t\t\t\tvar enclosing = currentNode.textContent.indexOf('{[');\r\n\t\t\t\tif(enclosing !== -1)\r\n\t\t\t\t\tenclosedHTMLParse = false;\r\n\t\t\t\telse if(enclosedHTMLParse === true)\r\n\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\t// Start enclosed if closing pattern was found\r\n\t\t\t\tvar enclosed = currentNode.textContent.indexOf(']}');\r\n\t\t\t\tif(enclosed !== -1 && (enclosing === -1 || enclosing > enclosed)){ // avoid {[ ... ]}\r\n\t\t\t\t\tenclosedHTMLParse = true; // when ]} ... \r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(currentNode.nodeValue.indexOf('{{') !== -1){\r\n\t\t\t\t\tif(extracting === void 0){\r\n\t\t\t\t\t\ttemp.push(currentNode.parentNode);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\ttemp.push(currentNode);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn temp;\r\n\t}\r\n\r\n\tself.parsePreprocess = function(nodes, queued){\r\n\t\tfor (var a = 0; a < nodes.length; a++) {\r\n\t\t\t// Get reference for debugging\r\n\t\t\tvar current = processingElement = nodes[a];\r\n\r\n\t\t\tvar modelElement = sf.controller.modelElement(current);\r\n\t\t\tif(modelElement === null)\r\n\t\t\t\tcontinue;\r\n\r\n\t\t\tvar model = modelElement.sf$component === void 0 ? modelElement.getAttribute('sf-controller') : modelElement.sf$component;\r\n\r\n\t\t\tif(queued !== void 0)\r\n\t\t\t\tcurrent.classList.remove('sf-dom-queued');\r\n\r\n\t\t\t// Check if it's component\r\n\t\t\tif(self.root[model] === void 0 && sf.component.registered[model])\r\n\t\t\t\tmodel = sf.component.new(model, modelElement);\r\n\r\n\t\t\tvar modelRef = self.root[model] || root_(model);\r\n\r\n\t\t\t// Double check if the child element already bound to prevent vulnerability\r\n\t\t\tif(/sf-bind-key|sf-bind-list/.test(current.innerHTML)){\r\n\t\t\t\tconsole.error(\"Can't parse element that already bound\");\r\n\t\t\t\tconsole.log(processingElement.cloneNode(true));\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif(current.hasAttribute('sf-bind-ignore') === false)\r\n\t\t\t\tself.bindElement(current);\r\n\t\t\telse{\r\n\t\t\t\tvar temp = uniqueDataParser(current.innerHTML, modelRef, false, model);\r\n\t\t\t\tcurrent.innerHTML = dataParser(temp, modelRef, false, model);\r\n\t\t\t\tvar attrs = current.attributes;\r\n\t\t\t\tfor (var i = 0; i < attrs.length; i++) {\r\n\t\t\t\t\tif(attrs[i].value.indexOf('{{') !== -1){\r\n\t\t\t\t\t\tvar attr = attrs[i];\r\n\t\t\t\t\t\tattr.value = dataParser(attr.value, modelRef, false, model);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tfunction initBindingInformation(modelRef){\r\n\t\tif(modelRef.sf$bindedKey !== void 0)\r\n\t\t\treturn;\r\n\r\n\t\t// Element binding data\r\n\t\tObject.defineProperty(modelRef, 'sf$bindedKey', {\r\n\t\t\tconfigurable: true,\r\n\t\t\tenumerable:false,\r\n\t\t\twritable:true,\r\n\t\t\tvalue:{}\r\n\t\t});\r\n\t}\r\n})();","// DOM Controller on loaded app\r\nsf.controller = new function(){\r\n\tvar self = this;\r\n\tself.pending = {};\r\n\tself.active = {};\r\n\r\n\tself.for = function(name, func){\r\n\t\tif(sf.component.registered[name]){\r\n\t\t\tsf.component.registered[name][1] = func;\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tself.pending[name] = func;\r\n\t}\r\n\r\n\tself.modelScope = function(element, func){\r\n\t\tvar model = sf.controller.modelName(element);\r\n\r\n\t\tif(!model)\r\n\t\t\tthrow 'model or controller was not found';\r\n\r\n\t\tvar bindedList = element.getAttribute('sf-bind-list');\r\n\t\tif(!bindedList){\r\n\t\t\tvar parentEl = $.parent(element, '[sf-bind-list]');\r\n\t\t\tif(parentEl !== null)\r\n\t\t\t\tbindedList = parentEl.getAttribute('sf-bind-list');\r\n\t\t}\r\n\t\telse var parentEl = element;\r\n\r\n\t\tif(!bindedList){\r\n\t\t\tif(func) return func(sf.model.root[model], -1);\r\n\t\t\telse return sf.model.root[model];\r\n\t\t}\r\n\r\n\t\t// Find index\r\n\t\tvar bindedListIndex = 0;\r\n\t\tif(bindedList)\r\n\t\t\tbindedListIndex = $.prevAll(parentEl, '[sf-bind-list]').length;\r\n\r\n\t\tif(func) return func(sf.model.root[model][bindedList], bindedListIndex);\r\n\t\telse return sf.model.root[model][bindedList][bindedListIndex];\r\n\t}\r\n\r\n\tself.modelElement = function(element){\r\n\t\tif(element.nodeType === 1 && element.hasAttribute('sf-controller') === true)\r\n\t\t\treturn element;\r\n\r\n\t\treturn $.parent(element, '[sf-controller]');\r\n\t}\r\n\r\n\tself.modelName = function(element){\r\n\t\tvar name = self.modelElement(element);\r\n\t\tif(name === null){\r\n\t\t\tconsole.error(\"Can't find any controller for\", element);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tname = name.sf$component === void 0? name.getAttribute('sf-controller') : name.sf$component;\r\n\r\n\t\t// Initialize it first\r\n\t\tif(name !== void 0 && !self.active[name])\r\n\t\t\tself.run(name);\r\n\r\n\t\treturn name;\r\n\t}\r\n\r\n\tvar listenSFClick = function(e){\r\n\t\tvar element = e.target;\r\n\t\tvar script = element.getAttribute('sf-click');\r\n\r\n\t\tif(!script){\r\n\t\t\telement = $.parent(element, '[sf-click]');\r\n\t\t\tscript = element.getAttribute('sf-click');\r\n\t\t}\r\n\r\n\t\tvar model = $.parent(element, '[sf-controller]');\r\n\t\tmodel = model.sf$component === void 0 ? model.getAttribute('sf-controller') : model;\r\n\t\tvar _modelScope = sf.model.root[model];\r\n\r\n\t\tif(_modelScope === void 0)\r\n\t\t\tthrow \"Couldn't find model for \"+model+\" that was called from sf-click\";\r\n\r\n\t\tvar modelKeys = sf.model.modelKeys(_modelScope).join('|');\r\n\t\tscript = avoidQuotes(script, function(script_){\r\n\t\t\treturn script_.replace(RegExp(sf.regex.strictVar+'('+modelKeys+')\\\\b', 'g'), function(full, matched){\r\n\t\t\t\treturn '_modelScope.'+matched;\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tscript = script.split('(');\r\n\r\n\t\tvar method = script[0];\r\n\t\tvar method_ = method;\r\n\r\n\t\t// Get method reference\r\n\t\ttry{\r\n\t\t\tmethod = eval(method);\r\n\t\t} catch(e) {\r\n\t\t\tmethod = false;\r\n\t\t}\r\n\r\n\t\tif(!method){\r\n\t\t\tconsole.error(\"Error on sf-click for model: \" + model + ' [Cannot call `'+method_+'`]\\n', element);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Take the argument list\r\n\t\tscript.shift();\r\n\t\tscript = script.join('(');\r\n\t\tscript = script.split(')');\r\n\t\tscript.pop();\r\n\t\tscript = script.join('(');\r\n\r\n\t\t// Turn argument as array\r\n\t\tif(script.length !== 0){\r\n\t\t\t// Replace `this` to `element`\r\n\t\t\tscript = eval(('['+script+']').replace(/,this|\\[this/g, function(found){\r\n\t\t\t\treturn found[0] + 'element';\r\n\t\t\t}));\r\n\t\t}\r\n\t\tif(!script)\r\n\t\t\tscript = [];\r\n\r\n\t\ttry{\r\n\t\t\tmethod.apply(element, script);\r\n\t\t\te.preventDefault();\r\n\t\t} catch(e) {\r\n\t\t\tconsole.error(\"Error on sf-click for model: \" + model + '\\n', element, '\\n', e);\r\n\t\t}\r\n\t}\r\n\r\n\tself.run = function(name, func){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.run(name, func);\r\n\t\t\t});\r\n\r\n\t\tif(sf.component.registered[name])\r\n\t\t\treturn console.error(\"'\"+name+\"' is registered as a component\");\r\n\r\n\t\tif(self.pending[name]){\r\n\t\t\tif(!sf.model.root[name])\r\n\t\t\t\tsf.model.root[name] = {};\r\n\r\n\t\t\tself.pending[name](sf.model.root[name], root_);\r\n\t\t\tself.active[name] = true;\r\n\t\t\tdelete self.pending[name];\r\n\t\t}\r\n\r\n\t\tif(sf.model.root[name] === void 0)\r\n\t\t\tsf.model.root[name] = {};\r\n\r\n\t\tif(func)\r\n\t\t\tfunc(sf.model.root[name], root_);\r\n\t}\r\n\r\n\tself.init = function(parent){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.init(name);\r\n\t\t\t});\r\n\r\n\t\tvar temp = $('[sf-controller]', parent || document.body);\r\n\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\tself.run(temp[i].sf$component === void 0? temp[i].getAttribute('sf-controller') : temp[i].sf$component);\r\n\t\t}\r\n\t}\r\n\r\n\t// Create listener for sf-click\r\n\tdocument.addEventListener('DOMContentLoaded', function(){\r\n\t\t$.on(document.body, 'click', '[sf-click]', listenSFClick);\r\n\t}, {capture:true, once:true});\r\n}\r\n\r\nvar root_ = function(scope){\r\n\tif(sf.component.registered[scope]){\r\n\t\tvar available = [];\r\n\t\tvar component = sf.component.available[scope];\r\n\t\tif(component !== void 0){\r\n\t\t\tfor (var i = 0; i < component.length; i++) {\r\n\t\t\t\tavailable.push(sf.model.root[component[i]]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn available;\r\n\t}\r\n\r\n\tif(!sf.model.root[scope])\r\n\t\tsf.model.root[scope] = {};\r\n\r\n\treturn sf.model.root[scope];\r\n}","/*\r\n Special Thanks to Vladimir Kharlampidi\r\n https://github.com/nolimits4web/\r\n*/\r\n\r\nvar globals = {};\r\nvar jsonpRequests = 0;\r\nfunction Request(requestOptions) {\r\n var globalsNoCallbacks = Object.assign({}, globals);\r\n ('beforeCreate beforeOpen beforeSend error complete success statusCode').split(' ').forEach(function (callbackName) {\r\n delete globalsNoCallbacks[callbackName];\r\n });\r\n var defaults = Object.assign({\r\n url: window.location.toString(),\r\n method: 'GET',\r\n data: false,\r\n async: true,\r\n cache: true,\r\n user: '',\r\n password: '',\r\n headers: {},\r\n xhrFields: {},\r\n statusCode: {},\r\n processData: true,\r\n dataType: 'text',\r\n contentType: 'application/x-www-form-urlencoded',\r\n timeout: 0,\r\n }, globalsNoCallbacks);\r\n var options = Object.assign({}, defaults, requestOptions);\r\n var proceedRequest;\r\n // Function to run XHR callbacks and events\r\n function fireCallback(callbackName) {\r\n var data = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n data[_i - 1] = arguments[_i];\r\n }\r\n /*\r\n Callbacks:\r\n beforeCreate (options),\r\n beforeOpen (xhr, options),\r\n beforeSend (xhr, options),\r\n error (xhr, status),\r\n complete (xhr, stautus),\r\n success (response, status, xhr),\r\n statusCode ()\r\n */\r\n var globalCallbackValue;\r\n var optionCallbackValue;\r\n if (globals[callbackName]) {\r\n globalCallbackValue = globals[callbackName].apply(globals, data);\r\n }\r\n if (options[callbackName]) {\r\n optionCallbackValue = options[callbackName].apply(options, data);\r\n }\r\n if (typeof globalCallbackValue !== 'boolean')\r\n globalCallbackValue = true;\r\n if (typeof optionCallbackValue !== 'boolean')\r\n optionCallbackValue = true;\r\n return (globalCallbackValue && optionCallbackValue);\r\n }\r\n // Before create callback\r\n proceedRequest = fireCallback('beforeCreate', options);\r\n if (proceedRequest === false)\r\n return void 0;\r\n // For jQuery guys\r\n if (options.type)\r\n options.method = options.type;\r\n // Parameters Prefix\r\n var paramsPrefix = options.url.indexOf('?') >= 0 ? '&' : '?';\r\n // UC method\r\n var method = options.method.toUpperCase();\r\n // Data to modify GET URL\r\n if ((method === 'GET' || method === 'HEAD' || method === 'OPTIONS' || method === 'DELETE') && options.data) {\r\n var stringData = void 0;\r\n if (typeof options.data === 'string') {\r\n // Should be key=value string\r\n if (options.data.indexOf('?') >= 0)\r\n stringData = options.data.split('?')[1];\r\n else\r\n stringData = options.data;\r\n }\r\n else {\r\n // Should be key=value object\r\n stringData = serializeQuery(options.data);\r\n }\r\n if (stringData.length) {\r\n options.url += paramsPrefix + stringData;\r\n if (paramsPrefix === '?')\r\n paramsPrefix = '&';\r\n }\r\n }\r\n // JSONP\r\n if (options.dataType === 'json' && options.url.indexOf('callback=') >= 0) {\r\n var callbackName_1 = \"jsonp_\" + (Date.now() + ((jsonpRequests += 1)));\r\n var abortTimeout_1;\r\n var callbackSplit = options.url.split('callback=');\r\n var requestUrl = callbackSplit[0] + \"callback=\" + callbackName_1;\r\n if (callbackSplit[1].indexOf('&') >= 0) {\r\n var addVars = callbackSplit[1].split('&').filter(function (el) { return el.indexOf('=') > 0; }).join('&');\r\n if (addVars.length > 0)\r\n requestUrl += \"&\" + addVars;\r\n }\r\n // Create script\r\n var script_1 = document.createElement('script');\r\n script_1.type = 'text/javascript';\r\n script_1.onerror = function onerror() {\r\n clearTimeout(abortTimeout_1);\r\n fireCallback('error', null, 'scripterror');\r\n fireCallback('complete', null, 'scripterror');\r\n };\r\n script_1.src = requestUrl;\r\n // Handler\r\n window[callbackName_1] = function jsonpCallback(data) {\r\n clearTimeout(abortTimeout_1);\r\n fireCallback('success', data);\r\n script_1.parentNode.removeChild(script_1);\r\n script_1 = null;\r\n delete window[callbackName_1];\r\n };\r\n document.querySelector('head').appendChild(script_1);\r\n if (options.timeout > 0) {\r\n abortTimeout_1 = setTimeout(function () {\r\n script_1.parentNode.removeChild(script_1);\r\n script_1 = null;\r\n fireCallback('error', null, 'timeout');\r\n }, options.timeout);\r\n }\r\n return void 0;\r\n }\r\n // Cache for GET/HEAD requests\r\n if (method === 'GET' || method === 'HEAD' || method === 'OPTIONS' || method === 'DELETE') {\r\n if (options.cache === false) {\r\n options.url += paramsPrefix + \"_nocache\" + Date.now();\r\n }\r\n }\r\n // Create XHR\r\n var xhr = new XMLHttpRequest();\r\n // Save Request URL\r\n xhr.requestUrl = options.url;\r\n xhr.requestParameters = options;\r\n // Before open callback\r\n proceedRequest = fireCallback('beforeOpen', xhr, options);\r\n if (proceedRequest === false)\r\n return xhr;\r\n // Open XHR\r\n xhr.open(method, options.url, options.async, options.user, options.password);\r\n // Create POST Data\r\n var postData = null;\r\n if ((method === 'POST' || method === 'PUT' || method === 'PATCH') && options.data) {\r\n if (options.processData) {\r\n var postDataInstances = [ArrayBuffer, Blob, Document, FormData];\r\n // Post Data\r\n if (postDataInstances.indexOf(options.data.constructor) >= 0) {\r\n postData = options.data;\r\n }\r\n else {\r\n // POST Headers\r\n var boundary = \"---------------------------\" + Date.now().toString(16);\r\n if (options.contentType === 'multipart/form-data') {\r\n xhr.setRequestHeader('Content-Type', \"multipart/form-data; boundary=\" + boundary);\r\n }\r\n else {\r\n xhr.setRequestHeader('Content-Type', options.contentType);\r\n }\r\n postData = '';\r\n var data = serializeQuery(options.data);\r\n if (options.contentType === 'multipart/form-data') {\r\n data = data.split('&');\r\n var newData = [];\r\n for (var i = 0; i < data.length; i += 1) {\r\n newData.push(\"Content-Disposition: form-data; name=\\\"\" + data[i].split('=')[0] + \"\\\"\\r\\n\\r\\n\" + data[i].split('=')[1] + \"\\r\\n\");\r\n }\r\n postData = \"--\" + boundary + \"\\r\\n\" + newData.join(\"--\" + boundary + \"\\r\\n\") + \"--\" + boundary + \"--\\r\\n\";\r\n }\r\n else if (options.contentType === 'application/json') {\r\n postData = JSON.stringify(options.data);\r\n }\r\n else {\r\n postData = data;\r\n }\r\n }\r\n }\r\n else {\r\n postData = options.data;\r\n xhr.setRequestHeader('Content-Type', options.contentType);\r\n }\r\n }\r\n // Additional headers\r\n if (options.headers) {\r\n Object.keys(options.headers).forEach(function (headerName) {\r\n xhr.setRequestHeader(headerName, options.headers[headerName]);\r\n });\r\n }\r\n // Check for crossDomain\r\n if (typeof options.crossDomain === 'void 0') {\r\n // eslint-disable-next-line\r\n options.crossDomain = /^([\\w-]+:)?\\/\\/([^\\/]+)/.test(options.url) && RegExp.$2 !== window.location.host;\r\n }\r\n if (!options.crossDomain) {\r\n xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\r\n }\r\n if (options.xhrFields) {\r\n Object.assign(xhr, options.xhrFields);\r\n }\r\n var xhrTimeout;\r\n // Handle XHR\r\n xhr.onload = function onload() {\r\n if (xhrTimeout)\r\n clearTimeout(xhrTimeout);\r\n if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {\r\n var responseData = void 0;\r\n if (options.dataType === 'json') {\r\n var parseError = void 0;\r\n try {\r\n responseData = JSON.parse(xhr.responseText);\r\n }\r\n catch (err) {\r\n parseError = true;\r\n }\r\n if (!parseError) {\r\n fireCallback('success', responseData, xhr.status, xhr);\r\n }\r\n else {\r\n fireCallback('error', xhr, 'parseerror');\r\n }\r\n }\r\n else {\r\n responseData = xhr.responseType === 'text' || xhr.responseType === '' ? xhr.responseText : xhr.response;\r\n fireCallback('success', responseData, xhr.status, xhr);\r\n }\r\n }\r\n else {\r\n fireCallback('error', xhr, xhr.status);\r\n }\r\n if (options.statusCode) {\r\n if (globals.statusCode && globals.statusCode[xhr.status])\r\n globals.statusCode[xhr.status](xhr);\r\n if (options.statusCode[xhr.status])\r\n options.statusCode[xhr.status](xhr);\r\n }\r\n fireCallback('complete', xhr, xhr.status);\r\n };\r\n xhr.onerror = function onerror() {\r\n if (xhrTimeout)\r\n clearTimeout(xhrTimeout);\r\n fireCallback('error', xhr, xhr.status);\r\n fireCallback('complete', xhr, 'error');\r\n };\r\n // Timeout\r\n if (options.timeout > 0) {\r\n xhr.onabort = function onabort() {\r\n if (xhrTimeout)\r\n clearTimeout(xhrTimeout);\r\n };\r\n xhrTimeout = setTimeout(function () {\r\n xhr.abort();\r\n fireCallback('error', xhr, 'timeout');\r\n fireCallback('complete', xhr, 'timeout');\r\n }, options.timeout);\r\n }\r\n // Ajax start callback\r\n proceedRequest = fireCallback('beforeSend', xhr, options);\r\n if (proceedRequest === false)\r\n return xhr;\r\n // Send XHR\r\n xhr.send(postData);\r\n // Return XHR object\r\n return xhr;\r\n}\r\nfunction RequestShortcut(method) {\r\n var args = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n args[_i - 1] = arguments[_i];\r\n }\r\n var _a = [], url = _a[0], data = _a[1], success = _a[2], error = _a[3], dataType = _a[4];\r\n if (typeof args[1] === 'function') {\r\n url = args[0], success = args[1], error = args[2], dataType = args[3];\r\n }\r\n else {\r\n url = args[0], data = args[1], success = args[2], error = args[3], dataType = args[4];\r\n }\r\n [success, error].forEach(function (callback) {\r\n if (typeof callback === 'string') {\r\n dataType = callback;\r\n if (callback === success)\r\n success = void 0;\r\n else\r\n error = void 0;\r\n }\r\n });\r\n dataType = dataType || (method === 'json' || method === 'postJSON' ? 'json' : void 0);\r\n var requestOptions = {\r\n url: url,\r\n method: method === 'post' || method === 'postJSON' ? 'POST' : 'GET',\r\n data: data,\r\n success: success,\r\n error: error,\r\n dataType: dataType,\r\n };\r\n if (method === 'postJSON') {\r\n Object.assign(requestOptions, {\r\n contentType: 'application/json',\r\n processData: false,\r\n crossDomain: true,\r\n data: typeof data === 'string' ? data : JSON.stringify(data),\r\n });\r\n }\r\n return Request(requestOptions);\r\n}\r\nObject.assign(Request, {\r\n get: function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n return RequestShortcut.apply(void 0, ['get'].concat(args));\r\n },\r\n post: function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n return RequestShortcut.apply(void 0, ['post'].concat(args));\r\n },\r\n json: function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n return RequestShortcut.apply(void 0, ['json'].concat(args));\r\n },\r\n getJSON: function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n return RequestShortcut.apply(void 0, ['json'].concat(args));\r\n },\r\n postJSON: function () {\r\n var args = [];\r\n for (var _i = 0; _i < arguments.length; _i++) {\r\n args[_i] = arguments[_i];\r\n }\r\n return RequestShortcut.apply(void 0, ['postJSON'].concat(args));\r\n },\r\n});\r\nRequest.setup = function setup(options) {\r\n if (options.type && !options.method) {\r\n Object.assign(options, { method: options.type });\r\n }\r\n Object.assign(globals, options);\r\n};\r\nfunction serializeQuery(params, prefix) {\r\n var key = Object.keys(params);\r\n for (var i = 0; i < key.length; i++) {\r\n var value = params[key[i]];\r\n if (params.constructor === Array)\r\n key[i] += prefix + \"[]\";\r\n else if (params.constructor === Object)\r\n key[i] = (prefix ? prefix + \"[\" + key[i] + \"]\" : key[i]);\r\n\r\n if (typeof value === 'object')\r\n key[i] = serializeQuery(value, key[i]);\r\n else\r\n key[i] = key[i] + \"=\" + encodeURIComponent(value);\r\n }\r\n return key.join('&');\r\n}\r\n$.ajax = sf.ajax = Request;","return sf;\r\n\r\n// ===== Module End =====\r\n})));","sf.router = new function(){\r\n\tvar self = this;\r\n\tself.loading = false;\r\n\tself.enabled = false;\r\n\tself.pauseRenderOnTransition = false;\r\n\tself.currentPage = [];\r\n\tvar initialized = false;\r\n\tvar lazyRouting = false;\r\n\tvar currentRouterURL = '';\r\n\r\n\t// Should be called if not using lazy page load\r\n\tself.init = function(targetNode){\r\n\t\tif(!sf.loader.DOMWasLoaded)\r\n\t\t\treturn sf(function(){\r\n\t\t\t\tself.init();\r\n\t\t\t});\r\n\r\n\t\t// Run 'before' event for new page view\r\n\t\tvar temp = $('[sf-controller], [sf-page]', targetNode);\r\n\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\tif(temp[i].hasAttribute('sf-controller') === true)\r\n\t\t\t\tsf.controller.run(temp[i].getAttribute('sf-controller'));\r\n\t\t\t\r\n\t\t\tif(temp[i].getAttribute('sf-page')){\r\n\t\t\t\tvar name = temp[i].getAttribute('sf-page');\r\n\t\t\t\tbeforeEvent(name);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tinitialized = true;\r\n\t\tcurrentRouterURL = window.location.pathname;\r\n\t}\r\n\r\n\tfunction popstateListener(event) {\r\n\t\t// Don't continue if the last routing was error\r\n\t\tif(routingError){\r\n\t\t\troutingError = false;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\troutingBack = true;\r\n\t\tself.goto(window.location.pathname);\r\n\t}\r\n\r\n\tself.enable = function(status){\r\n\t\tif(status === void 0) status = true;\r\n\t\tif(self.enabled === status) return;\r\n\t\tself.enabled = status;\r\n\r\n\t\tif(status === true){\r\n\t\t\t// Create listener for link click\r\n\t\t\t$.on(document.body, 'click', 'a[href]', self.load);\r\n\r\n\t\t\t// Create listener when navigate backward\r\n\t\t\twindow.addEventListener('popstate', popstateListener, false);\r\n\t\t}\r\n\t\telse{\r\n\t\t\t$.off(document.body, 'click', 'a[href]', self.load);\r\n\t\t\twindow.removeEventListener('popstate', popstateListener, false);\r\n\t\t}\r\n\t}\r\n\r\n\tvar before = {};\r\n\t// Set index with number if you want to replace old function\r\n\tself.before = function(name, func, index){\r\n\t\tif(!before[name])\r\n\t\t\tbefore[name] = [];\r\n\r\n\t\tif(index === void 0){\r\n\t\t\tif(before[name].indexOf(func) === -1)\r\n\t\t\t\tbefore[name].push(func);\r\n\t\t}\r\n\t\telse\r\n\t\t\tbefore[name][index] = func;\r\n\t}\r\n\r\n\tvar after = {};\r\n\t// Set index with number if you want to replace old function\r\n\tself.after = function(name, func, index){\r\n\t\tif(!after[name])\r\n\t\t\tafter[name] = [];\r\n\r\n\t\tif(index === void 0){\r\n\t\t\tif(after[name].indexOf(func) === -1)\r\n\t\t\t\tafter[name].push(func);\r\n\t\t}\r\n\t\telse\r\n\t\t\tafter[name][index] = func;\r\n\t}\r\n\r\n\t// Running 'before' new page going to be displayed\r\n\tvar beforeEvent = function(name){\r\n\t\tif(self.currentPage.indexOf(name) === -1)\r\n\t\t\tself.currentPage.push(name);\r\n\r\n\t\tif(before[name]){\r\n\t\t\tfor (var i = 0; i < before[name].length; i++) {\r\n\t\t\t\tbefore[name][i](sf.model);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Running 'after' old page going to be removed\r\n\tvar afterEvent = function(name){\r\n\t\tif(self.currentPage.indexOf(name) === -1)\r\n\t\t\tself.currentPage.splice(self.currentPage.indexOf(name), 1);\r\n\r\n\t\tif(after[name]){\r\n\t\t\tfor (var i = 0; i < after[name].length; i++) {\r\n\t\t\t\tafter[name][i](sf.model);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tvar onEvent = {\r\n\t\t'loading':[],\r\n\t\t'loaded':[],\r\n\t\t'special':[],\r\n\t\t'error':[]\r\n\t};\r\n\tself.on = function(event, func){\r\n\t\tif(onEvent[event].indexOf(func) === -1)\r\n\t\t\tonEvent[event].push(func);\r\n\t}\r\n\r\n\tself.lazyViewPoint = {};\r\n\t/*\r\n\t\t{\r\n\t\t\toldURlPattern:{\r\n\t\t\t\tnewURLPattern:'.viewPoint'\r\n\t\t\t}\r\n\t\t}\r\n\t*/\r\n\r\n\tself.load = function(ev){\r\n\t\tif(self.enabled !== true) return;\r\n\r\n\t\tvar elem = ev.target;\r\n\t\tif(!elem.href) return;\r\n\r\n\t\tif(!history.pushState || elem.hasAttribute('sf-router-ignore'))\r\n\t\t\treturn;\r\n\r\n\t\t// Make sure it's from current origin\r\n\t\tvar path = elem.href.replace(window.location.origin, '');\r\n\t\tif(path.indexOf('//') !== -1)\r\n\t\t\treturn;\r\n\r\n\t\tev.preventDefault()\r\n\t\treturn !self.goto(path);\r\n\t}\r\n\r\n\tvar RouterLoading = false;\r\n\tvar routingBack = false;\r\n\tvar routingError = false;\r\n\tself.goto = function(path, data, method){\r\n\t\tif(!method) method = 'GET';\r\n else method = method.toUpperCase();\r\n\r\n\t\tif(!data) data = {};\r\n\r\n\t\tfor (var i = 0; i < onEvent['loading'].length; i++) {\r\n\t\t\tif(onEvent['loading'][i](path)) return;\r\n\t\t}\r\n\t\tvar oldPath = window.location.pathname;\r\n\t\tinitialized = false;\r\n\r\n\t\tif(RouterLoading) RouterLoading.abort();\r\n\t\tRouterLoading = $.ajax({\r\n\t\t\turl:window.location.origin + path,\r\n\t\t\tmethod:method,\r\n data:Object.assign(data, {\r\n _scarlets:'.dynamic.'\r\n }),\r\n\t\t\tsuccess:function(data){\r\n\t\t\t\tif(initialized) return;\r\n\t\t\t\tlazyRouting = true;\r\n\r\n\t\t\t\t// Run 'loaded' event\r\n\t\t\t\tRouterLoading = false;\r\n\r\n\t\t\t\t// Find special data\r\n\t\t\t\tvar regex = RegExp('', 'gm');\r\n\t\t\t\tvar special = regex.exec(data);\r\n\t\t\t\tif(special && special.length !== 1){\r\n\t\t\t\t\tspecial = special[1].split('--|&>').join('-->');\r\n\t\t\t\t\tspecial = JSON.parse(special);\r\n\r\n\t\t\t\t\tif(!isEmptyObject(special)){\r\n\t\t\t\t\t\tfor (var i = 0; i < onEvent['special'].length; i++) {\r\n\t\t\t\t\t\t\tif(onEvent['special'][i](special)) return;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar DOMReference = false;\r\n\t\t\t\tvar foundAction = function(ref){\r\n\t\t\t\t\tDOMReference = $.findOne(ref);\r\n\r\n\t\t\t\t\t// Run 'after' event for old page view\r\n\t\t\t\t\tvar last = $.findOne('[sf-page]', DOMReference);\r\n\t\t\t\t\tafterEvent(last ? last.getAttribute('sf-page') : '/');\r\n\r\n\t\t\t\t\t// Redefine title if exist\r\n\t\t\t\t\tif(special && special.title)\r\n\t\t\t\t\t\t$('head > title').innerHTML = special.title;\r\n\r\n\t\t\t\t\tfound = true;\r\n\t\t\t\t};\r\n\r\n\t\t\t\tvar found = false;\r\n\t\t\t\tfor(var oldURL in self.lazyViewPoint){\r\n\t\t\t\t\tif(currentRouterURL.indexOf(oldURL) !== -1){\r\n\t\t\t\t\t\tfor(var newURL in self.lazyViewPoint[oldURL]){\r\n\t\t\t\t\t\t\tif(currentRouterURL.indexOf(oldURL) !== -1){\r\n\t\t\t\t\t\t\t\tfoundAction(self.lazyViewPoint[oldURL][newURL]);\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif(found) break;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// When the view point was not found\r\n\t\t\t\tif(!found){\r\n\t\t\t\t\t// Use fallback if exist\r\n\t\t\t\t\tif(sf.router.lazyViewPoint[\"@default\"])\r\n\t\t\t\t\t\tfoundAction(sf.router.lazyViewPoint[\"@default\"]);\r\n\r\n\t\t\t\t\tif(!found){\r\n\t\t\t\t\t\tfor (var i = 0; i < onEvent['error'].length; i++) {\r\n\t\t\t\t\t\t\tonEvent['error'][i]('sf.router.lazyViewPoint[\"'+oldURL+'\"][\"'+newURL+'\"] was not found');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Run 'before' event for new page view\r\n\t\t\t\tif(!DOMReference) DOMReference = document.body;\r\n\t\t\t\tif(self.pauseRenderOnTransition)\r\n\t\t\t\t\tself.pauseRenderOnTransition.css('display', 'none');\r\n\r\n\t\t\t\t// Let page script running first, then update the data binding\r\n\t\t\t\tDOMReference.innerHTML = data;\r\n\r\n\t\t\t\t// Parse the DOM data binding\r\n\t\t\t\tsf.model.init(DOMReference);\r\n\r\n\t\t\t\t// Init template to model binding\r\n\t\t\t\tvar temp = $('[sf-page]', DOMReference);\r\n\t\t\t\tfor (var i = 0; i < temp.length; i++) {\r\n\t\t\t\t\tbeforeEvent(temp[i].getAttribute('sf-page'));\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(self.pauseRenderOnTransition)\r\n\t\t\t\t\tself.pauseRenderOnTransition.css('display', '');\r\n\r\n\t\t\t\trouterLoaded(currentRouterURL, path, DOMReference);\r\n\r\n\t\t\t\tinitialized = true;\r\n\t\t\t\tlazyRouting = false;\r\n\r\n\t\t\t\tcurrentRouterURL = path;\r\n\t\t\t\troutingError = false;\r\n\t\t\t},\r\n\t\t\terror:function(xhr, data){\r\n\t\t\t\troutingError = true;\r\n\t\t\t\tif(xhr.aborted) return;\r\n\r\n\t\t\t\tRouterLoading = false;\r\n\t\t\t\tfor (var i = 0; i < onEvent['error'].length; i++) {\r\n\t\t\t\t\tonEvent['error'][i](xhr.status, data);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Back on error\r\n\t\t\t\twindow.history.back();\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif(!routingBack)\r\n\t\t\twindow.history.pushState(null, \"\", path);\r\n\r\n\t\troutingBack = false;\r\n\t\treturn true;\r\n\t}\r\n\r\n\t// Trigger loaded event\r\n\tfunction routerLoaded(currentRouterURL, path, data){\r\n\t\tfor (var i = 0; i < onEvent['loaded'].length; i++) {\r\n\t\t\tonEvent['loaded'][i](currentRouterURL, path, data);\r\n\t\t}\r\n\t}\r\n};","sf.internal.virtual_scroll = new function(){\r\n\tvar self = this;\r\n\tvar styleInitialized = false;\r\n\tvar scrollingByScript = false;\r\n\r\n\t// before and after\r\n\tself.prepareCount = 4; // 4, 8, 12, 16, ...\r\n\r\n\tself.handle = function(list, targetNode, parentNode){\r\n\t\tif(!styleInitialized){\r\n\t\t\tinitStyles();\r\n\t\t\tstyleInitialized = true;\r\n\t\t}\r\n\r\n\t\tvar dynamicList = false;\r\n\t\tvar virtual = list.$virtual;\r\n\t\tvirtual.reset = function(reinitOnly){\r\n\t\t\tvirtual.DOMCursor = 0; // cursor of first element in DOM tree as a cursor\r\n\r\n\t\t\tvirtual.bounding.ceiling = -1;\r\n\t\t\tvirtual.bounding.floor = 0;\r\n\r\n\t\t\tvirtual.vCursor.ceiling = null; // for forward direction\r\n\t\t\tvirtual.vCursor.floor = virtual.dom.firstElementChild; // for backward direction\r\n\r\n\t\t\tvirtual.bounding.initial = virtual.dCursor.ceiling.offsetTop;\r\n\t\t\trefreshScrollBounding(0, virtual.bounding, list, parentNode);\r\n\t\t}\r\n\r\n\t\tvirtual.reinitCursor = function(){\r\n\t\t\tvirtual.vCursor.ceiling = virtual.dom.children[virtual.DOMCursor - 1] || null;\r\n\t\t\tvirtual.vCursor.floor = virtual.dom.children[virtual.DOMCursor] || null;\r\n\t\t}\r\n\r\n\t\tvirtual.reinitScroll = function(){\r\n\t\t\trefreshScrollBounding(virtual.DOMCursor, virtual.bounding, list, parentNode);\r\n\t\t}\r\n\r\n\t\tvirtual.elements = function(){\r\n\t\t\treturn obtainElements(list, parentNode);\r\n\t\t}\r\n\r\n\t\tvirtual.dCursor = { // DOM Cursor\r\n\t\t\tceiling:parentNode.querySelector('.virtual-spacer.ceiling'),\r\n\t\t\tfloor:parentNode.querySelector('.virtual-spacer.floor')\r\n\t\t};\r\n\r\n\t\tvirtual.bounding = {};\r\n\t\tvirtual.vCursor = {};\r\n\r\n\t\tvirtual.reset();\r\n\t\tvirtual.targetNode = parentNode;\r\n\t\tvirtual.scrollHeight = virtual.dCursor.floor.offsetTop - virtual.bounding.initial;\r\n\r\n\t\tvar scroller = parentNode;\r\n\t\tvirtual.destroy = function(){\r\n\t\t\t$.off(scroller, 'scroll');\r\n\t\t\t$.off(parentNode, 'mousedown mouseup');\r\n\t\t\tvirtual.dom.innerHTML = '';\r\n\t\t\toffElementResize(parentNode);\r\n\r\n\t\t\tdelete list.$virtual;\r\n\t\t}\r\n\r\n\t\tvirtual.resetViewport = function(){\r\n\t\t\tvirtual.visibleLength = Math.floor(scroller.clientHeight / virtual.scrollHeight);\r\n\t\t\tvirtual.preparedLength = virtual.visibleLength + self.prepareCount * 2;\r\n\r\n\t\t\tif(virtual.preparedLength < 18)\r\n\t\t\t\tvirtual.preparedLength = 18;\r\n\t\t}\r\n\r\n\t\tsetTimeout(function(){\r\n\t\t\tscroller = parentNode;\r\n\r\n\t\t\tvar length = parentNode.getAttribute('scroll-parent-index') || 0;\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\tscroller = scroller.parentElement;\r\n\t\t\t}\r\n\r\n\t\t\tvirtual.resetViewport();\r\n\r\n\t\t\tif(parentNode.classList.contains('sf-list-dynamic')){\r\n\t\t\t\tdynamicList = true;\r\n\t\t\t\tdynamicHeight(list, targetNode, parentNode, scroller);\r\n\t\t\t}\r\n\t\t\telse staticHeight(list, targetNode, parentNode, scroller);\r\n\t\t}, 500);\r\n\t}\r\n\r\n\t// Recommended for a list that have different element height\r\n\tfunction dynamicHeight(list, targetNode, parentNode, scroller){\r\n\t\tvar virtual = list.$virtual;\r\n\t\tvar ceiling = virtual.dCursor.ceiling;\r\n\t\tvar floor = virtual.dCursor.floor;\r\n\t\tvar vCursor = virtual.vCursor;\r\n\t\tvCursor.floor = virtual.dom.firstElementChild;\r\n\t\t\r\n\t\tvirtual.scrollTo = function(index){\r\n\t\t\tscrollTo(index, list, self.prepareCount, parentNode, scroller);\r\n\r\n\t\t\t// Reset virtual spacer height\r\n\t\t\tceilingHeight = 0;\r\n\t\t\tfloorHeight = 0;\r\n\t\t\tceiling.style.height = ceilingHeight+'px';\r\n\t\t\tfloor.style.height = floorHeight+'px';\r\n\t\t}\r\n\r\n\t\tvirtual.refresh = function(force){\r\n\t\t\trefresh(force, list, self.prepareCount, parentNode, scroller);\r\n\t\t\tfillViewport();\r\n\t\t}\r\n\r\n\t\t// Insert some element until reach visible height\r\n\t\tfillViewport();\r\n\r\n\t\tvirtual.visibleLength = parentNode.childElementCount - 2;\r\n\t\tvirtual.preparedLength = virtual.visibleLength + self.prepareCount * 2;\r\n\r\n\t\tfor (var i = 0; i < self.prepareCount; i++) {\r\n\t\t\tvar temp = vCursor.floor;\r\n\t\t\tif(temp === null) break;\r\n\r\n\t\t\tvCursor.floor = temp.nextElementSibling;\r\n\t\t\tfloor.insertAdjacentElement('beforeBegin', temp);\r\n\t\t}\r\n\t\tvirtual.DOMCursor = 0;\r\n\r\n\t\tvar ceilingHeight = 0;\r\n\t\tvar floorHeight = 0;\r\n\t\tfunction previousCeiling(){\r\n\t\t\tvar temp = null;\r\n\t\t\tvar resetCeiling = false;\r\n\r\n\t\t\t// Add some element on the ceiling\r\n\t\t\tfor (var i = 0; i < self.prepareCount; i++) {\r\n\t\t\t\tif(vCursor.floor === null)\r\n\t\t\t\t\ttemp = virtual.dom.lastElementChild;\r\n\t\t\t\telse\r\n\t\t\t\t\ttemp = vCursor.floor.previousElementSibling;\r\n\r\n\t\t\t\tif(temp === null) break;\r\n\t\t\t\tvCursor.ceiling = temp.previousElementSibling;\r\n\t\t\t\tvirtual.DOMCursor--;\r\n\r\n\t\t\t\tceiling.insertAdjacentElement('afterEnd', temp);\r\n\r\n\t\t\t\tif(ceilingHeight > 0)\r\n\t\t\t\t\tceilingHeight -= getAbsoluteHeight(temp);\r\n\r\n\t\t\t\tif(virtual.DOMCursor < self.prepareCount && !resetCeiling){\r\n\t\t\t\t\ti = 0;\r\n\t\t\t\t\tresetCeiling = true;\r\n\t\t\t\t\ttemp = null;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif(ceilingHeight < 0 || temp === null)\r\n\t\t\t\tceilingHeight = 0;\r\n\r\n\t\t\tvar length = parentNode.childElementCount - 2 - list.$virtual.preparedLength;\r\n\t\t\t// Remove some element on the floor\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\ttemp = floor.previousElementSibling;\r\n\t\t\t\tfloorHeight += getAbsoluteHeight(temp);\r\n\r\n\t\t\t\tif(vCursor.floor === null)\r\n\t\t\t\t\tvirtual.dom.insertAdjacentElement('beforeEnd', temp);\r\n\t\t\t\telse vCursor.floor.insertAdjacentElement('beforeBegin', temp);\r\n\r\n\t\t\t\tvCursor.floor = temp;\r\n\t\t\t}\r\n\r\n\t\t\tif(vCursor.floor === null)\r\n\t\t\t\tvCursor.ceiling = virtual.dom.lastElementChild;\r\n\t\t\telse \r\n\t\t\t\tvCursor.ceiling = vCursor.floor.previousElementSibling;\r\n\r\n\t\t\tceiling.style.height = ceilingHeight+'px';\r\n\t\t\tfloor.style.height = floorHeight+'px';\r\n\t\t}\r\n\r\n\t\tfunction fillViewport(){\r\n\t\t\t// Insert some element depend on prepared length\r\n\t\t\tvar length = virtual.preparedLength - (parentNode.childElementCount - 2);\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\tif(vCursor.ceiling === null)\r\n\t\t\t\t\ttemp = virtual.dom.firstElementChild;\r\n\t\t\t\telse\r\n\t\t\t\t\ttemp = vCursor.ceiling.nextElementSibling;\r\n\r\n\t\t\t\tif(temp === null) break;\r\n\t\t\t\tvCursor.floor = temp.nextElementSibling;\r\n\r\n\t\t\t\tfloor.insertAdjacentElement('beforeBegin', temp);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction nextFloor(){\r\n\t\t\tvar temp = null;\r\n\t\t\tfillViewport();\r\n\r\n\t\t\tif(vCursor.floor !== null){\r\n\t\t\t\tif(vCursor.ceiling === null)\r\n\t\t\t\t\tvCursor.ceiling = vCursor.floor.previousElementSibling;\r\n\r\n\t\t\t\t// Add extra element based on prepare count\r\n\t\t\t\tfor (var i = 0; i < self.prepareCount; i++) {\r\n\t\t\t\t\ttemp = vCursor.floor;\r\n\t\t\t\t\tif(temp === null) break;\r\n\r\n\t\t\t\t\tvCursor.floor = temp.nextElementSibling;\r\n\t\t\t\t\tfloor.insertAdjacentElement('beforeBegin', temp);\r\n\r\n\t\t\t\t\tif(floorHeight > 0)\r\n\t\t\t\t\t\tfloorHeight -= getAbsoluteHeight(temp);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif(floorHeight < 0 || temp === null)\r\n\t\t\t\tfloorHeight = 0;\r\n\r\n\t\t\t// Remove some element on the ceiling\r\n\t\t\tvar length = parentNode.childElementCount - 2 - list.$virtual.preparedLength;\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\ttemp = ceiling.nextElementSibling;\r\n\t\t\t\tceilingHeight += getAbsoluteHeight(temp);\r\n\t\t\t\tvirtual.DOMCursor++;\r\n\r\n\t\t\t\tif(vCursor.ceiling === null)\r\n\t\t\t\t\tvirtual.dom.insertAdjacentElement('afterBegin', temp);\r\n\t\t\t\telse vCursor.ceiling.insertAdjacentElement('afterEnd', temp);\r\n\r\n\t\t\t\tvCursor.ceiling = temp;\r\n\t\t\t}\r\n\r\n\t\t\tif(vCursor.ceiling === null)\r\n\t\t\t\tvCursor.floor = virtual.dom.firstElementChild;\r\n\t\t\telse \r\n\t\t\t\tvCursor.floor = vCursor.ceiling.nextElementSibling;\r\n\r\n\t\t\tceiling.style.height = ceilingHeight+'px';\r\n\t\t\tfloor.style.height = floorHeight+'px';\r\n\t\t}\r\n\r\n\t\tvar bounding = virtual.bounding;\r\n\t\trefreshScrollBounding(0, bounding, list, parentNode);\r\n\r\n\t\tif(virtual.callback_ !== void 0){\r\n\t\t\tvar callback_ = virtual.callback_;\r\n\t\t\tdelete virtual.callback_;\r\n\t\t}\r\n\r\n\t\tvar updating = false;\r\n\t\tfunction checkCursorPosition(){\r\n\t\t\tif(updating || scrollingByScript) return;\r\n\t\t\tupdating = true;\r\n\r\n\t\t\tif(scroller.scrollTop < bounding.ceiling){\r\n\t\t\t\t// console.log('back', bounding, scroller.scrollTop, virtual.DOMCursor);\r\n\t\t\t\tpreviousCeiling();\r\n\t\t\t\trefreshScrollBounding(virtual.DOMCursor, bounding, list, parentNode);\r\n\t\t\t\t// console.warn('back', bounding, scroller.scrollTop, virtual.DOMCursor);\r\n\t\t\t}\r\n\r\n\t\t\telse if(scroller.scrollTop > bounding.floor){\r\n\t\t\t\t// console.log('front', bounding, scroller.scrollTop, virtual.DOMCursor);\r\n\t\t\t\tnextFloor();\r\n\t\t\t\trefreshScrollBounding(virtual.DOMCursor, bounding, list, parentNode);\r\n\t\t\t\t// console.warn('front', bounding, scroller.scrollTop, virtual.DOMCursor);\r\n\t\t\t}\r\n\r\n\t\t\tif(virtual.callback !== void 0 && list.length !== 0){\r\n\t\t\t\tif(virtual.callback.hitFloor && virtual.vCursor.floor === null &&\r\n\t\t\t\t\tscroller.scrollTop + scroller.clientHeight === scroller.scrollHeight\r\n\t\t\t\t){\r\n\t\t\t\t\tvirtual.callback.hitFloor(virtual.DOMCursor);\r\n\t\t\t\t}\r\n\t\t\t\telse if(virtual.callback.hitCeiling && virtual.vCursor.ceiling === null && scroller.scrollTop === 0){\r\n\t\t\t\t\tvirtual.callback.hitCeiling(virtual.DOMCursor);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if(callback_ && callback_.ref[callback_.var]){\r\n\t\t\t\tvirtual.callback = callback_.ref[callback_.var];\r\n\t\t\t\tcallback_ = null;\r\n\t\t\t}\r\n\r\n\t\t\tupdating = false;\r\n\t\t}\r\n\r\n\t\t$.on(scroller, 'scroll', checkCursorPosition);\r\n\t\tonElementResize(parentNode, function(){\r\n\t\t\trefreshScrollBounding(virtual.DOMCursor, bounding, list, parentNode);\r\n\t\t});\r\n\t}\r\n\r\n\t// Recommended for a list that have similar element height\r\n\tfunction staticHeight(list, targetNode, parentNode, scroller){\r\n\t\tvar virtual = list.$virtual;\r\n\t\tvar ceiling = virtual.dCursor.ceiling;\r\n\t\tvar floor = virtual.dCursor.floor;\r\n\r\n\t\t// Insert visible element to dom tree\r\n\t\tvar insertCount = virtual.preparedLength <= list.length ? virtual.preparedLength : list.length;\r\n\t\tfor (var i = 0; i < insertCount; i++) {\r\n\t\t\tif(virtual.dom.firstElementChild === null)\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tfloor.insertAdjacentElement('beforeBegin', virtual.dom.firstElementChild);\r\n\t\t}\r\n\r\n\t\tvirtual.refreshVirtualSpacer = refreshVirtualSpacer;\r\n\r\n\t\tfunction refreshVirtualSpacer(cursor){\r\n\t\t\tif(cursor >= self.prepareCount){\r\n\t\t\t\tceiling.style.height = (cursor - self.prepareCount) * virtual.scrollHeight + 'px';\r\n\t\t\t\tfloor.style.height = (list.length - virtual.preparedLength - cursor) * virtual.scrollHeight + 'px';\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\tceiling.style.height = cursor * virtual.scrollHeight + 'px'; //'0px';\r\n\t\t\t\tvar count = (list.length - virtual.preparedLength);\r\n\t\t\t\tfloor.style.height = (count || 0) * virtual.scrollHeight + 'px';\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tvar bounding = virtual.bounding;\r\n\r\n\t\trefreshVirtualSpacer(0);\r\n\t\trefreshScrollBounding(self.prepareCount, bounding, list, parentNode);\r\n\t\tbounding.ceiling = -1;\r\n\r\n\t\tvirtual.offsetTo = function(index){\r\n\t\t\treturn index * virtual.scrollHeight + ceiling.offsetTop;\r\n\t\t}\r\n\r\n\t\tvar vCursor = virtual.vCursor;\r\n\t\tvCursor.floor = virtual.dom.firstElementChild;\r\n\t\tvirtual.scrollTo = function(index){\r\n\t\t\tscrollTo(index, list, self.prepareCount, parentNode, scroller);\r\n\t\t}\r\n\r\n\t\tvirtual.refresh = function(force){\r\n\t\t\trefresh(force, list, self.prepareCount, parentNode, scroller, checkCursorPosition, refreshVirtualSpacer);\r\n\t\t}\r\n\r\n\t\tif(virtual.callback_ !== void 0){\r\n\t\t\tvar callback_ = virtual.callback_;\r\n\t\t\tdelete virtual.callback_;\r\n\t\t}\r\n\r\n\t\tvar updating = false;\r\n\t\tvar fromCeiling = true;\r\n\t\tvar scrollFocused = false;\r\n\t\tfunction checkCursorPosition(){\r\n\t\t\tif(updating || scrollingByScript || scroller.scrollTop >= bounding.ceiling && scroller.scrollTop <= bounding.floor){\r\n\t\t\t\t// Fix chrome scroll anchoring bugs when scrolling at corner\r\n\t\t\t\tif(scrollFocused){\r\n\t\t\t\t\tif(scroller.scrollTop === 0 || scroller.scrollTop === scroller.scrollHeight - scroller.clientHeight){\r\n\t\t\t\t\t\tremoveUserScrollFocus(scroller);\r\n\t\t\t\t\t\tscrollFocused = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tvar cursor = Math.floor(scroller.scrollTop / virtual.scrollHeight);\r\n\t\t\tif(cursor + virtual.preparedLength > list.length)\r\n\t\t\t\tcursor = list.length - virtual.preparedLength;\r\n\r\n\t\t\tif(fromCeiling){\r\n\t\t\t\tif(cursor < self.prepareCount*2)\r\n\t\t\t\t\tcursor -= self.prepareCount;\r\n\r\n\t\t\t\t// Fix chrome scroll anchoring bugs\r\n\t\t\t\tif(scrollFocused){\r\n\t\t\t\t\tremoveUserScrollFocus(scroller);\r\n\t\t\t\t\tscrollFocused = false;\r\n\t\t\t\t}\r\n\t\t\t\tfromCeiling = false;\r\n\t\t\t}\r\n\r\n\t\t\tif(cursor < self.prepareCount){\r\n\t\t\t\tcursor = 0;\r\n\t\t\t\tfromCeiling = true;\r\n\t\t\t}\r\n\r\n\t\t\tupdating = true;\r\n\r\n\t\t\tvar changes = cursor - virtual.DOMCursor;\r\n\t\t\tif(cursor + changes >= list.length)\r\n\t\t\t\tchanges = cursor + changes - list.length;\r\n\r\n\t\t\tif(changes === 0){ // This should be fixed to improve performance and future bugs\r\n\t\t\t\t//console.warn(\"No changes (The scroll bounding is not correct)\");\r\n\t\t\t\tupdating = false;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tvirtual.DOMCursor = cursor;\r\n\r\n\t\t\t// console.log(cursor, changes, bounding.ceiling, bounding.floor, scroller.scrollTop);\r\n\t\t\tmoveElementCursor(changes, list);\r\n\t\t\trefreshVirtualSpacer(cursor);\r\n\t\t\trefreshScrollBounding(cursor, bounding, list, parentNode);\r\n\t\t\t// console.log('a', bounding.ceiling, bounding.floor, scroller.scrollTop);\r\n\r\n\t\t\tif(virtual.callback !== void 0 && list.length !== 0){\r\n\t\t\t\tif(virtual.callback.hitFloor && virtual.vCursor.floor === null){\r\n\t\t\t\t\tvirtual.callback.hitFloor(cursor);\r\n\t\t\t\t}\r\n\t\t\t\telse if(virtual.callback.hitCeiling && virtual.vCursor.ceiling === null){\r\n\t\t\t\t\tvirtual.callback.hitCeiling(cursor);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if(callback_ && callback_.ref[callback_.var]){\r\n\t\t\t\tvirtual.callback = callback_.ref[callback_.var];\r\n\t\t\t\tcallback_ = null;\r\n\t\t\t}\r\n\r\n\t\t\tupdating = false;\r\n\t\t}\r\n\r\n\t\t$.on(scroller, 'scroll', checkCursorPosition);\r\n\r\n\t\t// For preventing scroll jump if scrolling over than viewport\r\n\t\tif(scroller === parentNode && navigator.userAgent.indexOf('Chrom') !== -1){\r\n\t\t\t$.on(parentNode, 'mousedown', function(){\r\n\t\t\t\tscrollFocused = true;\r\n\t\t\t});\r\n\t\t\t$.on(parentNode, 'mouseup', function(){\r\n\t\t\t\tscrollFocused = false;\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tfunction refreshScrollBounding(cursor, bounding, list, parentNode){\r\n\t\tvar temp = Math.floor(self.prepareCount / 2); // half of element preparation\r\n\t\tif(cursor < self.prepareCount){\r\n\t\t\tbounding.ceiling = -1;\r\n\t\t\tbounding.floor = parentNode.children[self.prepareCount * 2 + 1];\r\n\r\n\t\t\tif(bounding.floor !== void 0)\r\n\t\t\t\tbounding.floor = bounding.floor.offsetTop;\r\n\t\t\telse bounding.floor = parentNode.lastElementChild.offsetTop + 1000;\r\n\r\n\t\t\tbounding.floor -= bounding.initial;\r\n\t\t\treturn;\r\n\t\t}\r\n\t\telse if(parentNode.children[temp + 1] !== void 0)\r\n\t\t\t\tbounding.ceiling = parentNode.children[temp + 1].offsetTop; // -2 element\r\n\r\n\t\tif(list.$virtual.preparedLength !== void 0 && cursor >= list.length - list.$virtual.preparedLength)\r\n\t\t\tbounding.floor = list.$virtual.dCursor.floor.offsetTop + list.$virtual.scrollHeight*2;\r\n\t\telse{\r\n\t\t\tbounding.floor = parentNode.children[self.prepareCount + 3].offsetTop; // +2 element\r\n\r\n\t\t\tif(parentNode.hasAttribute('scroll-reduce-floor')){\r\n\t\t\t\tbounding.floor -= parentNode.getAttribute('scroll-reduce-floor');\r\n\t\t\t\tbounding.ceiling -= parentNode.getAttribute('scroll-reduce-floor');\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tbounding.ceiling -= bounding.initial;\r\n\t\tbounding.floor -= bounding.initial;// scrollHeight - clientHeight\r\n\t}\r\n\r\n\tfunction moveElementCursor(changes, list){\r\n\t\tvar vDOM = list.$virtual.dom;\r\n\t\tvar vCursor = list.$virtual.vCursor;\r\n\t\tvar dCursor = list.$virtual.dCursor;\r\n\r\n\t\tif(changes > 0){ // forward\r\n\t\t\tvar ref = 0;\r\n\r\n\t\t\t// Select from virtual ceiling cursor to Dom tree\r\n\t\t\tfor (var i = 0; i < changes; i++) { // vDom -> Dom tree\r\n\t\t\t\tif(vCursor.ceiling === null)\r\n\t\t\t\t\tref = vDOM.firstElementChild;\r\n\r\n\t\t\t\telse ref = vCursor.ceiling.nextElementSibling;\r\n\t\t\t\tif(ref === null) break;\r\n\t\t\t\tdCursor.floor.insertAdjacentElement('beforeBegin', ref);\r\n\t\t\t}\r\n\r\n\t\t\t// Move element on the ceiling to vDom\r\n\t\t\tfor (var i = changes; i > 0; i--) { // Dom tree -> vDom\r\n\t\t\t\tif(vCursor.ceiling === null){\r\n\t\t\t\t\tvCursor.ceiling = dCursor.ceiling.nextElementSibling;\r\n\t\t\t\t\tvDOM.insertAdjacentElement('afterBegin', vCursor.ceiling);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tref = dCursor.ceiling.nextElementSibling;\r\n\t\t\t\t\tvCursor.ceiling.insertAdjacentElement('afterEnd', ref);\r\n\t\t\t\t\tvCursor.ceiling = ref;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tvCursor.floor = vCursor.ceiling.nextElementSibling;\r\n\t\t}\r\n\t\telse if(changes < 0){ // backward\r\n\t\t\tvar ref = 0;\r\n\t\t\tchanges = -changes;\r\n\r\n\t\t\t// Select from virtual floor cursor to Dom tree\r\n\t\t\tfor (var i = 0; i < changes; i++) { // vDom -> Dom tree\r\n\t\t\t\tif(vCursor.floor === null)\r\n\t\t\t\t\tref = vDOM.lastElementChild;\r\n\r\n\t\t\t\telse ref = vCursor.floor.previousElementSibling;\r\n\t\t\t\tif(ref === null) break;\r\n\t\t\t\tdCursor.ceiling.insertAdjacentElement('afterEnd', ref);\r\n\t\t\t}\r\n\r\n\t\t\t// Move element on the floor to vDom\r\n\t\t\tfor (var i = 0; i < changes; i++) { // Dom tree -> vDom\r\n\t\t\t\tif(vCursor.floor === null){\r\n\t\t\t\t\tvCursor.floor = dCursor.floor.previousElementSibling;\r\n\t\t\t\t\tvDOM.insertAdjacentElement('beforeEnd', vCursor.floor);\r\n\t\t\t\t}\r\n\r\n\t\t\t\telse{\r\n\t\t\t\t\tref = dCursor.floor.previousElementSibling;\r\n\t\t\t\t\tvCursor.floor.insertAdjacentElement('beforeBegin', ref);\r\n\t\t\t\t\tvCursor.floor = ref;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tvCursor.ceiling = vCursor.floor.previousElementSibling;\r\n\t\t}\r\n\t}\r\n\r\n\tfunction scrollTo(index, list, prepareCount, parentNode, scroller){\r\n\t\tvar virtual = list.$virtual;\r\n\t\tvar reduce = 0;\r\n\r\n\t\tif(index >= list.length - virtual.preparedLength){\r\n\t\t\treduce -= prepareCount;\r\n\t\t\tindex = list.length - virtual.preparedLength;\r\n\t\t}\r\n\r\n\t\tif(index - virtual.DOMCursor === 0 || index >= list.length) return;\r\n\r\n\t\tscrollingByScript = true;\r\n\r\n\t\t// Already on DOM tree\r\n\t\tif((virtual.DOMCursor === 0 && index < prepareCount + prepareCount/2) ||\r\n\t\t\t(virtual.DOMCursor + prepareCount/2 > index\r\n\t\t\t&& virtual.DOMCursor + prepareCount < index))\r\n\t\t\tscroller.scrollTop = parentNode.children[index - virtual.DOMCursor + 1].offsetTop;\r\n\r\n\t\t// Move cursor\r\n\t\telse {\r\n\t\t\tvar temp = null;\r\n\t\t\tvar ceiling = virtual.dCursor.ceiling;\r\n\t\t\tvar floor = virtual.dCursor.floor;\r\n\t\t\tvar vCursor = virtual.vCursor;\r\n\r\n\t\t\t// DOM tree to virtual DOM\r\n\t\t\tvar length = parentNode.childElementCount - 2;\r\n\t\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\t\ttemp = ceiling.nextElementSibling;\r\n\r\n\t\t\t\tif(vCursor.floor === null){\r\n\t\t\t\t\tvirtual.dom.insertAdjacentElement('beforeEnd', temp);\r\n\r\n\t\t\t\t\tif(i === length-1)\r\n\t\t\t\t\t\tvCursor.floor = temp;\r\n\t\t\t\t}\r\n\t\t\t\telse vCursor.floor.insertAdjacentElement('beforeBegin', temp);\r\n\t\t\t}\r\n\r\n\t\t\tif(index >= prepareCount){\r\n\t\t\t\tif(index < list.length - virtual.preparedLength)\r\n\t\t\t\t\tindex -= prepareCount;\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\treduce = prepareCount - index;\r\n\t\t\t\tvirtual.DOMCursor = index = 0;\r\n\t\t\t}\r\n\r\n\t\t\tvar insertCount = virtual.preparedLength <= list.length ? virtual.preparedLength : list.length;\r\n\r\n\t\t\t// Virtual DOM to DOM tree\r\n\t\t\tfor (var i = 0; i < insertCount; i++) {\r\n\t\t\t\ttemp = virtual.dom.children[index];\r\n\t\t\t\tif(temp === void 0) break;\r\n\r\n\t\t\t\tfloor.insertAdjacentElement('beforeBegin', temp);\r\n\t\t\t}\r\n\t\t\tvirtual.DOMCursor = index;\r\n\r\n\t\t\tvCursor.floor = virtual.dom.children[index] || null;\r\n\t\t\tvCursor.ceiling = vCursor.floor ? vCursor.floor.previousElementSibling : null;\r\n\r\n\t\t\tif(list.$virtual.refreshVirtualSpacer)\r\n\t\t\t\tlist.$virtual.refreshVirtualSpacer(index);\r\n\r\n\t\t\trefreshScrollBounding(index, virtual.bounding, list, parentNode);\r\n\r\n\t\t\ttemp = parentNode.children[prepareCount - reduce + 1];\r\n\t\r\n\t\t\tif(temp !== void 0)\r\n\t\t\t\tscroller.scrollTop = temp.offsetTop - scroller.offsetTop;\r\n\t\t}\r\n\r\n\t\tscrollingByScript = false;\r\n\t}\r\n\r\n\tfunction removeUserScrollFocus(parentNode){\r\n\t\tparentNode.style.overflow = 'hidden';\r\n\t\tsetTimeout(function(){\r\n\t\t\tparentNode.style.overflow = '';\r\n\t\t}, 50);\r\n\t}\r\n\r\n\tfunction getAbsoluteHeight(el){\r\n\t var styles = window.getComputedStyle(el);\r\n\t var margin = parseInt(styles['marginTop']) + parseInt(styles['marginBottom']);\r\n\t return el.offsetHeight + margin || 0;\r\n\t}\r\n\r\n\tfunction obtainElements(list, parentNode){\r\n\t\tvar exist = [];\r\n\t\tvar temp = void 0;\r\n\r\n\t\tvar length = list.$virtual.DOMCursor;\r\n\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\ttemp = list.$virtual.dom.children[i];\r\n\t\t\tif(temp === void 0) break;\r\n\t\t\texist.push(temp);\r\n\t\t}\r\n\r\n\t\tlength = parentNode.childElementCount - 2;\r\n\t\tfor (var i = 1; i <= length; i++) {\r\n\t\t\ttemp = parentNode.children[i];\r\n\t\t\tif(temp === void 0) break;\r\n\t\t\texist.push(temp);\r\n\t\t}\r\n\t\t\r\n\t\t// Get elements length\r\n\t\tvar elementLength = list.$virtual.dom.childElementCount + length;\r\n\r\n\t\tlength = elementLength - length - list.$virtual.DOMCursor;\r\n\t\tfor (var i = 0; i < length; i++) {\r\n\t\t\ttemp = list.$virtual.dom.children[list.$virtual.DOMCursor + i];\r\n\t\t\tif(temp === void 0) break;\r\n\t\t\texist.push(temp);\r\n\t\t}\r\n\r\n\t\treturn exist;\r\n\t}\r\n\r\n\tfunction refresh(force, list, prepareCount, parentNode, scroller, checkCursorPosition, refreshVirtualSpacer){\r\n\t\tvar cursor = list.$virtual.DOMCursor;\r\n\t\tvar additionalScroll = 0;\r\n\r\n\t\t// Find nearest cursor for current view position\r\n\t\tif(force){\r\n\t\t\tvar i = -1;\r\n\t\t\tvar length = list.$virtual.preparedLength;\r\n\r\n\t\t\tdo{\r\n\t\t\t\ti++;\r\n\t\t\t} while(i < length && parentNode.children[i].offsetTop < scroller.scrollTop);\r\n\r\n\t\t\tcursor = cursor + i;\r\n\t\t\tif(cursor > 0) cursor -= 1;\r\n\r\n\t\t\tadditionalScroll = scroller.scrollTop - parentNode.children[i].offsetTop;\r\n\t\t}\r\n\r\n\t\t// Force move cursor if element in the DOM tree was overloaded\r\n\t\tif(force || parentNode.childElementCount - 2 > list.$virtual.preparedLength){\r\n\t\t\tlist.$virtual.DOMCursor = list.length;\r\n\t\t\tvar moveTo = cursor;\r\n\t\t\tif(!force)\r\n\t\t\t\tmoveTo = cursor <= prepareCount ? cursor : (cursor + prepareCount);\r\n\r\n\t\t\tscrollTo(moveTo,\r\n\t\t\t\tlist,\r\n\t\t\t\tprepareCount,\r\n\t\t\t\tparentNode,\r\n\t\t\t\tscroller\r\n\t\t\t);\r\n\r\n\t\t\tscroller.scrollTop += additionalScroll;\r\n\t\t}\r\n\r\n\t\tif(refreshVirtualSpacer)\r\n\t\t\trefreshVirtualSpacer(cursor);\r\n\r\n\t\tif(checkCursorPosition)\r\n\t\t\tcheckCursorPosition();\r\n\r\n\t\trefreshScrollBounding(cursor, list.$virtual.bounding, list, parentNode);\r\n\t}\r\n\r\n\tvar _onElementResize = [];\r\n\tvar _onElementResize_timer = -1;\r\n\tfunction onElementResize(parentNode, callback){\r\n\t\tif(_onElementResize_timer === -1){\r\n\t\t\t_onElementResize_timer = setInterval(function(){\r\n\t\t\t\tvar temp = null;\r\n\t\t\t\tfor (var i = _onElementResize.length - 1; i >= 0; i--) {\r\n\t\t\t\t\ttemp = _onElementResize[i];\r\n\r\n\t\t\t\t\t// Check resize\r\n\t\t\t\t\tif(temp.element.scrollHeight === temp.height\r\n\t\t\t\t\t\t|| temp.element.scrollWidth === temp.width)\r\n\t\t\t\t\t\tcontinue;\r\n\r\n\t\t\t\t\t// Check if it's removed from DOM\r\n\t\t\t\t\tif(temp.element.parentElement === null){\r\n\t\t\t\t\t\t_onElementResize.splice(i, 1);\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\ttemp.callback();\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(_onElementResize.length === 0){\r\n\t\t\t\t\tclearInterval(_onElementResize_timer);\r\n\t\t\t\t\t_onElementResize_timer = -1;\r\n\t\t\t\t}\r\n\t\t\t}, 1000);\r\n\t\t}\r\n\r\n\t\t_onElementResize.push({\r\n\t\t\telement:parentNode,\r\n\t\t\tcallback:callback,\r\n\t\t\theight:parentNode.scrollHeight,\r\n\t\t\twidth:parentNode.scrollWidth\r\n\t\t});\r\n\t}\r\n\r\n\tfunction offElementResize(parentNode){\r\n\t\tfor (var i = _onElementResize.length - 1; i >= 0; i--) {\r\n\t\t\tif(_onElementResize[i].element === parentNode)\r\n\t\t\t\t_onElementResize.splice(i, 1);\r\n\t\t}\r\n\r\n\t\t// Interval will be cleared when the array is empty\r\n\t}\r\n\r\n\tfunction initStyles(){\r\n\t\tvar style = document.getElementById('sf-styles');\r\n\r\n\t\tif(!style){\r\n\t\t\tstyle = document.createElement('style');\r\n\t\t\tstyle.id = 'sf-styles';\r\n \tdocument.head.appendChild(style);\r\n\t\t}\r\n\r\n\t\tstyle.sheet.insertRule(\r\n\t\t'.sf-virtual-list .virtual-spacer{'+\r\n 'visibility: hidden;'+\r\n 'position: relative;'+\r\n 'height: 1px;'+\r\n 'transform-origin: 0 0;'+\r\n 'width: 1px;'+\r\n 'margin: 0;'+\r\n 'padding: 0;'+\r\n 'background: none;'+\r\n 'border: none;'+\r\n 'box-shadow: none;'+\r\n '}', style.sheet.cssRules.length);\r\n\t}\r\n};"]} \ No newline at end of file diff --git a/package.json b/package.json index 49294d4..b51f6c3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "scarletsframe", "description":"A frontend framework that can help you write a simple web structure", - "version": "0.14.1", + "version": "0.14.2", "repository": { "type": "git", "url": "https://github.com/ScarletsFiction/ScarletsFrame.git" diff --git a/src/sf-model.js b/src/sf-model.js index 9b31343..cc13f2f 100644 --- a/src/sf-model.js +++ b/src/sf-model.js @@ -198,8 +198,11 @@ sf.model = function(scope){ } var templateParser = function(template, item, original){ - if(template.component !== void 0) - return new window[template.component]; + if(template.constructor !== Object){ + var html = template.cloneNode(true); + html.model.$item = item; + return html; + } var html = original === true ? template.html : template.html.cloneNode(true); var addresses = template.addresses; @@ -1926,9 +1929,9 @@ sf.model = function(scope){ var tagName = targetNode.tagName.toLowerCase(); if(sf.component.registered[tagName] !== void 0){ targetNode.parentNode.classList.add('sf-keyed-list'); - return { - component:'$'+capitalizeLetters(tagName.split('-')) - }; + targetNode.textContent = ''; + targetNode.remove(); + return targetNode; } var copy = targetNode.outerHTML; diff --git a/tests/index.html b/tests/index.html index 5338fe2..c6e4d0e 100644 --- a/tests/index.html +++ b/tests/index.html @@ -139,11 +139,12 @@ -
+
+ test click
1. {{ data }}
2. {{ data }}
- +
diff --git a/tests/script.js b/tests/script.js index c38dfd3..6f9d2f8 100644 --- a/tests/script.js +++ b/tests/script.js @@ -203,11 +203,18 @@ sf.controller.for('model-binding', function(self, root){ } }); +sf.model.for('components', function(self){ + self.items = [{id:1},{id:2},{id:3}]; + self.clickOK = function(){ + console.warn("Click OK!"); + } +}); + sf.component.for('comp-test', function(self){ self.data = 'zxc'; }); -sf.component.html('comp-test', `
1. {{ data }}
2. {{ data }}
`); +sf.component.html('comp-test', `
1. {{ data }}
2. {{ data }}

`); sf(function(){ var ID = sf.component.new('comp-test', compDefined);