
      /**
       * @description Siteheart library
       */
       
      if(!("Siteheart" in window)){
      Siteheart = {};
      Siteheart.VERSION = '3.0.0';

      /**
       * @description Domain
       */
      Siteheart.HOST     = ("https:" == document.location.protocol ? "https" : "http") + '://' + (document.location.hostname == 'siteheart.dev' ? 'siteheart.dev' : (document.location.hostname == 'siteheart.my' ? 'siteheart.my' : 'siteheart.com')) ;
      Siteheart.WSHOST   = ("https:" == document.location.protocol ? "wss" : "ws") + '://' + (document.location.hostname == 'siteheart.dev' ? 'siteheart.dev' : (document.location.hostname == 'siteheart.my' ? 'siteheart.my' : 'siteheart.com')) ;

      Siteheart.autoId = 1;


      /**
       * @description Debug mode
       */
      Siteheart.DEBUG = false;



      /**
       * @description Templates
       */
      Siteheart.template = [];



      /**
       * @description array events listeners
       */
      Siteheart.Events = [];

       /**
        * @method onEvent
        * @param app        - Application object
        * @param event_name - Evenet name
        * @param callback   - Callback function
        * @description Method added callback function to event
        * return void()
        */
       Siteheart.onEvent = function(app, event_name, callback, unique){

             if(typeof(app['Events']) == 'undefined')app['Events'] = [];

             if(typeof(app['Events'][event_name]) == 'undefined'){
                app['Events'][event_name] = [];
             }
             if(!unique)unique = 'default';
             if(unique != 'default'){
               app['Events'][event_name][unique] = callback;
             }else{
               app['Events'][event_name][unique] = [];
               app['Events'][event_name].push(callback);
             }




        };

       /**
        * @method callEvent
        * @param app        - Application object
        * @param event_name - Evenet name
        * @param params     - Callback params
        * @description Method call callback functions to event
        * return void()
        */
      Siteheart.callEvent = function(app, event_name, param1, param2, param3, param4, param5){

         if(typeof(app['Events']) == 'undefined' || typeof(app['Events'][event_name]) == 'undefined')return;

          for(var unique in app['Events'][event_name]){

            if(unique != 'default' && typeof(app['Events'][event_name][unique]) == 'function'){

              app['Events'][event_name][unique](param1, param2, param3, param4, param5);

            }else if(unique == 'default'){

                   for(var i in app['Events'][event_name]['default']){

                        if(typeof(app['Events'][event_name]['default'][i]) == 'function'){
                           app['Events'][event_name]['default'][i](param1, param2, param3, param4, param5);
                        }
                   }

            }

          }
      };






       /**
        * @description Add to Application config initParams
        * return Object
        */
       Siteheart.reconfigure = function(config, options){

         if(typeof(options) != 'object')options = {};
           for(var i in options){
             config[i.toLowerCase()] = options[i];
           }
         return config;
       };





       Siteheart.getCnf = function(app, param){

            var params = param.split('.');
            if(params.length == 1){
              return (app.config[params[0]] || false);
            }else if(params.length == 2){
               if(typeof(app.config[params[0]]) == 'undefined')return false;
                return ( app.config[params[0]][params[1]] || false);
            }
          return false;
        };


         /**
         * @description Send reguest to server
         * return void
         */
     	Siteheart.request =  function (){

            function request(){

                var self = this;
                var params = [];
                var s = null;
                var respName = null;

                 this.onSuccess = function(){};

                 this.onError   = function(){};

                 this.setParams = function(p){params = p;};

                 this.cancel = function(){

                   self.onSuccess = function(){};
                   if(s)s.parentNode.removeChild(s);
                   s = null;
                   window[respName] = function(){};

                 }


                 this.start = function(url){

                 if(url.indexOf('http://') == -1 && url.indexOf('https://') == -1){url = Siteheart.HOST + url;}

                     respName = 'Func' + Math.random().toString();
                     respName = respName.replace('.','');
                     params['callback'] = respName;

                        s =  document.createElement('script');
                	    s.type = 'text/javascript';
                	    s.charset = 'utf-8';
                        s.async = true;
                        var p = "";
                        for(var name in params){
                           p += name + '=' + params[name] + '&';
                        }
                	    s.src = url + '?' + p;
                        document.body.appendChild(s);

                        window[respName] = function(response){
                                            if(s)s.parentNode.removeChild(s);
                                            s = null;
                                            self.onSuccess(response);
                                            window[respName] = null; 
                                       }

                 }

            }


              return new request();
     	};






       /**
         * @description Templates Parser
         * return String
         */
       Siteheart.nano = function(template, data) {
            data = (data || {});
            data.siteheart = {};
            data.siteheart.host = Siteheart.HOST;
          
              return template.replace(/\{([\w\.]*)\}/g, function (str, key) {
                      var keys  = key.split(".");
                      var key   = keys.shift();
                      var value = data[key];

                         for(var i = 0; i< keys.length; i++){
                         	if(key == 'tpl')
                               value = Siteheart.nano(value[keys[i]], data);
                            else
                               value = value[keys[i]];
                         }
                         /*
                         for(var i in keys){
                             value = value[keys[i]];
                         }
                         */
                      return (value === null || value === undefined) ? "" : value;
                    });
       };



       Siteheart.setProtocol = function(str){
           str = str.replace("**", Siteheart.HOST);
          return str.replace("*", ("https:" == document.location.protocol ? "https" : "http"));
       };




        /**
         * @description Localization Parser
         * return String
         */
       Siteheart.l = function(name, params){
            params = (params || {});
            if(typeof(Siteheart['language']) != 'undefined' && typeof(Siteheart.language[name]) != 'undefined'){
              return Siteheart.nano(Siteheart.language[name], params);
            }
            return name;
       };




       Siteheart.addJS = function(file){
           if(file.indexOf('http://') == -1 && file.indexOf('https://') == -1){file = Siteheart.HOST + file;}
           if(Siteheart.DEBUG){
            file += '?t='+(new Date()).getTime()
           }
          var s = document.createElement('script');
               s.type  = 'text/javascript';
               s.async = true ;
               s.src   = file;
               Siteheart.addFile(s);
       };




       Siteheart.addCSS = function(file){
            if(file.indexOf('http://') == -1 && file.indexOf('https://') == -1){file =  Siteheart.HOST + file;}
            if(Siteheart.DEBUG){file += '?t='+(new Date()).getTime()};
           var s = document.createElement('link');
               s.rel = 'stylesheet';
               s.href  = file;
               Siteheart.addFile(s);
       };



       Siteheart.addFile = function(s){
           var c = (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]);
               c.appendChild(s);
       };


       /**
         * @description Load Application
         * return application constructor
         */
       Siteheart.widgetStart = [];
       Siteheart.widget = function(Name, initParams, noDev){
       
       	 NamePath = Siteheart.DEBUG && !noDev ? Name + 'dev' : Name;
       	 
         var app = {constructor : null};

            if(!(Name in Siteheart)){

                  if(typeof(Siteheart.widgetStart[Name.toLowerCase()]) == 'undefined')
                        Siteheart.addJS('/apps/' + NamePath.toLowerCase() + '/js/app.start.js' + '?v=' + Siteheart.VERSION );

                   Siteheart.onEvent(Siteheart, Name +'.isready', function(){
                       app.constructor = new Siteheart[Name](initParams);
                       app.constructor.init();
                    });

            }else{

             app.constructor = new Siteheart[Name](initParams);
             app.constructor.init();

            }

            Siteheart.widgetStart[Name.toLowerCase()] = 1;

         return app;
       };




        /**
         * @description Load Application Plugin
         * return plugin constructor
         */
       Siteheart.pluginsStart = [];
       Siteheart.plugin = function(app, Name, initParams){
       	
       	var appname = Siteheart.DEBUG ? app.name + 'dev' : app.name;

         var plugin = {constructor : null};

            if(!("Plugin" + Name in Siteheart)){

                  if(typeof(Siteheart.pluginsStart[Name.toLowerCase()]) == 'undefined')
                        Siteheart.addJS('/apps/' + appname + '/js/plugins/plugin.' + Name.toLowerCase() + '.js?v=' + Siteheart.VERSION);

                   Siteheart.onEvent(Siteheart, "Plugin" + Name + '.isready', function(){
                       plugin.constructor = new Siteheart["Plugin" + Name](app, initParams);
                       plugin.constructor.init();
                       app[Name] = plugin.constructor;
                    });

            }else{

             plugin.constructor = new Siteheart["Plugin" + Name](app, initParams);
             plugin.constructor.init();
              app[Name] = plugin.constructor;

            }

            Siteheart.pluginsStart[Name.toLowerCase()] = 1;

         return plugin;
       };
       
       
       
        Siteheart.tmplLoad = function(widget, template, callback){
   	
	   	     $.get(Siteheart.HOST + '/apps/' + widget + '/tmpl/' + template + '.html?v=' + Siteheart.VERSION, function(tpl){
	   	     	
	   	     	        var re = new RegExp('<template name="([a-zA-Z_]*)"[^>]*>(.*?)</template>','gi');
			    		var template;
			    		tpl = tpl.replace( /[\r\t\n]/g, "" ).replace(/\s{2,}/g, ' ').replace(/>\s</g, '><');		    		
			    	
			    		while ((template = re.exec(tpl)) != null)
			    					$.template(template[1], template[2]);		    		
	   	     	
	   	                if(typeof(callback) == 'function')callback();	
	   	     });
   	     
         };


       if(!Siteheart.resizeInit){
           Siteheart.WResize = (window.onresize || null);
           window.onresize = function(){
               if(typeof(Siteheart.WResize) == 'function'){ Siteheart.WResize();}
               Siteheart.callEvent(Siteheart, 'window.resize');
           };
       }
       Siteheart.resizeInit = true;
      }

