var saplo = {
	
	version: '2.0.0',
		
	cloudbase_uri: 'http://cloudbase3.s3.amazonaws.com/',
	widgetapi_uri: 'https://widget.saplo.com/endpoint/',
	adminpanel_uri: 'https://widget.saplo.com/auth/login/',
	
	site_uri: "",
	base_uri: "",
	
	site_uri_hash: "",
	base_uri_hash: "",
	
	article_text: "", //trimmed and normalized spaces
	text_hash: "", //MD5 of article_text
	
	main_settings: undefined,
	settings: undefined,
	results: undefined,
	
	init_interval: null,
	settings_interval: null,
	results_interval: null,
	
	settings_interval_count: 0,
	
	auto_update_on: false,
	auto_update_stop: false,
	auto_update_interval: null,
	auto_update_stop_interval: null,
	auto_make_results_interval: null,
	auto_make_results_stop_interval: null,
	
	admin_interface_loaded: false,
	admin_panel_in: false,
	
	data_old_struct: false,
	
	tagsBrand: false,
	matchBrand: false,
	
	tagResultExists: -1,
	matchResultExists: -1,
	topicResultExists: -1,
	
	load_sent: false,
	
	cloudbase_request_limit: 5,
	cloudbase_requests: 0,
	
	api_request_limit: 5,
	api_requests: 0,
	
	/**
	 * Get main settings file from cloudbase and run the callback until its fetched or stopped.
	 */
	main: function() {
		
		saplo.site_uri = saplo.utils.strip_uri(document.URL);
		saplo.site_uri_hash = saplo.MD5.hex_md5(saplo.site_uri);

		saplo.base_uri = document.domain;
		saplo.base_uri_hash = saplo.MD5.hex_md5(saplo.base_uri);
		
		var tmp_site_uri = saplo.site_uri.replace('https://','').replace('http://','').replace('/','');
		if(tmp_site_uri == document.domain) {
			return false;
		}
		
		saplo.s3_request(saplo.cloudbase_uri, "main_settings");
		saplo.init_interval = setInterval(saplo.check_main_settings, 100);
	},
	
	check_main_settings: function() {
		
		if(saplo.main_settings !== undefined && saplo.main_settings.servicesOn === 1) {

			clearInterval(saplo.init_interval);
			saplo.init();

		}else if(saplo.main_settings !== undefined && saplo.main_settings.servicesOn === 0) {

			clearInterval(saplo.init_interval);
			return false;
		}else {
			return false;
		}
			
	},
	
	init: function() {
		
		saplo.text_hash = saplo.get_text_hash();
		if(saplo.text_hash === false)
			return false;
		
		if(window.location.hash === "#saplowidget" || saplo.utils.getCookie('saplowidget') === 'true') {
		
			saplo.init_admin_interface();
		
			if(saplo.utils.getCookie('saplowidget') == null) {
				document.cookie = 'saplowidget=true';
			}
		}
		
		saplo.get_settings();
		
	},
	
	/**
	 * Gets the settings stored on Saplo Cloudbase
	 * (called by init)
	 * (runs callback function store_settings)
	 */
	get_settings: function() {

		saplo.s3_request(saplo.cloudbase_uri, saplo.base_uri_hash);
		saplo.settings_interval = setInterval(saplo.set_settings, 100);
		
	},
	
	/**
	 * Callback function for get_settings. Stores the settings
	 * to a variable and gets the results for specified uri.
	 */
	set_settings: function() {
		
		saplo.settings_interval_count++;
		
		if(saplo.settings != undefined) {
			
			clearInterval(saplo.settings_interval);

			if(saplo.settings.general.servicesOn === 1) {
				
				saplo.get_results();
				
			}
			
		}else if(saplo.settings_interval_count > 3){
			clearInterval(saplo.settings_interval);
		}
		
	},
	
	/**
	 * Gets the results stored on Saplo Cloudbase.
	 * (called by get_settings)
	 * (runs callback function store_results)
	 */
	get_results: function(url_hash) {
		
		if(url_hash == undefined) {
			url_hash = saplo.site_uri_hash;
		}
		saplo.s3_request(saplo.cloudbase_uri, url_hash);
		saplo.results_interval = setInterval('saplo.set_results()', 300);
	},
	
	
	/**
	 * Callback function for get_results. Stores the results
	 * to a variable and prints it to the DOM.
	 * (runs print_results or make_results)
	 */
	set_results: function() {
		clearInterval(saplo.results_interval);
		var make_results = false;
	
		if(saplo.results != undefined && saplo.results.general != undefined) {

			saplo.flush_screen();
			
			if(saplo.results.general.references != undefined && saplo.results.general.references.original_url_hash != undefined) {
				if(saplo.site_uri_hash == saplo.results.general.references.original_url_hash) {
					return false;
				}
				saplo.get_results(saplo.results.general.references.original_url_hash);
			}
			
			if(saplo.results.general.textHash != undefined && saplo.results.general.textHash !== saplo.text_hash) {
				make_results = true;
			}
			
			if(saplo.settings.general.tagsOn == 1 && saplo.results.tags != undefined && saplo.results.tags.length > 0) {

				saplo.print_tags();
				saplo.tagResultExists = 1;

			}else if(saplo.settings.general.tagsOn == 1 && (saplo.results.tags == undefined || saplo.results.tags.length == 0)){
				make_results = true;
				saplo.tagResultExists = 0;
			}

			if(saplo.settings.general.matchOn == 1 && saplo.results.similarArticles != undefined && saplo.results.similarArticles.length > 0) {

				saplo.print_similar_articles();
				saplo.matchResultExists = 1;

			}else if(saplo.settings.general.matchOn == 1 && (saplo.results.similarArticles == undefined || saplo.results.similarArticles.length == 0)) {
				make_results = true;
				saplo.matchResultExists = 0;
			}
				
			if(saplo.settings.general.topicsOn == 1 && saplo.results.topics != undefined && saplo.results.topics.length > 0) {

				saplo.topicResultExists = 1;

			}else if(saplo.settings.general.topicsOn == 1 && (saplo.results.topics == undefined || saplo.results.topics.length == 0)) {
				make_results = true; 
				saplo.topicResultExists = 0;
			}
			
			
		}else {
			make_results = true;			
		}
	
		if(make_results === true && saplo.auto_update_on === false && saplo.auto_update_stop === false) {
			
			if(saplo.results == undefined || (saplo.results.general.stopUpdate != undefined && saplo.results.general.stopUpdate == 0)) {
				if(saplo.topicResultExists != 1 && saplo.tagResultExists != 1 && saplo.matchResultExists != 1)
					saplo.make_results();
			}
		}
		
		if(!saplo.load_sent && saplo.settings.general.loadMultiplier != undefined && saplo.settings.general.loadMultiplier > 0) {
			//saplo.load();
			saplo.load_sent = true;
		}
		
	},
	
	make_results: function() {

		if((saplo.results != undefined && saplo.results.general.stopUpdate == 1) || saplo.settings == undefined)
			return false;

		if(window.saplo_extension_post != undefined && saplo.settings.general.postAllowed == 1) {
		
			saplo_extension_post.postArticle();
		
		}else {
			
			//Check which services that has no results
			var missingResults = "";
			
			if(saplo.tagResultExists == 0) {
				missingResults = missingResults + 'tags,';
			}
			if(saplo.matchResultExists == 0) {
				missingResults = missingResults + 'match,'; 
			}
			if(saplo.topicResultExists == 0) {
				missingResults = missingResults + 'topic'; 
			}
			
			

			var params = {
					"method" : 'make_results',
					"shash" : saplo.base_uri_hash,
					"uhash" : saplo.site_uri_hash,
					"url" : encodeURIComponent(saplo.site_uri),
					"thash" : saplo.text_hash,
					"services" : missingResults
			};

			saplo.api_request(saplo.widgetapi_uri, params);
	
		}
		

		/**
		 * Just runs the auto update if no results at all exists.
		 */
//		if((saplo.settings.general.topicsOn == 1 && saplo.topicResultExists == 0) && (saplo.settings.general.tagsOn == 1 && saplo.tagResultExists == 0) && (saplo.settings.general.matchOn == 1 && saplo.matchResultExists == 0) && saplo.auto_update_on == false && saplo.auto_update_stop == false) {
//			saplo.start_auto_update();
//			saplo.start_auto_make_results();
//		}
//		
		if(saplo.topicResultExists != 1 && saplo.tagResultExists != 1 && saplo.matchResultExists != 1 && saplo.auto_update_on == false && saplo.auto_update_stop == false) {
			saplo.start_auto_update();
			saplo.start_auto_make_results();
		}
		
	},
	
	/** 
	 * Starts an auto check against amazon to see if any results have been added.
	 * This increases cost and don't really add that much value to the script when
	 * it is running live on sites. Though might be good in demo purpose.
	 */
	start_auto_update: function() {
		saplo.auto_update_on = true;
		saplo.auto_update_interval = setInterval('saplo.get_results()', 12000);
		saplo.auto_update_stop_interval = setInterval(saplo.stop_auto_update, 14000);
	},
	
	stop_auto_update: function() {
		saplo.auto_update_on = false;
		saplo.auto_update_stop = true;
		clearInterval(saplo.auto_update_interval);
		clearInterval(saplo.auto_update_stop_interval);
	},
	
	start_auto_make_results: function() {
		saplo.auto_make_results_interval = setInterval('saplo.make_results()', 6000);
		saplo.auto_make_results_stop_interval = setInterval('saplo.stop_auto_make_results()', 8000);
	},
	
	stop_auto_make_results: function() {
		clearInterval(saplo.auto_make_results_interval);		
		clearInterval(saplo.auto_make_results_stop_interval);
	},
	
	/**/
	
	// load: function() {
	// 	
	// 	var load_multiplier = saplo.settings.general.loadMultiplier;
	// 	
	// 	if(load_multiplier != 1 || saplo.settings == undefined || saplo.results == undefined)
	// 		return false;
	// 	
	// 	if(Math.random()*load_multiplier <= 1) {
	// 		
	// 		var params = {
	// 			'method' : 'load',
	// 			'url' : encodeURIComponent(saplo.site_uri),
	// 			'uhash' : saplo.site_uri_hash,
	// 			'shash' : saplo.base_uri_hash,
	// 			'tag_results' : saplo.tagResultExists,
	// 			'topic_results' : saplo.topicResultExists,
	// 			'match_results' : saplo.matchResultExists				
	// 		};
	// 
	// 		saplo.api_request(saplo.widgetapi_uri, params);
	// 	}
	// 
	// },
	
	click_tag: function(element) {
		
		var click_multiplier = saplo.settings.general.clickMultiplier;
		var url_dest = jQuery(element).attr("href");
		
		if(Math.random()*click_multiplier <= 1 && click_multiplier > 0) {
			var parentElement = jQuery(element).parent();
			var parentElementId = parentElement.attr("id");
			var service_id = 1;
			
			var params = "";
			var method = "";
	
	
			var tag_id = parentElement.attr("tag_id");	
	
	
			var params = {
					"method" : 'click',
					"shash" : saplo.base_uri_hash,
					"url" : encodeURIComponent(saplo.site_uri),
					"durl" : encodeURIComponent(url_dest),
					"cid" : saplo.results.general.corpusId,
					"aid" : saplo.results.general.articleId,
					"iid" : tag_id,
					"sid" : service_id
			};
						
			saplo.api_request(saplo.widgetapi_uri, params);
		}
		setInterval('saplo.go("'+url_dest+'")', 50);
	},
	
	click_match: function(element) {
		
		var click_multiplier = saplo.settings.general.clickMultiplier;	
		var url_dest = jQuery(element).attr("href");
		
		if(Math.random()*click_multiplier <= 1 && click_multiplier > 0) {
			var parentElement = jQuery(element).parent();
			var parentElementId = parentElement.attr("id");
			var service_id = 2;
			
			var params = "";
			var method = "";
	
			jQuery("#"+parentElementId).attr("match_id");
	
			var match_id = jQuery("#"+parentElementId).attr("match_id");//parentElement.attr("match_id");
			
			var params = {
					"method" : 'click',
					"iid" : match_id,
					"sid" : service_id,
					"aid" : saplo.results.general.articleId,
					"cid" : saplo.results.general.corpusId,
					"durl" : encodeURIComponent(url_dest),
					"url" : encodeURIComponent(saplo.site_uri),
					"shash" : saplo.base_uri_hash
			};
		
			saplo.api_request(saplo.widgetapi_uri, params);
		}
		setInterval('saplo.go("'+url_dest+'")', 50);
	},
	
	go: function(url) {
		document.location = url;
	},
	
	s3_request: function(uri, hash) {
		if(saplo.cloudbase_requests >= saplo.cloudbase_request_limit)
			return false;
		
		var saploapiscript = document.createElement('script');
		saploapiscript.type = 'text/javascript';
		saploapiscript.id = 's3_request_script';
		saploapiscript.charset = 'utf-8';
		saploapiscript.src = uri+hash+'.json?'+Math.floor(Math.random()*1000000000000);

		var head = document.getElementsByTagName('head')[0];
		head.appendChild(saploapiscript);
		
		saplo.cloudbase_requests++;
	},

	api_request: function(url, params) {
		if(saplo.api_requests >= saplo.api_request_limit)
			return false;
		
		jQuery.ajax({
			  url: url,
			  data: params,
			  cache: false
		});
		
		saplo.api_requests++;
	},

	print_tags: function() {
	
		jQuery("<ul id=saplo_tags></ul>").appendTo("#saplowidget_tags");

		if(saplo.settings.tags.mainLabelOn == 1) {
			jQuery("<li id=saplo_tags_label></li>").appendTo("#saplo_tags");
			jQuery("<label></label>").appendTo("#saplo_tags_label").append(saplo.settings.tags.mainLabel);
		}

		var lastDelimiterId;

		for(i in saplo.results.tags){

			if(saplo.settings.general.charset == "latin1" && saplo.data_old_struct == true) {
				var tagWord = saplo.utils.UTF8.decode(saplo.results.tags[i].tagWord);			
			}else {
				var tagWord = saplo.results.tags[i].tagWord;			
			}

			var tagUrl = saplo.check_tag_url(tagWord, saplo.results.tags[i].url);
			//var tagUrl = saplo.check_tag_url(tagWord), saplo.results.tags[i].url);
			var tagTypeId = saplo.results.tags[i].tagTypeId;
			var tagId = saplo.results.tags[i].tagId;

			if(saplo.is_tag_type_on(tagTypeId) == 1 && !saplo.is_tag_in_blacklist(tagWord)) {

				jQuery("<li id=saplo_tag_"+tagId+" class=saplo_tag tag_id="+tagId+"></li>").appendTo("#saplo_tags");
				// jQuery("<a class=saplo_tag_link href="+tagUrl+"></a>").click(function(){
				// 	saplo.click_tag(this);
				// 	$(this).removeAttr("href");
				// }).append(tagWord).appendTo("#saplo_tag_"+tagId);
				jQuery("<a class=saplo_tag_link href="+tagUrl+"></a>").append(tagWord).appendTo("#saplo_tag_"+tagId);
				jQuery("<span id=delimiter_tag_"+tagId+"></span>").append(saplo.settings.tags.tagDelimiter).appendTo("#saplo_tag_"+tagId);
				
				lastDelimiterId = tagId;

			}
		}
		
		jQuery("#delimiter_tag_"+lastDelimiterId).remove();
		
		
		if(saplo.settings.general.brandOn != undefined && saplo.settings.general.brandOn == 1 && saplo.tagsBrand == false) {
			jQuery("<a id=saplo_brand_tags class=saplo_brand href=http://saplo.com></a>").append("by Saplo").appendTo("#saplowidget_tags");
			saplo.tagsBrand = true;
		}
		
		

	},

	print_similar_articles: function() {
		
		jQuery("<ul id=saplo_similar_articles></ul>").appendTo("#saplowidget_match");

		if(saplo.settings.match.mainLabelOn == 1) {
			jQuery("<li id=saplo_similar_articles_label ></li>").appendTo("#saplo_similar_articles");
			jQuery("<label></label>").appendTo("#saplo_similar_articles_label").append(saplo.settings.match.mainLabel);
		}	


		var nbrResults = saplo.settings.match.nbrResults;
		var j = 1;
	
		for(i in saplo.results.similarArticles){
			if(j <= nbrResults) {
				var matchUrl = saplo.results.similarArticles[i].resultPublishUrl;
				var matchId = saplo.results.similarArticles[i].matchId;

				if(saplo.settings.general.charset == "latin1" && saplo.data_old_struct == true) {
					var matchHeadline = saplo.utils.UTF8.decode(saplo.results.similarArticles[i].resultHeadline);
				}else {
					var matchHeadline = saplo.results.similarArticles[i].resultHeadline;
				}
				//var matchHeadline = saplo.results.similarArticles[i].resultHeadline;



				jQuery("<li id=saplo_match_"+matchId+" class=saplo_match match_id="+matchId+"></li>").appendTo("#saplo_similar_articles");

				// jQuery("<a href="+matchUrl+"></a>").click(function() {
				// 	
				// 	saplo.click_match(this);
				// 	$(this).removeAttr("href");
				// 	
				// }).appendTo("#saplo_match_"+matchId).append(matchHeadline);

				jQuery("<a href="+matchUrl+"></a>").appendTo("#saplo_match_"+matchId).append(matchHeadline);				

			}
			
			j++;
		}
		
		if(saplo.settings.general.brandOn != undefined && saplo.settings.general.brandOn == 1 && saplo.matchBrand == false) {
			jQuery("<a id=saplo_brand_match class=saplo_brand href=http://saplo.com></a>").append("by Saplo").appendTo("#saplowidget_match");
			saplo.matchBrand = true;
		}
		
	},
		
	getInnerText: function(e, normalizeSpaces) {
			var textContent = "";
			var trimRe = /^\s+|\s+$/g;
			var normalizeRe = /\s{2,}/g;

			normalizeSpaces = (typeof normalizeSpaces == 'undefined') ? true : normalizeSpaces;
			
			var l = e.length;
			
			for(var i = 0; i < l; i++) {
				
				if (navigator.appName == "Microsoft Internet Explorer") {
					textContent = textContent + " " + e[i].innerText.replace(trimRe, "" );
				}else {
					textContent = textContent + " " + e[i].textContent.replace(trimRe, "" );
				}
			}
			
			if(normalizeSpaces)
				return textContent.replace(normalizeRe, " ");
			else
				return textContent;
	},

	get_text_hash: function() {
				
		var headline = jQuery(".saplo\\:headline");
		var headlineText = jQuery.trim(saplo.getInnerText(headline));
		if(headlineText.length == 0) {
			return false; //Abort if no headline exists.
		}
		
		var lead = jQuery(".saplo\\:lead");
		var leadText = jQuery.trim(saplo.getInnerText(lead));
		
		var body = jQuery(".saplo\\:body");
		var bodyText = jQuery.trim(saplo.getInnerText(body));
		if(bodyText.length == 0) {
			return false; //Abort if no body text exists.
		}
		
		saplo.article_text = jQuery.trim(headlineText+leadText+bodyText);
		
		if(saplo.article_text.length == 0) {
			return false; //Abort if no article exists
		}
		return saplo.MD5.hex_md5(saplo.article_text);
		
		
	},
	
	flush_settings: function() {
		saplo.settings = undefined;
		saplo.cloudbase_requests = 0;
		
		
	},
	
	flush_results: function() {
		saplo.results = undefined;
		saplo.cloudbase_requests = 0;
	},
	
	flush_screen: function() {
		jQuery("#saplo_similar_articles").remove();
		jQuery("#saplo_tags").remove();	
		
		if(saplo.matchBrand) {
			jQuery("#saplo_brand_match").remove();	
			saplo.matchBrand = false;
		}
		if(saplo.tagsBrand) {
			jQuery("#saplo_brand_tags").remove();
			saplo.tagsBrand = false;
		}
		
	},
	
	/**
	 * Checks if a tag has a custom URL
	 * or if we should give it the standard
	 * URL query instead.
	 * 
	 */
	check_tag_url: function(tag, url) {
	
		// var escaped_tag = encodeURIComponent(tag);
		var escaped_tag = escape(tag);
		if(url == "" || url == null || url == undefined) {
			return saplo.settings.tags.searchUrl.replace("[TAG]", escaped_tag);
		}else {
			return url;
		}
	},
	
	is_tag_in_blacklist: function(tag) {
		
		if(saplo.settings.blacklist == undefined) {
			return false;
		}
		
		var count = saplo.settings.blacklist.length;
		
		if(count == 0) {
			return false;
		} 
		
		for(var i = 0; i < count; i++ ) {
			if(saplo.settings.blacklist[i]['word'].toLowerCase() === tag.toLowerCase()) {
				return true;
			}
		}
		return false;
		
	},
	
	is_tag_type_on: function(tagType) {

		if(tagType == 1) {

			return saplo.settings.tags.uncategorizedOn;

		}else if(tagType == 2) {

			return saplo.settings.tags.topicsOn;

		}else if(tagType == 3) {

			return saplo.settings.tags.personsOn;

		}else if(tagType == 4) {

			return saplo.settings.tags.organisationsOn;

		}else if(tagType == 5) {

			return saplo.settings.tags.geonamesOn;

		}else if(tagType == 6) {

			return saplo.settings.tags.productsOn;
		}
	},
	
	init_admin_interface: function() {
		if(!saplo.admin_interface_loaded) {
			saplo.admin_overlay();
			saplo.admin_box();
		}
	},
	
	admin_overlay: function() {
		jQuery('<div></div>').attr("id","saplo_overlay").css("z-index",9999999).css("position", "fixed").appendTo("body").hide();
	},
	
	admin_box: function() {
			
		/* Saplo Admin Container */
		jQuery('<div></div>').attr("id","saplo_admin_frame").css( {
				width : '558px',
				height : 'auto', 
				position : 'fixed',
				top : '60px',
				right : '-525px',
				overflow:'hidden',
				'z-index' : 9999999
		}).appendTo('body');

		jQuery('<div></div>').attr("id","saplo_admin_box").css( {
			width : '518px',
			height : 'auto', 
			overflow:'hidden',
			'float' : 'right',
			margin : 0,
			padding : 0,
			'border-top' : '4px solid #01B0F0',
			'border-bottom' : '4px solid #01B0F0',
			'border-left' : '4px solid #01B0F0',
			'z-index' : 9999
		} ).appendTo('#saplo_admin_frame');

		jQuery('<div></div>').attr("id","saplo_admin_trigger").append("S").appendTo("#saplo_admin_frame")
		.css({
			width : '23px',
			height : '23px',
			'border-left' : '3px solid #01B0F0',
			'border-top' : '3px solid #01B0F0',
			'border-bottom' : '3px solid #01B0F0',
			'float' : 'left',
			'font-size' : '32px',
			'margin-top' : '20px',
			padding : '4px 5px 10px 5px',
			color : '#fff',
			'background-color' : '#000'
		}).click(function(){

			if(saplo.admin_panel_in) {

				//Slide in
		    	jQuery('#saplo_admin_frame').animate({'right':'-525px'},300,function(){
		               jQuery('#saplo_overlay').fadeOut('fast');
		         });
		
				saplo.admin_panel_in = false;
				saplo.flush_settings();
				saplo.flush_results();
				saplo.flush_screen();
				saplo.get_settings();
				
				
				return false;

			}else {

				//Slide out
				jQuery('#saplo_overlay').fadeIn('fast',function(){		
					jQuery('#saplo_admin_frame').animate({'right':'0px'},300);
				});

				if(!saplo.admin_interface_loaded) {
					saplo.admin_load_panel();
				}

				saplo.admin_panel_in = true;
				return false;
			}


		});
		
		
	
		
	},
	
	admin_load_panel: function() {
	
		jQuery('<iframe id="saplo_iframe" src='+saplo.adminpanel_uri+saplo.base_uri_hash+'/'+saplo.site_uri_hash+'/'+saplo.text_hash+' width=517px height=500px>').appendTo('#saplo_admin_box');
		saplo.admin_interface_loaded = true;
	},

	
	utils: {
		
		strip_uri: function(uri){
			
			/* Strip URL from known GET params */
			jQuery.each(['utm_campaign','utm_source','utm_medium','utm_content'], function(key, value) {
				charPosition = uri.search(value);
				if(charPosition != -1){
					uri = uri.split(value)[0];
				}
			});
			
			/* Strip URL from anchor tags */
			charPosition = uri.search('#');
			if(charPosition != -1){
				uri = uri.split('#')[0];
			}
			
			// Check if url ends with ?
			if(uri.charAt(uri.length-1) == "?") {
				uri = uri.split("?")[0];
			}
			
			// Check if url ends with &
			if(uri.charAt(uri.length-1) == "&") {
				uri = uri.split("&")[0];
			}
			
			return uri;
			
		},
		
		getCookie: function(c_name) {
			if (document.cookie.length>0)
			  {
			  c_start=document.cookie.indexOf(c_name + "=");
			  if (c_start!=-1)
			    {
			    c_start=c_start + c_name.length+1;
			    c_end=document.cookie.indexOf(";",c_start);
			    if (c_end==-1) c_end=document.cookie.length;
			    return unescape(document.cookie.substring(c_start,c_end));
			    }
			  }
			return null;
		},

		deleteCookie: function(c_name) {
			var d = new Date();
			document.cookie = c_name +	"=; expires=" + d.toGMTString() + ";" + ";";
		},
		
		/**
		*
		*  UTF-8 data encode / decode
		*  http://www.webtoolkit.info/
		*
		**/
		UTF8: {

			// public method for url encoding
			encode : function (string) {
				string = string.replace(/\r\n/g,"\n");
				var utftext = "";

				for (var n = 0; n < string.length; n++) {

					var c = string.charCodeAt(n);

					if (c < 128) {
						utftext += String.fromCharCode(c);
					}
					else if((c > 127) && (c < 2048)) {
						utftext += String.fromCharCode((c >> 6) | 192);
						utftext += String.fromCharCode((c & 63) | 128);
					}
					else {
						utftext += String.fromCharCode((c >> 12) | 224);
						utftext += String.fromCharCode(((c >> 6) & 63) | 128);
						utftext += String.fromCharCode((c & 63) | 128);
					}

				}

				return utftext;
			},

			// public method for url decoding
			decode : function (str_data) {
				 // Converts a UTF-8 encoded string to ISO-8859-1  
				    // 
				    // version: 1008.1718
				    // discuss at: http://phpjs.org/functions/utf8_decode
				    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
				    // +      input by: Aman Gupta
				    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
				    // +   improved by: Norman "zEh" Fuchs
				    // +   bugfixed by: hitwork
				    // +   bugfixed by: Onno Marsman
				    // +      input by: Brett Zamir (http://brett-zamir.me)
				    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
				    // *     example 1: utf8_decode('Kevin van Zonneveld');
				    // *     returns 1: 'Kevin van Zonneveld'
				    var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0;
				    				    
					str_data += '';
   
   				    while ( i < str_data.length ) {
   				        c1 = str_data.charCodeAt(i);
   				        if (c1 < 128) {
   				            tmp_arr[ac++] = String.fromCharCode(c1);
   				            i++;
   				        } else if ((c1 > 191) && (c1 < 224)) {
   				            c2 = str_data.charCodeAt(i+1);
   				            tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
   				            i += 2;
   				        } else {
   				            c2 = str_data.charCodeAt(i+1);
   				            c3 = str_data.charCodeAt(i+2);
   				            tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
   				            i += 3;
   				        }
   				    }
   
   				    return tmp_arr.join('');

			}

		}
		
		
	},
	
	MD5: {
		
		/*
		 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
		 * Digest Algorithm, as defined in RFC 1321.
		 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
		 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
		 * Distributed under the BSD License
		 * See http://pajhome.org.uk/crypt/md5 for more info.
		 */

		/*
		 * Configurable variables. You may need to tweak these to be compatible with
		 * the server-side, but the defaults work in most cases.
		 */
		hexcase: 0,  /* hex output format. 0 - lowercase; 1 - uppercase        */
		b64pad: "", /* base-64 pad character. "=" for strict RFC compliance   */
		chrsz: 8,  /* bits per input character. 8 - ASCII; 16 - Unicode      */

		/*
		 * These are the functions you'll usually want to call
		 * They take string arguments and return either hex or base-64 encoded strings
		 */
		hex_md5: function (s){ return this.binl2hex(this.core_md5(this.str2binl(s), s.length * this.chrsz));},
		b64_md5: function (s){ return this.binl2b64(this.core_md5(this.str2binl(s), s.length * this.chrsz));},
		str_md5: function (s){ return this.binl2str(this.core_md5(this.str2binl(s), s.length * this.chrsz));},
		hex_hmac_md5: function (key, data) { return this.binl2hex(this.core_hmac_md5(key, data)); },
		b64_hmac_md5: function (key, data) { return this.binl2b64(this.core_hmac_md5(key, data)); },
		str_hmac_md5: function (key, data) { return this.binl2str(this.core_hmac_md5(key, data)); },

		/*
		 * Perform a simple self-test to see if the VM is working
		 */
		md5_vm_test: function ()
		{
		  return this.hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
		},

		/*
		 * Calculate the MD5 of an array of little-endian words, and a bit length
		 */
		core_md5: function (x, len)
		{
		  /* append padding */
		  x[len >> 5] |= 0x80 << ((len) % 32);
		  x[(((len + 64) >>> 9) << 4) + 14] = len;

		  var a =  1732584193;
		  var b = -271733879;
		  var c = -1732584194;
		  var d =  271733878;

		  for(var i = 0; i < x.length; i += 16)
		  {
		    var olda = a;
		    var oldb = b;
		    var oldc = c;
		    var oldd = d;

		    a = this.md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
		    d = this.md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
		    c = this.md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
		    b = this.md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
		    a = this.md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
		    d = this.md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
		    c = this.md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
		    b = this.md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
		    a = this.md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
		    d = this.md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
		    c = this.md5_ff(c, d, a, b, x[i+10], 17, -42063);
		    b = this.md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
		    a = this.md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
		    d = this.md5_ff(d, a, b, c, x[i+13], 12, -40341101);
		    c = this.md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
		    b = this.md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

		    a = this.md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
		    d = this.md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
		    c = this.md5_gg(c, d, a, b, x[i+11], 14,  643717713);
		    b = this.md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
		    a = this.md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
		    d = this.md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
		    c = this.md5_gg(c, d, a, b, x[i+15], 14, -660478335);
		    b = this.md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
		    a = this.md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
		    d = this.md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
		    c = this.md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
		    b = this.md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
		    a = this.md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
		    d = this.md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
		    c = this.md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
		    b = this.md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

		    a = this.md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
		    d = this.md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
		    c = this.md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
		    b = this.md5_hh(b, c, d, a, x[i+14], 23, -35309556);
		    a = this.md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
		    d = this.md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
		    c = this.md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
		    b = this.md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
		    a = this.md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
		    d = this.md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
		    c = this.md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
		    b = this.md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
		    a = this.md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
		    d = this.md5_hh(d, a, b, c, x[i+12], 11, -421815835);
		    c = this.md5_hh(c, d, a, b, x[i+15], 16,  530742520);
		    b = this.md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

		    a = this.md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
		    d = this.md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
		    c = this.md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
		    b = this.md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
		    a = this.md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
		    d = this.md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
		    c = this.md5_ii(c, d, a, b, x[i+10], 15, -1051523);
		    b = this.md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
		    a = this.md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
		    d = this.md5_ii(d, a, b, c, x[i+15], 10, -30611744);
		    c = this.md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
		    b = this.md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
		    a = this.md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
		    d = this.md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
		    c = this.md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
		    b = this.md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

		    a = this.safe_add(a, olda);
		    b = this.safe_add(b, oldb);
		    c = this.safe_add(c, oldc);
		    d = this.safe_add(d, oldd);
		  }
		  return Array(a, b, c, d);

		},

		/*
		 * These functions implement the four basic operations the algorithm uses.
		 */
		md5_cmn: function (q, a, b, x, s, t)
		{
		  return this.safe_add(this.bit_rol(this.safe_add(this.safe_add(a, q), this.safe_add(x, t)), s),b);
		},
		md5_ff: function (a, b, c, d, x, s, t)
		{
		  return this.md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
		},
		md5_gg: function (a, b, c, d, x, s, t)
		{
		  return this.md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
		},
		md5_hh: function (a, b, c, d, x, s, t)
		{
		  return this.md5_cmn(b ^ c ^ d, a, b, x, s, t);
		},
		md5_ii: function (a, b, c, d, x, s, t)
		{
		  return this.md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
		},

		/*
		 * Calculate the HMAC-MD5, of a key and some data
		 */
		core_hmac_md5: function (key, data)
		{
		  var bkey = this.str2binl(key);
		  if(bkey.length > 16) bkey = this.core_md5(bkey, key.length * this.chrsz);

		  var ipad = Array(16), opad = Array(16);
		  for(var i = 0; i < 16; i++)
		  {
		    ipad[i] = bkey[i] ^ 0x36363636;
		    opad[i] = bkey[i] ^ 0x5C5C5C5C;
		  }

		  var hash = this.core_md5(ipad.concat(this.str2binl(data)), 512 + data.length * this.chrsz);
		  return this.core_md5(opad.concat(hash), 512 + 128);
		},

		/*
		 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
		 * to work around bugs in some JS interpreters.
		 */
		safe_add: function (x, y)
		{
		  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
		  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
		  return (msw << 16) | (lsw & 0xFFFF);
		},

		/*
		 * Bitwise rotate a 32-bit number to the left.
		 */
		bit_rol: function (num, cnt)
		{
		  return (num << cnt) | (num >>> (32 - cnt));
		},

		/*
		 * Convert a string to an array of little-endian words
		 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
		 */
		str2binl: function (str)
		{
		  var bin = Array();
		  var mask = (1 << this.chrsz) - 1;
		  for(var i = 0; i < str.length * this.chrsz; i += this.chrsz)
		    bin[i>>5] |= (str.charCodeAt(i / this.chrsz) & mask) << (i%32);
		  return bin;
		},

		/*
		 * Convert an array of little-endian words to a string
		 */
		binl2str: function (bin)
		{
		  var str = "";
		  var mask = (1 << this.chrsz) - 1;
		  for(var i = 0; i < bin.length * 32; i += this.chrsz)
		    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
		  return str;
		},

		/*
		 * Convert an array of little-endian words to a hex string.
		 */
		binl2hex: function (binarray)
		{
		  var hex_tab = this.hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
		  var str = "";
		  for(var i = 0; i < binarray.length * 4; i++)
		  {
		    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
		           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
		  }
		  return str;
		},

		/*
		 * Convert an array of little-endian words to a base-64 string
		 */
		binl2b64: function (binarray)
		{
		  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
		  var str = "";
		  for(var i = 0; i < binarray.length * 4; i += 3)
		  {
		    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
		                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
		                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
		    for(var j = 0; j < 4; j++)
		    {
		      if(i * 8 + j * 6 > binarray.length * 32) str += this.b64pad;
		      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
		    }
		  }
		  return str;
		}
	}
};

function saplodata(response_obj) {
 	saplo.data_old_struct = true;
 	saplo.results = response_obj;
	saplo.set_results();
};

jQuery(document).ready(function() {
     saplo.main();
});
