text: /**
   * @author alexander.farkas
   * 
   * @version 2.5.4
   * project site: http://plugins.jquery.com/project/AjaxManager
   */
  (function($){
  	$.support.ajax = !!(window.XMLHttpRequest);
  	if(window.ActiveXObject){
  		try{
  			new ActiveXObject("Microsoft.XMLHTTP");
  			$.support.ajax = true;
  		} catch(e){
  			if(window.XMLHttpRequest){
  				$.ajaxSetup({xhr: function(){
  					return new XMLHttpRequest();
  				}});
  			}
  		}
  	}
  	$.manageAjax = (function(){
  		var cache 			= {},
  			queues			= {},
  			presets 		= {},
  			activeRequest 	= {},
  			allRequests 	= {},
  			triggerEndCache = {},
  			defaults 		= {
  						queue: true, //clear
  						maxRequests: 1,
  						abortOld: false,
  						preventDoubbleRequests: true,
  						cacheResponse: false,
  						complete: function(){},
  						error: function(ahr, status){
  							var opts = this;
  							if(status && status.indexOf('error') != -1){
  								setTimeout(function(){
  									var errStr = status +': ';
  									if(ahr.status){
  										errStr += 'status: '+ ahr.status +' | ';
  									}
  									errStr += 'URL: '+ opts.url;
  									throw new Error(errStr);
  								}, 1);
  							}
  						},
  						success: function(){},
  						abort: function(){}
  				}
  		;
  		
  		function create(name, settings){
  			var publicMethods = {};
  			presets[name] = presets[name] ||
  				{};
  			
  			$.extend(true, presets[name], $.ajaxSettings, defaults, settings);
  			
  			if(!allRequests[name]){
  				allRequests[name] 	= {};
  				activeRequest[name] = {};
  				activeRequest[name].queue = [];
  				queues[name] 		= [];
  				triggerEndCache[name] = [];
  			}
  			$.each($.manageAjax, function(fnName, fn){
  				if($.isFunction(fn) && fnName.indexOf('_') !== 0){
  					publicMethods[fnName] = function(param, param2){
  						if(param2 && typeof param === 'string'){
  							param = param2;
  						}
  						fn(name, param);
  					};
  				}
  			});
  			return publicMethods;
  		}
  		
  		function complete(opts, args){
  			
  			if(args[1] == 'success' || args[1] == 'notmodified'){
  				opts.success.apply(opts, [args[0].successData, args[1]]);
  				if (opts.global) {
  					$.event.trigger("ajaxSuccess", args);
  				}
  			}
  			
  			if(args[1] === 'abort'){
  				opts.abort.apply(opts, args);
  				if(opts.global){
  					$.active--;
  					$.event.trigger("ajaxAbort", args);
  				}
  			}
  			
  			opts.complete.apply(opts, args);
  			
  			if (opts.global) {
  				$.event.trigger("ajaxComplete", args);
  			}
  			
  			if (opts.global && ! $.active){
  				$.event.trigger("ajaxStop");
  			}
  			//args[0] = null; 
  		}
  		
  		function proxy(oldFn, fn){
  			return function(xhr, s, e){
  				fn.call(this, xhr, s, e);
  				oldFn.call(this, xhr, s, e);
  				xhr = null;
  				e = null;
  			};
  		}
  		
  					
  		function callQueueFn(name){
  			var q = queues[name];
  			if(q && q.length){
  				var fn = q.shift();
  				if(fn){
  					fn();
  				}
  			}
  		}
  
  		
  		function add(name, opts){
  			if(!presets[name]){
  				create(name, opts);
  			}
  			opts = $.extend({}, presets[name], opts);
  			//aliases
  			var allR 	= allRequests[name],
  				activeR = activeRequest[name],
  				queue	= queues[name];
  			
  			var id 				= opts.type +'_'+ opts.url.replace(/\./g, '_'),
  				triggerStart 	= true,
  				oldComplete 	= opts.complete,
  				ajaxFn 			= function(){
  									activeR.queue.push(id);
  									activeR[id] = {
  										xhr: false,
  										ajaxManagerOpts: opts
  									};
  									activeR[id].xhr = $.ajax(opts);
  									return id;
  								}
  				;
  				
  			if(opts.data){
  				id += (typeof opts.data == 'string') ? opts.data : $.param(opts.data);
  			}
  			
  			if(opts.preventDoubbleRequests && allRequests[name][id]){
  				return false;
  			}
  			
  			allR[id] = true;
  			
  			opts.complete = function(xhr, s, e){
  				var triggerEnd = true;
  				if(opts.abortOld){
  					$.each(activeR.queue, function(i, activeID){
  						if(activeID == id){
  							return false;
  						}
  						abort(name, activeID);
  						return activeID;
  					});
  				}
  				oldComplete.call(this, xhr, s, e);
  				//stop memory leak
  				if(activeRequest[name][id]){
  					if(activeRequest[name][id] && activeRequest[name][id].xhr){
  						activeRequest[name][id].xhr = null;
  					} 
  					activeRequest[name][id] = null;
  				}
  				triggerEndCache[name].push({xhr: xhr, status: s});
  				xhr = null;
  				activeRequest[name].queue = $.grep(activeRequest[name].queue, function(qid){
  					return (qid !== id);
  				});
  				allR[id] = false;
  				
  				e = null;
  				
  				delete activeRequest[name][id];
  				
  				$.each(activeR, function(id, queueRunning){
  					if(id !== 'queue' || queueRunning.length){
  						triggerEnd = false;
  						return false;
  					}
  				});
  				
  				if(triggerEnd){
  					$.event.trigger(name +'End', [triggerEndCache[name]]);
  					$.each(triggerEndCache[name], function(i, cached){
  						cached.xhr = null; //memory leak
  					});
  					triggerEndCache[name] = [];
  				}
  			};
  			
  			if(cache[id]){
  				ajaxFn = function(){
  					activeR.queue.push(id);
  					complete(opts, cache[id]);
  					return id;
  				};
  			} else if(opts.cacheResponse){
  				 opts.complete = proxy(opts.complete, function(xhr, s){
  					if( s !== "success" && s !== "notmodified" ){
  						return false;
  					}
  					cache[id][0].responseXML 	= xhr.responseXML;
  					cache[id][0].responseText 	= xhr.responseText;
  					cache[id][1] 				= s;
  					//stop memory leak
  					xhr = null;
  					return id; //strict
  				});
  				
  				opts.success = proxy(opts.success, function(data, s){
  					cache[id] = [{
  						successData: data,
  						ajaxManagerOpts: opts
  					}, s];
  					data = null;
  				});
  			}
  			
  			ajaxFn.ajaxID = id;
  			
  			$.each(activeR, function(id, queueRunning){
  				if(id !== 'queue' || queueRunning.length){
  					triggerStart = false;
  					return false;
  				}
  			});
  			
  			if(triggerStart){
  				$.event.trigger(name +'Start');
  			}
  			if(opts.queue){
  				opts.complete = proxy(opts.complete, function(){
  					
  					callQueueFn(name);
  				});
  				 
  				if(opts.queue === 'clear'){
  					queue = clear(name);
  				}
  				
  				queue.push(ajaxFn);
  				
  				if(activeR.queue.length < opts.maxRequests){
  					callQueueFn(name); 
  				}
  				return id;
  			}
  			
  			
  			
  			return ajaxFn();
  		}
  		
  		function clear(name, shouldAbort){
  			$.each(queues[name], function(i, fn){
  				allRequests[name][fn.ajaxID] = false;
  			});
  			queues[name] = [];
  			
  			if(shouldAbort){
  				abort(name);
  			}
  			return queues[name];
  		}
  		
  		function getXHR(name, id){
  			var ar = activeRequest[name];
  			if(!ar || !allRequests[name][id]){
  				return false;
  			}
  			if(ar[id]){
  				return ar[id].xhr;
  			}
  			var queue = queues[name],
  				xhrFn;
  			$.each(queue, function(i, fn){
  				if(fn.ajaxID == id){
  					xhrFn = [fn, i];
  					return false;
  				}
  				return xhrFn;
  			});
  			return xhrFn;
  		}
  		
  		function abort(name, id){
  			var ar = activeRequest[name];
  			if(!ar){
  				return false;
  			}
  			function abortID(qid){
  				if(qid !== 'queue' && ar[qid] && ar[qid].xhr){
  					try {
  						ar[qid].xhr.abort();
  					} catch(e){}
  					complete(ar[qid].ajaxManagerOpts, [ar[qid].xhr, 'abort']);
  				}
  				return null;
  			}
  			if(id){
  				return abortID(id);
  			}
  			return $.each(ar, abortID);
  		}
  		
  		function unload(){
  			$.each(presets, function(name){
  				clear(name, true);
  			});
  			cache = {};
  		}
  		
  		return {
  			defaults: 		defaults,
  			add: 			add,
  			create: 		create,
  			cache: 			cache,
  			abort: 			abort,
  			clear: 			clear,
  			getXHR: 		getXHR,
  			_activeRequest: activeRequest,
  			_complete: 		complete,
  			_allRequests: 	allRequests,
  			_unload: 		unload
  		};
  	})();
  	//stop memory leaks
  	$(window).unload($.manageAjax._unload);
  })(jQuery);