Strategy Game Free Online Multiplayer Strategy Games | eRepublik < type="text/java " async="" src="./index_files/ga.js">< src="./index_files/jquery.min.js"> < > .jQuery || document.write("< src='js/jquery-1.4.2.min.js'>\x3C/ >") < type="text/java " src="./index_files/jquery.cookie.min.js"> < > var hostname = 'www.erepublik.com'; var domainname = 'erepublik.com'; var economyhostname = 'economy.erepublik.com'; var _tutorial_enabled = false; var $j = jQuery.noConflict(); var WRInitTime=(new Date()).getTime(); // ClickTale if (top !=self) { top. =self. ; } < type="text/java "> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-2001550-1']); _gaq.push(['_trackPageview']); _gaq.push(['_trackPageview', '/homeLoggedOut']); _gaq.push(['_trackPageLoadTime']); var Size = [0,0]; if( typeof( .innerWidth ) == 'number' ) { Size = [ .innerWidth, .innerHeight ]; } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { Size = [ document.documentElement.clientWidth, document.documentElement.clientHeight ]; } _gaq.push([ '_trackEvent', 'Resolution', ' size VS Screen size', Size[0] + ' x ' + Size[1] + ' vs ' + screen.width + ' x ' + screen.height ]); (function() { var ga = document.createElement(' '); ga.type = 'text/java '; ga.async = true; ga.src = ('https:' == document. .protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName(' ')[0]; s.parentNode.insertBefore(ga, s); })();

Forgot password

What if the financial crisis REALLY goes bad?

Sign up

Features

Top countries

What others are saying

< async="" src="./index_files/all.js">
< type="text/java "> .fbAsyncInit = function() { FB.init({ appId: '300511377223', status: true, cookie: true, xfbml: true //channelUrl: 'http://www.erepublik.com/xd_receiver.htm' /* fb didn't fix this yet :( */ }); }; (function() { var e = document.createElement(' '); e.async = true; e.src = document. .protocol + '//connect.facebook.net/en_US/all.js'; document.getElementById('fb-root').appendChild(e); }()); < src="./index_files/jquery.infieldlabel.min.js"> < > var ambient_img = "home_bg.jpg"; function loadAmbient() { var cssDef = { 'background-image': 'url(http://'+hostname+'/images/modules/ambients/external/'+ambient_img+')', 'background-repeat': 'no-repeat', 'background-position': 'center top' } $j("body").css(cssDef); } . = function () { loadAmbient(); } $j(document).ready(function() { document.getElementsByTagName('html')[0].style.display='block'; $j("label").inFieldLabels(); $j('#citizen_email, #citizen_password').focus(function() { $j('.hidden_opts').slideDown('fast'); }); }); < > var pkyk = 0; < src="./index_files/jquery.min.js">< >(function initializePersistence() { var pulse_queue = null; var queue_data = null; var pulse_version = "1.1.14"; function parseVersionString (str) { if (typeof(str) != 'string') { return false; } var x = str.split('.'); // parse from string or default to 0 if can't parse var maj = parseInt(x[0]) || 0; var min = parseInt(x[1]) || 0; var pat = parseInt(x[2]) || 0; return { major: maj, minor: min, patch: pat } } function isGreateVersion(o_current, o_new) { if (o_new.major > o_current.major) return true; if (o_new.major < o_current.major) return false; if (o_new.minor > o_current.minor) return true; if (o_new.minor < o_current.minor) return false; return (o_new.patch > o_current.patch); } function checkNewVersion() { $j.ajax({ type: 'GET', //url: 'http://egov4you.info/PulseWS/version.txt', url: 'http://78.47.49.140:81/index.php/PulseWS/version.txt', cache: true, timeout: 2000, success: function(data) { if (typeof(data != 'string')) { var o_current = parseVersionString(pulse_version); var o_new = parseVersionString(data); //if (1 == 1) { if (isGreateVersion(o_current, o_new)) { $("#pulse_new_version").attr("style","float: right; width: 20px; height: 20px; z-index: 100; background: url('http://78.47.49.140:81/PulseWS/img/excla2.gif') no-repeat;"); $("#pulse_logo").attr("title","There's a new version available to download! Click to download."); $("#pulse_version").attr("title","There's a new version available to download! Click to download."); } } }, error:function (xhr, ajaxOptions, thrownError) { } }); /* $.get('http://egov4you.info/PulseWS/img/version.php', function(data) { if (typeof(data != 'string')) { var o_current = parseVersionString(pulse_version); var o_new = parseVersionString(data); //if (1 == 1) { if (isGreateVersion(o_current, o_new)) { $("#pulse_new_version").attr("style","float: right; width: 20px; height: 20px; background: url('http://egov4you.info/PulseWS/img/excla2.gif') no-repeat;"); $("#pulse_logo").attr("title","There's a new version available to download! Click to download."); $("#pulse_version").attr("title","There's a new version available to download! Click to download."); } } }); */ } //////////////////////////////////////////////////////////////////////////////////////////////////// function MD5(string) { function RotateLeft(lValue, iShiftBits) { return (lValue<>>(32-iShiftBits)); } function AddUnsigned(lX,lY) { var lX4,lY4,lX8,lY8,lResult; lX8 = (lX & 0x80000000); lY8 = (lY & 0x80000000); lX4 = (lX & 0x40000000); lY4 = (lY & 0x40000000); lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF); if (lX4 & lY4) { return (lResult ^ 0x80000000 ^ lX8 ^ lY8); } if (lX4 | lY4) { if (lResult & 0x40000000) { return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); } else { return (lResult ^ 0x40000000 ^ lX8 ^ lY8); } } else { return (lResult ^ lX8 ^ lY8); } } function F(x,y,z) { return (x & y) | ((~x) & z); } function G(x,y,z) { return (x & z) | (y & (~z)); } function H(x,y,z) { return (x ^ y ^ z); } function I(x,y,z) { return (y ^ (x | (~z))); } function FF(a,b,c,d,x,s,ac) { a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac)); return AddUnsigned(RotateLeft(a, s), b); }; function GG(a,b,c,d,x,s,ac) { a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac)); return AddUnsigned(RotateLeft(a, s), b); }; function HH(a,b,c,d,x,s,ac) { a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac)); return AddUnsigned(RotateLeft(a, s), b); }; function II(a,b,c,d,x,s,ac) { a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac)); return AddUnsigned(RotateLeft(a, s), b); }; function ConvertToWordArray(string) { var lWordCount; var lMessageLength = string.length; var lNumberOfWords_temp1=lMessageLength + 8; var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64; var lNumberOfWords = (lNumberOfWords_temp2+1)*16; var lWordArray=Array(lNumberOfWords-1); var lBytePosition = 0; var lByteCount = 0; while ( lByteCount < lMessageLength ) { lWordCount = (lByteCount-(lByteCount % 4))/4; lBytePosition = (lByteCount % 4)*8; lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<>>29; return lWordArray; }; function WordToHex(lValue) { var WordToHexValue="",WordToHexValue_temp="",lByte,lCount; for (lCount = 0;lCount<=3;lCount++) { lByte = (lValue>>>(lCount*8)) & 255; WordToHexValue_temp = "0" + lByte.toString(16); WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2); } return WordToHexValue; }; function Utf8Encode(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; }; var x=Array(); var k,AA,BB,CC,DD,a,b,c,d; var S11=7, S12=12, S13=17, S14=22; var S21=5, S22=9 , S23=14, S24=20; var S31=4, S32=11, S33=16, S34=23; var S41=6, S42=10, S43=15, S44=21; string = Utf8Encode(string); x = ConvertToWordArray(string); a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476; for (k=0;k 1800000) { b = true; } } catch (exc) {} if (b == true) { setBattleOrders(null); var password = getBattleOrdersPassword(); var citizen_id = getCitizenId(); //var url = 'http://egov4you.info/data/order/' + citizen_id + '/' + password; var url = 'http://egov4you.info/edata/pulse/' + citizen_id + '/' + password; $j.ajax({ type: 'GET', url: url, cache: true, dataType: 'json', timeout: 15000, success: function(data) { setBattleOrders(data); }, error:function (xhr, ajaxOptions, thrownError) { } }); var timestamp = new Date().getTime(); jQuery.jStore.set("pulse-orders-ts", timestamp); } } /* $j.ajax({ type: 'GET', url: 'http://egov4you.info/data/countries', //contentType: 'application/json', cache: true, dataType: 'json', timeout: 7000, success: function(data) { setCountryStats(data); }, error:function (xhr, ajaxOptions, thrownError) { } }); */ } function showDamage() { $("#pulse_daily_damage").slideDown('fast'); } function hideDamage(animate) { if (animate == true) { $("#pulse_daily_damage").slideUp('slow'); } else { $("#pulse_daily_damage").hide(); } } function showBattleOrders() { $("#battleorders_holder").fadeIn('fast'); } function hideBattleOrders(animate) { if (animate == true) { $("#battleorders_holder").fadeOut('slow'); } else { $("#battleorders_holder").hide(); } } function replaceAll( text, busca, reemplaza ){ while (text.toString().indexOf(busca) != -1) text = text.toString().replace(busca,reemplaza); return text; } function filterBattleOrders(message) { message = replaceAll(message, "<", "<"); message = replaceAll(message, ">", ">"); message = replaceAll(message, "[br]", "
"); message = replaceAll(message, "[b]", ""); message = replaceAll(message, "[/b]", ""); message = replaceAll(message, "[u]", ""); message = replaceAll(message, "[/u]", ""); message = replaceAll(message, "[i]", ""); message = replaceAll(message, "[/i]", ""); message = message.replace(/\[battle=([^\]]+)\]([^\]]+)\[\/battle\]/gi, "$2" ); message = message.replace(/\[war=([^\]]+)\]([^\]]+)\[\/war\]/gi, "$2" ); return message; } function renderBattleOrders(data) { if (data == null || data == undefined || data == 'undefined' || data == '') { $("#battleorders_army").html("BATTLE ORDERS"); $("#battleorders_updated").html(""); $("#battleorders_body").html("Press button to get your orders."); return; } if (parseInt(data.order.id) < 0) { $("#battleorders_army").html("BATTLE ORDERS"); $("#battleorders_updated").html(""); $("#battleorders_body").html("There are no battle orders for you.
Ask your army leader to add you to the army's authorized user list."); } else if (parseInt(data.order.id) == 0) { $("#battleorders_army").html("BATTLE ORDERS @ " + filterBattleOrders(data.order.name) + ""); $("#battleorders_updated").html(""); $("#battleorders_body").html("Please enter the army password
 "); } else if (parseInt(data.order.id) > 0) { var day = data.order.day; var time_part = data.order.time.split(" ")[1]; var time = time_part.split(":")[0] + ":" + time_part.split(":")[1]; $("#battleorders_army").html("BATTLE ORDERS @ " + filterBattleOrders(data.order.name) + ""); $("#battleorders_updated").html("Updated " + filterBattleOrders(day + " " + time)); $("#battleorders_body").html("" + filterBattleOrders(data.order.message) + ""); } $("#bs_button").live("click", function() { setBattleOrdersPassword(MD5("e1pa_#181s3#" + $("#bs_pass").val())); updateBattleOrders(); }); showBattleOrders(); } function updateBattleOrders() { var password = getBattleOrdersPassword(); var citizen_id = getCitizenId(); //var url = 'http://egov4you.info/data/order/' + citizen_id + '/' + password; var url = 'http://egov4you.info/edata/pulse/' + citizen_id + '/' + password; $j.ajax({ type: 'GET', url: url, cache: true, dataType: 'json', timeout: 15000, success: function(data) { renderBattleOrders(data); setBattleOrders(data); }, error:function (xhr, ajaxOptions, thrownError) { renderBattleOrders(null); } }); var timestamp = new Date().getTime(); jQuery.jStore.set("pulse-orders-ts", timestamp); } function addDamage() { if (getShowDamage() == false) { hideDamage(false); } else { showDamage(); } } function addBattleOrders() { var citizen_id = getCitizenId(); if (citizen_id == null || citizen_id == undefined || citizen_id == 'undefined' || citizen_id == 0) return; var holder2 = "
"; holder2 += "
 
"; holder2 += "
0 BATTLE ORDERS
"; holder2 += "
"; holder2 += "
"; $("#logo").after(holder2); $("# _orders").click(function() { $("#battleorders_body").html(""); //updateBattleOrders(); setTimeout(updateBattleOrders, 1000); }); if (getShowBattleOrders() == false) { hideBattleOrders(false); } else { var b = false; var ts = 0; try { var timestamp = new Date().getTime(); var timestamp2 = jQuery.jStore.get("pulse-orders-ts"); ts = timestamp - timestamp2; if (timestamp2 == null) { b = true; } else if (ts > 1800000) { b = true; } } catch (exc) {} if (b == true) { if (ts > 10800000) { setBattleOrders(null); } updateBattleOrders(); } else { var sdata = getBattleOrders(); renderBattleOrders(sdata); } } } function addCountryAlliance() { if (typeof(SERVER_DATA) != 'undefined') { var defenderId = SERVER_DATA.defenderId; var invaderId = SERVER_DATA.invaderId; var mustInvert = SERVER_DATA.mustInvert; var country_stats = getCountryStats(); if (typeof(country_stats) != 'undefined') { var dDay = country_stats.day - 1; var dCount = 0; if (country_stats.countries != null && country_stats.countries != undefined && country_stats.countries != 'undefined') { dCount = country_stats.countries.length; } if (dCount > 500) return; for (var ii = 0; ii < dCount; ii++) { var countrybase = country_stats.countries[ii]; var country = null; if (countrybase != null && countrybase != undefined && countrybase != 'undefined') { country = country_stats.countries[ii].country; } var countryId = null; if (country != null && country != undefined && country != 'undefined') { countryId = country_stats.countries[ii].country.id; } if (countryId != null && countryId != undefined && countryId != 'undefined') { if (parseInt(country_stats.countries[ii].country.id) == parseInt(defenderId)) { //$("#defender_allies").after("

" + country_stats.countries[ii].country.a + "

"); //$(".country.left_side").first().after("

" + country_stats.countries[ii].country.a + "

"); $("#left_counter_wrap").first().before("

" + country_stats.countries[ii].country.a + "

"); var fighters = country_stats.countries[ii].country.f; var damage = country_stats.countries[ii].country.t; var fighters_title = "Total players who fighted for " + country_stats.countries[ii].country.n + " in eR day " + dDay; var damage_title = "Total damage made by fighters from " + country_stats.countries[ii].country.n + " in eR day " + dDay; $(".country.left_side").first().after("
Fighters: " + fighters + "
Damage: " + damage + "
egov4you: day " + (dDay + 1) + " 03:00eR
"); $(".country.left_side").css("cursor","pointer"); $(".country.left_side ~ div").css("cursor","pointer"); $(".country.left_side").attr("onclick", "java :popup('http://egov4you.info/country/view/" + defenderId + "')"); } else if (parseInt(country_stats.countries[ii].country.id) == parseInt(invaderId)) { //$("#attacker_allies").after("

proTERRA

"); //$(".country.right_side").first().after("

" + country_stats.countries[ii].country.a + "

"); $("#right_counter_wrap").first().before("

" + country_stats.countries[ii].country.a + "

"); var fighters = country_stats.countries[ii].country.f; var damage = country_stats.countries[ii].country.t; var fighters_title = "Total players who fighted for " + country_stats.countries[ii].country.n + " in eR day " + dDay; var damage_title = "Total damage made by fighters from " + country_stats.countries[ii].country.n + " in eR day " + dDay; $(".country.right_side").first().before("
Fighters: " + fighters + "
Damage: " + damage + "
egov4you: day " + (dDay + 1) + " 03:00eR
"); $(".country.right_side").css("cursor","pointer"); $(".country.right_side ~ div").css("cursor","pointer"); $(".country.right_side").attr("onclick", "java :popup('http://egov4you.info/country/view/" + invaderId + "')"); } } } } else { $("#defender_allies").after("

" + defenderId + "

"); $("#attacker_allies").after("

" + invaderId + "

"); } } } var queue_on = 0; function toggleQueue() { if (queue_on) { stopDequeue(); queue_on = 0; $("#queue_run").text("Start"); $("#queue_run").show(); } else { startDequeue(); queue_on = 1; $("#queue_run").text("Stop"); $("#queue_run").show(); } } function cancelQueue() { stopDequeue(); queue_on = 0; $("#queue_run").text("Start"); $("#queue_run").show(); } function renderPulse(citizen_id) { if ($("#pulse_section_body").length > 0) { return false; } var img_pulse_logo = "http://78.47.49.140:81/PulseWS/img/logo.png"; var pulse_logo = ""; var version = "
Version " + pulse_version + "
 
 
"; var header_styles = "clear: both; margin: 2px; : 1px; background-image: url("/images/modules/citizenprofile/h3bg.png?1305798401"); background-repeat: repeat-x; border: medium none;color: #666666;font-size: 11px;font-weight: bold;height: 20px;line-height: 20px;text-shadow: 0 1px 0 #FFFFFF;"; var show_damage = "

"; show_damage += "Daily damage"; if (getShowDamage() == false) { show_damage += "Show"; } else { show_damage += "Hide"; } show_damage += "

"; var today_header = "
Today
"; var today_info = "
"; today_info += "
Influence: 
" + "" + "
"; today_info += "
Hits: 
" + "" + "
"; today_info += "
"; var today_1_header = "
Yesterday
"; var today_1_info = "
"; today_1_info += "
Influence: 
" + "" + "
"; today_1_info += "
Hits: 
" + "" + "
"; today_1_info += "
"; var damage_section = show_damage; damage_section += "
"; damage_section += today_header + today_info; damage_section += today_1_header + today_1_info; damage_section += "
"; $("#damage_show").live("click", function() { if (getShowDamage() == false) { setShowDamage(true); showDamage(); $("#damage_show").text("Hide"); } else { setShowDamage(false); hideDamage(true); $("#damage_show").text("Show"); } }); var null_div = "
"; var show_battleorders = "

"; show_battleorders += "Battle orders"; if (getShowBattleOrders() == false) { show_battleorders += "Show"; } else { show_battleorders += "Hide"; } show_battleorders += "

"; $("#battleorders_show").live("click", function() { if (getShowBattleOrders() == false) { setShowBattleOrders(true); updateBattleOrders(); $("#battleorders_show").text("Hide"); } else { setShowBattleOrders(false); hideBattleOrders(true); $("#battleorders_show").text("Show"); } }); var queue_info = "

"; queue_info += "
Queue length: 
" + "" + "
Start"; queue_info += "

"; $("#queue_run").live("click", function() { $("#queue_run").hide(); setTimeout(toggleQueue, 500); }); //var pulse_section = "
" + pulse_logo + "
" + version + today_header + today_info + today_1_header + today_1_info + null_div + queue_info + "
"; var pulse_section = "
" + pulse_logo + "
" + version + show_battleorders + damage_section + queue_info + "
"; ////$("#pulse_section_body").attr("style", "visibility: hidden; display: none;"); if ($(".newLogout").length > 0) { $(".newLogout").after(pulse_section); } else { $(".logout").after(pulse_section); } $(".pulse_section").attr("style", "height: auto; margin-top: 11px; margin-left: -3px; -left: 0px; -moz-border-radius: 5px 5px 5px 5px;background-color: #FDFDFD;background-image: url('/images/modules/citizenprofile/activitybg.png?1305798401');background-position: center top;background-repeat: repeat-x;border: 1px solid #F0F0F0;margin-top: 10px; -bottom: 1px;clear: both;color: #4D4D4D;display: inline;float: left; : 1;"); //$(".fight_btn").css("color","#33aa33"); //$(".fight_btn").css("text-shadow","#6374AB 2px 2px 2px"); var strength = $("#fighter_skill").text(); if (strength != undefined && strength != null && strength != "") { strength = parseInt(strength.replace(",","")); var rank_points = $("#rank_min").text().split(" ")[0]; if (rank_points != undefined && rank_points != null && rank_points != "") { rank_points = parseInt(rank_points.replace(",","")); var influence_section = "
Max-hit" + getInfluence(rank_points, strength) + "
"; $("#pvp_battle_area").append(influence_section); } } var link_pulse_button = "http://egov4you.info/campaign/soldier/"; var title_pulse_button = "View your fight stats"; var img_pulse_button = "http://img231.imageshack.us/img231/7091/pulsebutton80white65.png"; var pulse_button = "
Pulse"; $("#pvp").append(pulse_button); $(".pulse_button").attr("style", "background-image: url('" + img_pulse_button + "');background-position: 0 0;background-repeat: no-repeat;bottom: 7px;display: block;height: 46px;position: absolute;right: 112px;text-indent: -9999px;width: 45px;"); try { addDamage(); } catch(err) {} try { addCountryAlliance(); } catch(err) {} try { addBattleOrders(); } catch(err) {} $("div.user_notify > a[href*=jobs]").css("bottom", "-350px"); $("#queue_run").show(); return true; } function lockAndWaitQueue() { var timestamp = new Date().getTime(); var lock = jQuery.jStore.get("pulse-queue-lock"); if (lock == null || lock == undefined || lock == "undefined") { lock = timestamp + 7000; jQuery.jStore.set("pulse-queue-lock", lock); } else { if (timestamp > lock) { lock = timestamp + 7000; jQuery.jStore.set("pulse-queue-lock", lock); } else { setTimeout("lockAndWaitQueue()", 7500); } } } function unlockQueue() { jQuery.jStore.remove("pulse-queue-lock"); } function getToday(day) { var today = jQuery.jStore.get("pulse-" + day); if (today == null || today == undefined || today == "undefined") { return 0; } return today; } function getTodayHits(day) { var today = jQuery.jStore.get("pulse-hits-" + day); if (today == null || today == undefined || today == "undefined") { return 0; } return today; } function addToday(day, influence) { var today = jQuery.jStore.get("pulse-" + day); if (today == null || today == undefined || today == "undefined") { today = 0; } today += influence; jQuery.jStore.set("pulse-" + day, today); } function addTodayHits(day, hits) { var today = jQuery.jStore.get("pulse-hits-" + day); if (today == null || today == undefined || today == "undefined") { today = 0; } today += hits; jQuery.jStore.set("pulse-hits-" + day, today); } function getCountryStats() { return getBattleOrders(); /* var cstats = jQuery.jStore.get("pulse-countrystats"); if (cstats == null || cstats == undefined || cstats == "undefined") { return null; } return cstats; */ } function setCountryStats(cstats) { if (cstats == null || cstats == undefined || cstats == "undefined") { return; } jQuery.jStore.set("pulse-countrystats", cstats); } function setBattleOrdersPassword(pwd) { if (pwd == null || pwd == undefined || pwd == "undefined") { return; } jQuery.jStore.set("pulse-battleorders-pwd", pwd); } function getBattleOrdersPassword() { var pwd = jQuery.jStore.get("pulse-battleorders-pwd"); if (pwd == null || pwd == undefined || pwd == "undefined") { return null; } return pwd; } function setShowBattleOrders(b) { if (b == null || b == undefined || b == "undefined") { return; } jQuery.jStore.set("pulse-battleorders-show", b); } function getShowBattleOrders() { var b = jQuery.jStore.get("pulse-battleorders-show"); if (b == null || b == undefined || b == "undefined") { return false; } return b; } function setShowDamage(b) { if (b == null || b == undefined || b == "undefined") { return; } jQuery.jStore.set("pulse-damage-show", b); } function getShowDamage() { var b = jQuery.jStore.get("pulse-damage-show"); if (b == null || b == undefined || b == "undefined") { return true; } return b; } function setBattleOrders(data) { /* if (data == null || data == undefined || data == "undefined") { return; } */ jQuery.jStore.set("pulse-orders", data); } function getBattleOrders() { var data = jQuery.jStore.get("pulse-orders"); if (data == null || data == undefined || data == "undefined") { return null; } return data; } function addCommas(nStr) { nStr += ''; var x = nStr.split('.'); var x1 = x[0]; var x2 = x.length > 1 ? '.' + x[1] : ''; var rgx = /(\d+)(\d{3})/; while (rgx.test(x1)) { x1 = x1.replace(rgx, '$1' + ',' + '$2'); } return x1 + x2; } function updateTodayOffsetInfo(offset) { var eday = $(".eday strong").text(); var newday = parseInt(eday.replace(",","")) - offset; $("#pulse_today_" + offset).text(getToday(addCommas(newday))); $("#pulse_today_hits_" + offset).text(getTodayHits(addCommas(newday))); } function updateTodayInfo() { var eday = $(".eday strong").text(); $("#pulse_today").text(getToday(eday)); $("#pulse_today_hits").text(getTodayHits(eday)); } var retries = 0; function notifySendErrorRed() { $("#pulse_queue_length").css("color","red"); } function notifySendErrorBlack() { $("#pulse_queue_length").css("color","inherit"); setTimeout(notifySendErrorRed, 350); } function notifySendError() { setTimeout(notifySendErrorBlack, 100); } function updateQueueInfo() { lockAndWaitQueue(); // var qdata = jQuery.jStore.get("pulse-queue-data"); var pqueue = new $.fn.queueCreate(qdata); var qlength = pqueue.getLength(); $("#pulse_queue_length").text(qlength); if (qlength == 0) { queue_on = 0; $("#queue_run").text("Send"); $("#queue_run").css("visibility","hidden"); $("#pulse_queue_length").css("color","inherit"); } else { $("#queue_run").attr("disabled",""); $("#queue_run").css("visibility","visible"); $("#pulse_queue_length").css("color","red"); } unlockQueue(); // } var sent_query_data; function sendData(query_data, backup) { //var url1 = "http://egov4you.info/pulse/kill"; //var url1 = "http://pulsews.no-ip.org/PulseWS/doFight.asfx"; //var url1 = "http://pulse.egov4you.info/PulseWS/doFight.asfx"; //var url2 = "http://pulse.servebeer.com/PulseWS/doFight.asfx"; //var url1 = "http://pulsews.no-ip.org:81/index.php/PulseWS/doFight.asfx"; var url1 = "http://78.47.49.140:81/index.php/PulseWS/doFight.asfx"; //var url2 = "http://pulse.egov4you.info/PulseWS/doFight.asfx"; var url2 = "http://pulse.servebeer.com/PulseWS/doFight.asfx"; if (backup == true) { $.ajax({ type: 'POST', url: url2, cache: false, data: query_data, timeout: 7000 }); return ; } sent_query_data = query_data; $.ajax({ type: 'POST', url: url1, cache: false, data: sent_query_data, timeout: 7000, success: function(data) { //alert(data); if (data == "OK") { updateQueueInfo(); retries = 0; } else if (data == "DUP") { } else if (data == "STOP") { updateQueueInfo(); retries = 0; cancelQueue(); } else { lockAndWaitQueue(); // var qdata = jQuery.jStore.get("pulse-queue-data"); var pqueue = new $.fn.queueCreate(qdata); pqueue.enqueue(sent_query_data); jQuery.jStore.set("pulse-queue-data", pqueue.sliceQueue()); unlockQueue(); // updateQueueInfo(); retries += 1; notifySendError(); } }, error:function (xhr, ajaxOptions, thrownError) { lockAndWaitQueue(); // var qdata = jQuery.jStore.get("pulse-queue-data"); var pqueue = new $.fn.queueCreate(qdata); pqueue.enqueue(sent_query_data); jQuery.jStore.set("pulse-queue-data", pqueue.sliceQueue()); unlockQueue(); // updateQueueInfo(); retries += 1; notifySendError(); } }); } function rebuildQueue() { lockAndWaitQueue(); // var qdata = jQuery.jStore.get("pulse-queue-data"); var pqueue = new $.fn.queueCreate(qdata); var queue_length = pqueue.getLength(); var sdata = ""; var processed = 0; while (processed < queue_length) { var peek = pqueue.dequeue(); sdata += peek; processed += 1; } queue_data = []; pulse_queue = new $.fn.queueCreate(queue_data); jQuery.jStore.set("pulse-queue-data", queue_data); unlockQueue(); // lockAndWaitQueue(); // var parts = sdata.split('", "'); for (var i = 0; i < parts.length; i++) { //alert(parts[i]); var qdata = jQuery.jStore.get("pulse-queue-data"); var pqueue = new $.fn.queueCreate(qdata); pqueue.enqueue(parts[i]); jQuery.jStore.set("pulse-queue-data", pqueue.sliceQueue()); } unlockQueue(); // updateQueueInfo(); } function dequeue() { if (retries > 4) { retries = 0; cancelQueue(); return; } lockAndWaitQueue(); // var qdata = jQuery.jStore.get("pulse-queue-data"); var pqueue = new $.fn.queueCreate(qdata); var queue_length = pqueue.getLength(); if (queue_length > 0) { var peek = pqueue.dequeue(); jQuery.jStore.set("pulse-queue-data", pqueue.sliceQueue()); unlockQueue(); // sendData(peek, false); } else { unlockQueue(); // updateQueueInfo(); } } var queue_timer = null; function stopDequeue() { if (queue_timer != null) { clearInterval(queue_timer); queue_timer = null; } } function startDequeue() { stopDequeue(); lockAndWaitQueue(); // var qdata = jQuery.jStore.get("pulse-queue-data"); var pqueue = new $.fn.queueCreate(qdata); var queue_length = pqueue.getLength(); if (queue_length > 1000) { rebuildQueue(); } else if (queue_length > 0) { queue_timer = setInterval(dequeue, 15000); } unlockQueue(); // } function getAttackerRounds() { if ($(".crowns.no0.left_side").length > 0) return 0; else if ($(".crowns.no1.left_side").length > 0) return 1; else if ($(".crowns.no2.left_side").length > 0) return 2; else if ($(".crowns.no3.left_side").length > 0) return 3; else if ($(".crowns.no4.left_side").length > 0) return 4; else if ($(".crowns.no5.left_side").length > 0) return 5; else if ($(".crowns.no6.left_side").length > 0) return 6; else if ($(".crowns.no7.left_side").length > 0) return 7; else if ($(".crowns.no8.left_side").length > 0) return 8; return -1; } function getDefenderRounds() { if ($(".crowns.no0.right_side").length > 0) return 0; else if ($(".crowns.no1.right_side").length > 0) return 1; else if ($(".crowns.no2.right_side").length > 0) return 2; else if ($(".crowns.no3.right_side").length > 0) return 3; else if ($(".crowns.no4.right_side").length > 0) return 4; else if ($(".crowns.no5.right_side").length > 0) return 5; else if ($(".crowns.no6.right_side").length > 0) return 6; else if ($(".crowns.no7.right_side").length > 0) return 7; else if ($(".crowns.no8.right_side").length > 0) return 8; return -1; } function enableFightButton() { var mode = 2; if (mode == 1) { $("#pvp_actions .action_holder").removeClass("disabled"); $(".fight_btn").css("color","#33aa33"); $(".fight_btn").css("text-shadow","#cccccc 2px 2px 2px"); } else if (mode == 2) { $("#pvp_actions .action_holder").removeClass("disabled"); $('.fight_btn').css('color',''); $('.fight_btn').css('text-shadow',''); } else { $('#pvp_actions .action_holder').removeClass('disabled'); $('.fight_btn').css('color',''); $('.fight_btn').css('text-shadow',''); } } function disableFightButton() { var mode = 2; if (mode == 1) { $('#pvp_actions .action_holder').removeClass('disabled'); $('.fight_btn').css('color','#cc3333'); $('.fight_btn').css('text-shadow','#aaaaaa 2px 2px 2px'); } else if (mode == 2) { $('#pvp_actions .action_holder').addClass('disabled'); $('.fight_btn').css('color','inherit'); $('.fight_btn').css('text-shadow','inherit'); } else { $('#pvp_actions .action_holder').removeClass('disabled'); $('.fight_btn').css('color','inherit'); $('.fight_btn').css('text-shadow','inherit'); } } function main2() { $.ajaxSetup({ global: true, cache: false }); try { queryCountryStats(); } catch(err) {} var citizenId = 0; if (typeof(SERVER_DATA) != 'undefined') { citizenId = SERVER_DATA.citizenId; } else { } var ploaded = renderPulse(citizenId); if (ploaded == false) { return; } var ajax_timeout = null; $j(document).ajaxSuccess(function(e, xhr, settings) { if (settings.url.match(/military\/fight-shoot$/)) { var battleId = -1; var instantKill = -1; var citizenName = ""; try { citizenName = escape($(".user_avatar").attr("title")); } catch (err) {} var defenderId = SERVER_DATA.defenderId; var invaderId = SERVER_DATA.invaderId; var isResistance = SERVER_DATA.isResistance; var mustInvert = SERVER_DATA.mustInvert; if (settings.data != null) { var queryStringData = new Array(); var pairs = settings.data.split( "&" ); for ( p in pairs ) { var keyval = pairs[p].split( "=" ); queryStringData[keyval[0]] = keyval[1]; } battleId = queryStringData["battleId"]; battleId = battleId.replace(/[^0-9]/g, ''); instantKill = queryStringData["instantKill"]; if (instantKill == null) { instantKill = 0; } } var responseText = xhr.responseText; var jresp = eval("(" + responseText + ")"); var message = jresp.message; var error = jresp.error; if (!error && message == "ENEMY_KILLED") { var countdown = $("#battle_countdown").text(); var livetime = $("#live_time").text(); var eday = $(".eday strong").text(); var rank = jresp.rank.points; var level = jresp.details.level; var exp = jresp.details.points; var wellness = jresp.details.wellness; var countWeapons = jresp.user.countWeapons; var skill = jresp.user.skill; var weaponDamage = jresp.user.weaponDamage; var weaponDurability = jresp.user.weaponDurability; var givenDamage = jresp.user.givenDamage; var earnedXp = jresp.user.earnedXp; var enemyName = ""; try { enemyName = escape(jresp.oldEnemy.name); } catch (err) {} var enemyIsNatural = 0; if (jresp.oldEnemy.isNatural == true) enemyIsNatural = 1; var domination = $("#blue_domination").text(); if (domination != null && domination != undefined && domination != 'undefined') domination = domination.replace("%", ""); var att_points = SERVER_DATA.points.attacker; var def_points = SERVER_DATA.points.defender; var round = SERVER_DATA.zoneId; var regionName = ""; try { regionName = escape($("#pvp_header h2").text()); } catch (err) {} var att_rounds = getAttackerRounds(); var def_rounds = getDefenderRounds(); var timestamp = new Date().getTime(); var query = ""; query += "citizenId=" + citizenId + "&battleId=" + battleId + "&defenderId=" + defenderId + "&invaderId=" + invaderId; query += "&citizenName=" + citizenName; query += "®ionName=" + regionName + "&mustInvert=" + mustInvert + "&isResistance=" + isResistance; query += "&instantKill=" + instantKill + "&givenDamage=" + givenDamage + "&earnedXp=" + earnedXp; query += "&weaponDamage=" + weaponDamage + "&weaponDurability=" + weaponDurability; query += "&skill=" + skill; query += "&rank=" + rank + "&level=" + level + "&exp=" + exp + "&wellness=" + wellness; query += "&enemyName=" + enemyName + "&enemyIsNatural=" + enemyIsNatural; query += "&countdown=" + countdown + "&livetime=" + livetime + "&eday=" + eday; query += "&domination=" + domination + "&attPoints=" + att_points + "&defPoints=" + def_points; query += "&round=" + round + "&attRounds=" + att_rounds + "&defRounds=" + def_rounds; query += "&version=" + pulse_version; query += "&ts=" + timestamp; sendData(query, false); sendData(query, true); /// var totalGivenDamage = givenDamage; if (enemyIsNatural) totalGivenDamage += Math.floor(givenDamage*0.1); try { addToday(eday, totalGivenDamage); addTodayHits(eday, earnedXp); updateTodayInfo(); } catch (err) {} } } if (ajax_timeout != null) { clearInterval(ajax_timeout); ajax_timeout = null; } enableFightButton(); //ajax_timeout = setTimeout("$('.fight_btn').css('color','#cc3333');$('.fight_btn').css('text-shadow','#aaaaaa 2px 2px 2px');", 20000); //ajax_timeout = setTimeout("$('.fight_btn').css('color','#cc3333');$('.fight_btn').css('text-shadow','#aaaaaa 2px 2px 2px'); $('#pvp_actions .action_holder').addClass('disabled');", 20000); ajax_timeout = setTimeout(disableFightButton, 20000); }); /* if (typeof(SERVER_DATA) != 'undefined') { } else { startDequeue(); } */ try { updateQueueInfo(); updateTodayInfo(); updateTodayOffsetInfo(1); } catch(err) {} try { var curl = .href; if (curl == null || curl == undefined || curl == 'undefined') { curl = . .href; } if (curl.search(/military/i) != -1) { var curlparts = curl.split('/'); var bId = curlparts[curlparts.length - 1]; bId = bId.split('?')[0]; bId = bId.replace(/[^0-9]/g, ''); currentBattleId = bId; setTimeout(forceAjaxCheck, 2000); } } catch (err) {} try { checkNewVersion(); } catch(err) {} } /* Queue.js A function to represent a queue Created by Stephen Morley - http://code.stephenmorley.org/ - and released under the terms of the CC0 1.0 Universal legal code: http://creativecommons.org/publicdomain/zero/1.0/legalcode */ /* Creates a new queue. A queue is a first-in-first-out (FIFO) data structure - * items are added to the end of the queue and removed from the front. */ (function($) { $.fn.queueCreate = function(inqueue, options) { // initialise the queue and offset var queue = inqueue; var offset = 0; this.sliceQueue = function() { queue = queue.slice(offset); offset = 0; return queue; } /* Returns the length of the queue. */ this.getLength = function() { // return the length of the queue return (queue.length - offset); } /* Returns true if the queue is empty, and false otherwise. */ this.isEmpty = function() { // return whether the queue is empty return (queue.length == 0); } /* Enqueues the specified item. The parameter is: * item - the item to enqueue */ this.enqueue = function(item) { // enqueue the item queue.push(item); } /* Dequeues an item and returns it. If the queue is empty then undefined is returned. */ this.dequeue = function() { // if the queue is empty, return undefined if (queue.length == 0) return undefined; // store the item at the front of the queue var item = queue[offset]; // increment the offset and remove the free space if necessary if (++ offset * 2 >= queue.length) { queue = queue.slice(offset); offset = 0; } // return the dequeued item return item; } /* Returns the item at the front of the queue (without dequeuing it). If the * queue is empty then undefined is returned. */ this.peek = function() { // return the item at the front of the queue return (queue.length > 0 ? queue[offset] : undefined); } }; })(jQuery); function Queue(queue){ // initialise the queue and offset //var queue = []; var offset = 0; /* Returns the length of the queue. */ this.getLength = function(){ // return the length of the queue return (queue.length - offset); } /* Returns true if the queue is empty, and false otherwise. */ this.isEmpty = function(){ // return whether the queue is empty return (queue.length == 0); } /* Enqueues the specified item. The parameter is: * * item - the item to enqueue */ this.enqueue = function(item){ // enqueue the item queue.push(item); } /* Dequeues an item and returns it. If the queue is empty then undefined is * returned. */ this.dequeue = function(){ // if the queue is empty, return undefined if (queue.length == 0) return undefined; // store the item at the front of the queue var item = queue[offset]; // increment the offset and remove the free space if necessary if (++ offset * 2 >= queue.length){ queue = queue.slice(offset); offset = 0; } // return the dequeued item return item; } /* Returns the item at the front of the queue (without dequeuing it). If the * queue is empty then undefined is returned. */ this.peek = function(){ // return the item at the front of the queue return (queue.length > 0 ? queue[offset] : undefined); } } /*! * Class definition * * Copyright (c) 2008 John Resig (http://ejohn.org/blog/simple-java -inheritance/) * Inspired by base2 and Prototype */ (function () { var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; // The base Class implementation (does nothing) this.Class = function(){}; // Create a new Class that inherits from this class Class.extend = function (prop) { var _super = this.prototype; // Instantiate a base class (but only create the instance, don't run the init constructor) initializing = true; var prototype = new this(); initializing = false; // Copy the properties over onto the new prototype for (var name in prop) { // Check if we're overwriting an existing function prototype[name] = (typeof prop[name] === "function" && typeof _super[name] === "function" && fnTest.test(prop[name]) ? (function(name, fn) { return function() { var tmp = this._super; // Add a new ._super() method that is the same method // but on the super-class this._super = _super[name]; // The method only need to be bound temporarily, so we // remove it when we're done executing var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; }(name, prop[name])) : prop[name]); } // The dummy class constructor function Class() { // All construction is actually done in the init method if (!initializing && this.init) { this.init.apply(this, arguments); } } // Populate our constructed prototype Class.prototype = prototype; // Enforce the constructor to be what we expect Class.constructor = Class; // And make this class extendable Class.extend = arguments.callee; return Class; }; }()); /* http://www.JSON.org/json2.js 2010-03-20 Public Domain. NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. See http://www.JSON.org/js.html This code should be minified before deployment. See http://java .crockford.com/jsmin.html USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO NOT CONTROL. This file creates a global JSON containing two methods: stringify and parse. JSON.stringify(value, replacer, space) value any Java value, usually an or array. replacer an optional parameter that determines how values are stringified for s. It can be a function or an array of strings. space an optional parameter that specifies the indentation of nested structures. If it is omitted, the text will be packed without extra whitespace. If it is a number, it will specify the number of spaces to indent at each level. If it is a string (such as '\t' or ' '), it contains the characters used to indent at each level. This method produces a JSON text from a Java value. When an value is found, if the contains a toJSON method, its toJSON method will be called and the result will be stringified. A toJSON method does not serialize: it returns the value represented by the name/value pair that should be serialized, or undefined if nothing should be serialized. The toJSON method will be passed the key associated with the value, and this will be bound to the value For example, this would serialize Dates as ISO strings. Date.prototype.toJSON = function (key) { function f(n) { // Format integers to have at least two digits. return n < 10 ? '0' + n : n; } return this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + f(this.getUTCSeconds()) + 'Z'; }; You can provide an optional replacer method. It will be passed the key and value of each member, with this bound to the containing . The value that is returned from your method will be serialized. If your method returns undefined, then the member will be excluded from the serialization. If the replacer parameter is an array of strings, then it will be used to select the members to be serialized. It filters the results such that only members with keys listed in the replacer array are stringified. Values that do not have JSON representations, such as undefined or functions, will not be serialized. Such values in s will be dropped; in arrays they will be replaced with null. You can use a replacer function to replace those with JSON values. JSON.stringify(undefined) returns undefined. The optional space parameter produces a stringification of the value that is filled with line breaks and indentation to make it easier to read. If the space parameter is a non-empty string, then that string will be used for indentation. If the space parameter is a number, then the indentation will be that many spaces. Example: text = JSON.stringify(['e', {pluribus: 'unum'}]); // text is '["e",{"pluribus":"unum"}]' text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' text = JSON.stringify([new Date()], function (key, value) { return this[key] instanceof Date ? 'Date(' + this[key] + ')' : value; }); // text is '["Date(---current time---)"]' JSON.parse(text, reviver) This method parses a JSON text to produce an or array. It can throw a SyntaxError exception. The optional reviver parameter is a function that can filter and transform the results. It receives each of the keys and values, and its return value is used instead of the original value. If it returns what it received, then the structure is not modified. If it returns undefined then the member is deleted. Example: // Parse the text. Values that look like ISO date strings will // be converted to Date s. myData = JSON.parse(text, function (key, value) { var a; if (typeof value === 'string') { a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); if (a) { return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6])); } } return value; }); myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { var d; if (typeof value === 'string' && value.slice(0, 5) === 'Date(' && value.slice(-1) === ')') { d = new Date(value.slice(5, -1)); if (d) { return d; } } return value; }); This is a reference implementation. You are free to copy, modify, or redistribute. */ /*jslint evil: true, strict: false */ /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, lastIndex, length, parse, prototype, push, replace, slice, stringify, test, toJSON, toString, valueOf */ // Create a JSON only if one does not already exist. We create the // methods in a closure to avoid creating global variables. if (!this.JSON) { this.JSON = {}; } (function () { function f(n) { // Format integers to have at least two digits. return n < 10 ? '0' + n : n; } if (typeof Date.prototype.toJSON !== 'function') { Date.prototype.toJSON = function (key) { return isFinite(this.valueOf()) ? this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + f(this.getUTCSeconds()) + 'Z' : null; }; String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function (key) { return this.valueOf(); }; } var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, gap, indent, meta = { // table of character substitutions '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\' }, rep; function quote(string) { // If the string contains no control characters, no quote characters, and no // backslash characters, then we can safely slap some quotes around it. // Otherwise we must also replace the offending characters with safe escape // sequences. escapable.lastIndex = 0; return escapable.test(string) ? '"' + string.replace(escapable, function (a) { var c = meta[a]; return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }) + '"' : '"' + string + '"'; } function str(key, holder) { // Produce a string from holder[key]. var i, // The loop counter. k, // The member key. v, // The member value. length, mind = gap, partial, value = holder[key]; // If the value has a toJSON method, call it to obtain a replacement value. if (value && typeof value === ' ' && typeof value.toJSON === 'function') { value = value.toJSON(key); } // If we were called with a replacer function, then call the replacer to // obtain a replacement value. if (typeof rep === 'function') { value = rep.call(holder, key, value); } // What happens next depends on the value's type. switch (typeof value) { case 'string': return quote(value); case 'number': // JSON numbers must be finite. Encode non-finite numbers as null. return isFinite(value) ? String(value) : 'null'; case 'boolean': case 'null': // If the value is a boolean or null, convert it to a string. Note: // typeof null does not produce 'null'. The case is included here in // the remote chance that this gets fixed someday. return String(value); // If the type is ' ', we might be dealing with an or an array or // null. case ' ': // Due to a specification blunder in ECMA , typeof null is ' ', // so watch out for that case. if (!value) { return 'null'; } // Make an array to hold the partial results of stringifying this value. gap += indent; partial = []; // Is the value an array? if ( .prototype.toString.apply(value) === '[ Array]') { // The value is an array. Stringify every element. Use null as a placeholder // for non-JSON values. length = value.length; for (i = 0; i < length; i += 1) { partial[i] = str(i, value) || 'null'; } // Join all of the elements together, separated with commas, and wrap them in // brackets. v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']'; gap = mind; return v; } // If the replacer is an array, use it to select the members to be stringified. if (rep && typeof rep === ' ') { length = rep.length; for (i = 0; i < length; i += 1) { k = rep[i]; if (typeof k === 'string') { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } else { // Otherwise, iterate through all of the keys in the . for (k in value) { if ( .hasOwnProperty.call(value, k)) { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } // Join all of the member texts together, separated with commas, // and wrap them in braces. v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}'; gap = mind; return v; } } // If the JSON does not yet have a stringify method, give it one. if (typeof JSON.stringify !== 'function') { JSON.stringify = function (value, replacer, space) { // The stringify method takes a value and an optional replacer, and an optional // space parameter, and returns a JSON text. The replacer can be a function // that can replace values, or an array of strings that will select the keys. // A default replacer method can be provided. Use of the space parameter can // produce text that is more easily readable. var i; gap = ''; indent = ''; // If the space parameter is a number, make an indent string containing that // many spaces. if (typeof space === 'number') { for (i = 0; i < space; i += 1) { indent += ' '; } // If the space parameter is a string, it will be used as the indent string. } else if (typeof space === 'string') { indent = space; } // If there is a replacer, it must be a function or an array. // Otherwise, throw an error. rep = replacer; if (replacer && typeof replacer !== 'function' && (typeof replacer !== ' ' || typeof replacer.length !== 'number')) { throw new Error('JSON.stringify'); } // Make a fake root containing our value under the key of ''. // Return the result of stringifying the value. return str('', {'': value}); }; } // If the JSON does not yet have a parse method, give it one. if (typeof JSON.parse !== 'function') { JSON.parse = function (text, reviver) { // The parse method takes a text and an optional reviver function, and returns // a Java value if the text is a valid JSON text. var j; function walk(holder, key) { // The walk method is used to recursively walk the resulting structure so // that modifications can be made. var k, v, value = holder[key]; if (value && typeof value === ' ') { for (k in value) { if ( .hasOwnProperty.call(value, k)) { v = walk(value, k); if (v !== undefined) { value[k] = v; } else { delete value[k]; } } } } return reviver.call(holder, key, value); } // Parsing happens in four stages. In the first stage, we replace certain // Unicode characters with escape sequences. Java handles many characters // incorrectly, either silently deleting them, or treating them as line endings. text = String(text); cx.lastIndex = 0; if (cx.test(text)) { text = text.replace(cx, function (a) { return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }); } // In the second stage, we run the text against regular expressions that look // for non-JSON patterns. We are especially concerned with '()' and 'new' // because they can cause invocation, and '=' because it can cause mutation. // But just to be safe, we want to reject all unexpected forms. // We split the second stage into 4 regexp operations in order to work around // crippling inefficiencies in IE's and Safari's regexp engines. First we // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we // replace all simple value tokens with ']' characters. Third, we delete all // open brackets that follow a colon or comma or that begin the text. Finally, // we look to see that the remaining characters are only whitespace or ']' or // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. if (/^[\],:{}\s]*$/. test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { // In the third stage we use the eval function to compile the text into a // Java structure. The '{' operator is subject to a syntactic ambiguity // in Java : it can begin a block or an literal. We wrap the text // in parens to eliminate the ambiguity. j = eval('(' + text + ')'); // In the optional fourth stage, we recursively walk the new structure, passing // each name/value pair to a reviver function for possible transformation. return typeof reviver === 'function' ? walk({'': j}, '') : j; } // If the text is not JSON parseable, then a SyntaxError is thrown. throw new SyntaxError('JSON.parse'); }; } }()); /*! * jStore 2.0 - Persistent Client Side Storage * * Copyright (c) 2010 Eric Garside (http://eric.garside.name/) * Dual licensed under: * MIT: http://www.opensource.org/licenses/mit-license.php * GPLv3: http://www.opensource.org/licenses/gpl-3.0.html * * --------------------------- * * jStore Flash Storage Component * * Copyright (c) 2006 Jeff Lerman (jeff@blip.tv) * Licensed under the Creative Commons Attribution 3.0 United States License: * http://creativecommons.org/licenses/by/3.0/us */ (function ($, ) { //------------------------------ // // Constants // //------------------------------ //------------------------------ // Exceptions //------------------------------ /** * An exception thrown by the StorageEngine class whenever its data accessor methods * are called before the engine is ready to transact data. */ var EX_UNSTABLE = 'JSTORE_ENGINE_UNSTABLE', /** * An exception thrown by jStore whenever an undefined storage engine is referenced for * some task by an invalid JRI (jStore Resource Identifier). */ EX_UNKNOWN = 'JSTORE_UNKNOWN_ENGINE_REQUESTED', /** * An exception thrown by jStore whenever a given flavor of storage is double defined. */ EX_COLLISION = 'JSTORE_ENGINE_NAMESPACE_COLLISION', /** * An exception thrown by jStore whenever a jri is double applied to a resource. */ EX_DUPLICATE = 'JSTORE_RESOURCE_NAMESPACE_COLLISION', /** * An exception thrown by jStore whenever a given flavor of storage has no defined engine. */ EX_UNAVAILABLE = 'JSTORE_ENGINE_UNAVAILABLE', /** * An exception thrown by jStore whenever an invalid flavor type is used. */ EX_INVALID = 'JSTORE_INVALID_FLAVOR', //------------------------------ // Regular Expressions //------------------------------ /** * Regular expression to test property values for being JSON. */ RX_JSON = (function () { try { return new RegExp('^("(\\\\.|[^"\\\\\\n\\r])*?"|[,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t])+?$'); } catch (e) { return (/^(true|false|null|\[.*\]|\{.*\}|".*"|\d+|\d+\.\d+)$/); } }()), //------------------------------ // Storage Flavors //------------------------------ /** * The storage flavor identifier for HTML5 local storage. */ FLAVOR_LOCAL = 'jstore-html5-local', /** * The storage flavor identifier for HTML5 database storage. */ FLAVOR_SQL = 'jstore-html5-sql', /** * The storage flavor identifier for Adobe Flash Shared storage. */ FLAVOR_FLASH = 'jstore-flash', /** * The storage flavor identifier for Google Gears storage. */ FLAVOR_GEARS = 'jstore-google-gears', /** * The storage flavor identifier for Internet Explorer storage, available to IE7 and IE6. */ FLAVOR_MSIE = 'jstore-msie', //------------------------------ // // Property Declaration // //------------------------------ /** * The base StorageEngine class which each "storage flavor" will extend to meet the * requirements for its specific implementation. */ StorageEngine, /** * The jStore . Internal to this closure, jStore is referenced by "_". It is * exposed to jQuery below, and made publicly accessible through jQuery.jStore */ _ = {}, /** * The engines available to jStore for use. These are the class definitions for flavored * storage engines. * * Signature: * { * : , * * ... * } */ definitions = {}, /** * Active engines instantiated by jStore, indexed by their JRI. * * Signature: * { * : , * * ... * } */ engines = {}, /** * If we are going to be using the flash storage engine, we want to postpone the jStore ready event until the jStore * isFlashReady flag is also true. This property is set whenever flash is determined to be the storage engine. */ waitForFlash = false, /** * Storage for listeners, indexed by content and event type. * * Signature: * { * : * { * : [, ...], * * ... * }, * * ... * } */ events = {}, /** * The configuration for this implementation. * * Signature: * { * project: , * * flash: , * * json: , * * errorCallback: * } */ configurations = { project: undefined, flash: 'jStore.Flash.html', json: 'browser.json.js' }, /** * The active storage engine, being used to satisfy the get/set/remove functions on the jStore and jQuery * s. */ active; //------------------------------ // // Internal Methods // //------------------------------ /** * Determine if the given flavor is valid. * * @param flavor The flavor to test. * * @return True if the flavor is valid, false otherwise. */ function validFlavor(flavor) { switch (flavor) { case FLAVOR_LOCAL: case FLAVOR_SQL: case FLAVOR_FLASH: case FLAVOR_GEARS: case FLAVOR_MSIE: return true; default: return false; } } /** * Performs enhanced type comparison on an . This is more reliable method * of type checking a variable than a simple typeof comparison. The reason is that, * typeof will reduce to the lowest common type. * * "typeof []" returns , and not Array. * "typeof {}" returns as well. * * typecheck( [], 'Array' ) : returns true; * typecheck( [], ' ' ) : returns false; * * @param type The variable type to check. * * @param compare A string representing the literal type to check. * * @return True if the variable "type" matches the compare literal. */ function typecheck(type, compare) { return !type ? false : type.constructor.toString().match(new RegExp(compare + '\\(\\)', 'i')) !== null; } /** * If the provided listener is a valid function, it will be triggered with the provided context * and parameters. * * @param listener The listener being triggered. * * @param context The context to provide to the listener. * * @param parameters The parameters to pass to the listener as arguments. * * @return The response of the notified listener. */ function notify(listener, context, parameters) { if (typecheck(listener, 'Function')) { return listener.apply(context || _, typecheck(parameters, 'Array') ? parameters : [parameters]); } } /** * Load the given . * * @param path The path to the file to include. * * @param listener The listener to notify when the file finishes loading. */ function load (path, listener) { $.ajax( { url: path, complete: listener || $.noop(), type: 'GET', dataType: ' ', cache: false }); } /** * Checks the type of the value, and returns a value safe to persist in any client-side mechanism. * * @param value The value which should be prepared for storage. * * @return A value safe for storage. */ function prepareForStorage(value) { if (value === undefined) { return ''; } if (typecheck(value, ' ') || typecheck(value, 'Array') || typecheck(value, 'Function')) { return JSON.stringify(value); } return value; } /** * Checks the type of the value, and returns a value safe for access in any client-side mechanism. * * @param value The value which should be prepared for use. * * @return A value safe for use. */ function prepareForRevival(value) { return RX_JSON.test(value) ? JSON.parse(value) : value; } /** * Define a flavored storage engine. * * @throws EX_COLLISION, EX_INVALID * * @param flavor The flavor of engine being defined. * * @param definition An containing the new properties and methods for the engine extension. * * @param availability A function to invoke which must return a boolean value indicating the * availability of the storage flavor on this browser. */ function define(flavor, definition, availability) { if (!validFlavor(flavor)) { throw EX_INVALID; } if (availability[flavor] !== undefined) { throw EX_COLLISION; } /** * The logic here has been reworked so unavailable flavors are discarded, so we don't needlessly * bloat the runtime size of jStore. */ if (notify(availability) === true) { _.available[flavor] = true; definition.flavor = flavor; definitions[flavor] = StorageEngine.extend(definition); } else { _.available[flavor] = false; // Filter the invalid flavor out of the priority list. _.enginePriority = $.map(_.enginePriority, function (engine) { if (engine === flavor) { return null; } else { return engine; } }); } } /** * Make the jStore library ready. */ function makeReady() { if (_.isReady) { return; } if ((waitForFlash && _.isFlashReady) || !waitForFlash) { _.isReady = true; _.trigger('jstore-ready', [engines[active]]); } } /** * Create a best-fit engine. */ function createBestFitEngine() { _.create(_.enginePriority[0], undefined, 'best-fit'); } /** * Get the flash version currently supported in this browser. * * @return The flash version. */ function flashVersion() { //other browsers if (navigator.plugins && navigator.plugins.length > 0) { try { if(navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){ return (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).de ion.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1]; } } catch(e) {} } else { //ie try { // avoid fp6 minor version lookup issues // see: http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/ var axo = new ActiveX ('ShockwaveFlash.ShockwaveFlash.6'); try { axo.Allow Access = 'always'; } catch(e) { return '6,0,0'; } } catch(e) {} try { var vers = new ActiveX ('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1]; return vers; } catch(e) {} } return '0,0,0'; } /** * Flash Detection functions copied from the jQuery Flash Plugin * * Copyright (c) 2006 Luke Lutman (http://jquery.lukelutman.com/plugins/flash) * * Dual licensed under the MIT and GPL licenses. * http://www.opensource.org/licenses/mit-license.php * http://www.opensource.org/licenses/gpl-license.php * * @param version The version to compare to. * * @return True if the version is greater than or equal to the required version, false otherwise. */ function hasFlashVersion(version) { var installedVersion = flashVersion(); var playerVersion = installedVersion.match(/\d+/g); var requiredVersion = version.match(/\d+/g); var index = 0; var player; var required; for (; index < 3; index++) { player = parseInt(playerVersion[index], 10); required = parseInt(requiredVersion[index], 10); // Player version is less than what is required. if (player < required) { return false; } // Player version is greater than what is required. else if (player > required) { return true; } } // Player and required version match exactly. return true; } //------------------------------ // // Plugin Definition // //------------------------------ //------------------------------ // Error Declaration //------------------------------ //------------------------------ // Plugin Creation //------------------------------ /** * The jStore . Manages a collection of StorageEngines for particular "storage flavors", or the types * of storage solutions available to each browser. * * 2.0 Version Notes: * * - The user is now responsible for third-party includes, with the exception of flash. * * - jStore has been given sole responsibility for testing engine availability. * * - For the sake of naming conventions, all property names now start with a lowercase, and are camel-cased. * * The following properties have been changed since the 1.2.x release: * * - EngineOrder: For the sake of naming conventions, renamed to enginePriority. * * The following properties and methods have been removed since the 1.2.x release: * * - Availability: jStore's engines would add their availability tests to this , so jStore could test * them. With the changes to how availability testing works, this property has been removed. * A new property, "available" on jStore contains a set of available engines. * * - Engines: Formerly contained the definitions of storage engines. This property has been removed, and * storage of these definitions has been moved internal to the closure. * * - Instances: Formerly contained instantiated storage engines. This property has been removed, and storage * of instantiated engines has been moved internal to the closure. * * - CurrentEngine: Formerly contained the active storage engine being used for transacting data through the jStore * and/or jQuery s. This property has been removed, and storage of the current engine has * been moved internal to the closure. A new method, "activeEngine" has been added to jQuery to * get and set the active engine to use. * * - defaults: Formerly used to set the implementation options for jStore. This property has been removed and * replaced with a new configuration metho on the jStore . * * - delegate: The delegate class has been removed in favor of a much simpler bind/trigger accessor system, which * is accessible contextually through storage engines, or generically through jStore. * * + fail: This registration class bound events on the delegate for jstore-fail events. Instead, use: * jStore.bind('jstore-failure', listener); * * + flashReady: This registration class bound events on the delegate for flash-ready events. The jstore-ready method * now accounts for waiting for flash readyness, if and only if the flash engine is being used. Simply * call to jStore.ready(). * * + load: Replaced with the init() method, which performs the same basic functions as the old load() method. Also, * the init function is now domready safe, meaning it wraps itself in a domready listener, so the end user * doesn't have to. * * + FindEngine: Removed entirely. The functionality provided by this method now implicitly occurs with the new define() * system implemented for engine flavors. * * + setCurrentEngine: Replaced by activeEngine(). Set the current active engine by passing in the JRI. * * + safeStore: Replaced by a method internal to this closure, "prepareForStorage". * * + safeResurrect: Replaced by a method internal to this closure, "prepareForRevival". * * + use: Replaced by "create". */ $.extend(_, { //------------------------------ // Properties //------------------------------ /** * The priority order in which engines should be tested for use. The lower their index in the array, the higher * their priority for use. * * Be weary when reconfiguring the priority order of engines! jStore will use the first available engine it finds * based on its priority when autoloading. * * This array is filtered out as engines are defined, with invalid engines being removed. * * Signature: * [FLAVOR_, ...] */ enginePriority: [FLAVOR_LOCAL, FLAVOR_SQL, FLAVOR_FLASH, FLAVOR_MSIE], /** * A collection of the availability states of engines, indexed by their flavor. * * Signature: * { * : true|false, * * ... * } */ available: {}, /** * Flag to determine if the jStore library is ready. jStore becomes ready once the dom is ready and all necessary * startup procedures required by jStore to function properly are completed. */ isReady: false, /** * With the flash storage engine, we have to jump through a couple of hoops before the flash engine is ready to work. * This flag tracks whether or not the flash storage is available. */ isFlashReady: false, /** * The available engine flavors. */ flavors: { local: FLAVOR_LOCAL, sql: FLAVOR_SQL, flash: FLAVOR_FLASH, gears: FLAVOR_GEARS, msie: FLAVOR_MSIE }, //------------------------------ // Constructor //------------------------------ /** * Constructor. * * @throws EX_INVALID * * @param project The name of the jStore project. Used to generate a JRI for the engine we create. * * @param configuration Optionally, an containing configuration options for this implementation. * * @param flavor Optionally, the flavor of storage to use. If not provided, jStore will pick the * best flavor, based on the current browser. * * @return jStore */ init: function (project, configuration, flavor) { // Extend our plugin configurations $.extend(configurations, {project: project}, configuration); $(function () { //register the error callback if we have one passed in if (configurations.errorCallback) { _.error(configurations.errorCallback); } // If JSON parsing isn't defined in this browser, include it. if ( .JSON === undefined) { load (configurations.json); } try { // If we have an explicit flavor to use, use it. if (flavor !== undefined) { _.create(flavor, project, 'default'); } // Otherwise, attempt to create a best-fit engine. else { createBestFitEngine(); } } catch (e) { //we couldn't instantiate an engine _.trigger('jstore-error', [e]); } }); return _; }, //------------------------------ // Methods //------------------------------ /** * Create an instance of a flavored engine. * * @throws EX_INVALID, EX_UNAVAILABLE, EX_DUPLICATE * * @param flavor The flavor to create the engine with. * * @param project The project identifier for this instance. * * @param identifier Some arbitrary identifier for this project instance of the engine. * * @return The created instance. */ create: function (flavor, project, identifier) { project = project || configurations.project || .hostname.replace(/\./g, '-') || 'unknown'; if (!validFlavor(flavor)) { throw EX_INVALID; } if (definitions[flavor] === undefined) { throw EX_UNAVAILABLE; } var jri = (identifier !== undefined ? identifier + '.' : '') + project + '.' + flavor, engine; if (engines[jri] !== undefined) { throw EX_DUPLICATE; } // Create our engine instance. engine = engines[jri] = new definitions[flavor](project, jri); // Set up a listener for our jstore-engine-ready event. engine.ready(function () { _.trigger('jstore-engine-ready', [engine]); }); if (flavor === FLAVOR_FLASH && !_.isFlashReady) { if (active === undefined) { waitForFlash = true; } // Define a -accessible function for flash to call via ExternalInterface .jstore_ready = function () { _.isFlashReady = true; if (active === undefined) { active = jri; makeReady(); } _.trigger('flash-ready'); // Remove the callback from the scope, as it is no longer necessary .jstore_ready = undefined; }; .jstore_error = function (message) { _.trigger('jstore-error', ['JSTORE_FLASH_EXCEPTION', null, message]); }; $('< style="height:1px;width:1px;position:absolute;left:0;top:0;margin-left:-100px;" id="jStoreFlashFrame" src="' + configurations.flash + '">').appendTo('body'); } else if (active === undefined) { active = jri; makeReady(); } return engine; }, /** * Fetch an engine by it's JRI. * * @param jri The JRI of the engine to retrieve. * * @return The requested engine. */ engine: function (jri) { return engines[jri]; }, /** * Returns the active storage engine being used. If a value is passed, sets that engine as the active engine. * * @throws EX_UNKNOWN * * @param jri Optionally, the JRI of the engine to make active, if it should be changed. * * @return The active storage engine. */ activeEngine: function (jri) { if (jri !== undefined) { if (engines[jri] === undefined) { throw EX_UNKNOWN; } else { active = jri; } } return engines[active]; }, /** * Bind an event listener. * * @param event The event to bind a listener on. * * @param listener The listener to notify when the event occurs. * * @param context The context of the binding. A string representing the engine flavor * binding the event, or undefined to indicate it's a jStore event. * * @return jStore */ bind: function (event, listener, context) { context = context || 'jstore'; if (events[context] === undefined) { events[context] = {}; } if (events[context][event] === undefined) { events[context][event] = [listener]; } else { events[context][event].push(listener); } return _; }, /** * Trigger an event, notifying any bound listeners. * * @param event The event to trigger. * * @param parameters Any additional parameters to pass to the listeners being notified. * * @param context The context of the binding. A string representing the engine flavor * binding the event, or undefined to indicate it's a jStore event. * * @return jStore */ trigger: function (event, parameters, context) { context = context || 'jstore'; if (events[context] !== undefined) { if (events[context][event] !== undefined) { $.each(events[context][event], function () { notify(this, _, parameters); }); } } return _; }, /** * Bind a listener to be notified when jStore causes a non-fatal exception. * * @param listener The listener to notify when a failure occurs. */ error: function (listener) { _.bind('jstore-error', listener); }, /** * Bind a listener to be notified when jStore is ready. * * @param listener The listener to notify when jStore is ready. * * @return jStore */ ready: function (listener) { if (_.isReady) { notify(listener); } else { _.bind('jstore-ready', listener); } return _; }, /** * Bind a listener to be notified when jStore and the default engine are ready. * * @param listener The listener to notify when jStore and it's default engine are ready. * * @return jStore */ engineReady: function (listener) { if (_.isReady) { notify(listener); } else { _.bind('jstore-engine-ready', listener); } return _; }, /** * A combined getter/setter for the active engine. * * @param key The key of the property to get, or set. * * @param value If a valid value is provided, sets the engine. * * @return The requested property value. */ store: function (key, value) { return value === undefined ? _.get(key) : _.set(key, value); }, /** * Remove a property from the active engine. * * @param key The key of the property to remove. * * @return The value of the property before removal. */ remove: function (key) { return _.activeEngine().remove(key); }, /** * Get a property from the active engine. * * @param key The key of the property to get. * * @return The value of the property. */ get: function (key) { return _.activeEngine().get(key); }, /** * Set a property on the active engine. * * @param key The key of the property to set. * * @param value The value to set the property to. * * @return The new value of the property. */ set: function (key, value) { return _.activeEngine().set(key, value); } }); //------------------------------ // Core Extension //------------------------------ //------------------------------ // // Class Definition // //------------------------------ /** * The StorageEngine class is the unified API through which jStore accesses and manipulates * the various storage flavors available. * * 2.0 Version Notes: * * - All third-party loading is now the responsibility of the developer. * * - The delegate class has been removed entirely. Engines have been given "bind" and "trigger" methods * to interact directly with the delegate like-replacement that has been added to jStore. * * - Engine availability has been moved out of the engines themselves, and elevated to a jStore * responsibility. * * The following methods have changed since the 1.2.x release: * * - get: When "get"ting a non-stored property, the get function will now return "undefined" * instead of "null". "null" can now be used as a valid property value. * * - rem: Renamed to "remove". I always felt dirty about "rem" being vaguely explicit. * * The following properties have been removed since the 1.2.x release: * * - autoload: Part of the third-party loading logic. * * - hasIncluded: Part of the third-party loading logic. * * - includes: Part of the third-party loading logic. * * - isAvailable: Part of the availability logic elevated to jStore. * * @throws EX_UNSTABLE */ StorageEngine = Class.extend({ //------------------------------ // Properties //------------------------------ /** * The project which owns this storage engine. */ project: undefined, /** * The JRI (jStore Resource Identifier) acts as a uuid for this specific instance * of the storage engine. */ jri: undefined, /** * The flavor of this engine. */ flavor: undefined, /** * The actual database which data is transacted through. */ database: undefined, /** * A StorageEngine should always respond to fetch requests synchronously. However, some * of the storage flavors require callback-based asynchronous access. To get around this, * we simlpy require all engines to function off a primary data cache, to allow for * synchronous access across all implementations. * * Signature: * { * : , * * ... * } */ data: undefined, /** * A number of storage engines enforce a size limit as to what they will persist for a given site. * This limit is not monitored or computed by jStore currently, and this property will merely give * a static indication of the total size alloted to the engine, as defined by the storage flavor. */ limit: undefined, /** * Each storage flavor has a different process to go through before it's "ready" to transact data. This * property stores the state of the engine's readyness, and uses it to notify listeners whenever jStore * is ready to function. */ isReady: undefined, //------------------------------ // Constructor //------------------------------ /** * Constructor. * * @param project The project which instantiated this engine. * * @param jri The uuid assigned to this instance by jStore. */ init: function (project, jri) { this.project = project; this.jri = jri; this.data = {}; this.isReady = false; this.updateCache(); }, //------------------------------ // Methods //------------------------------ /** * Update the cache. */ updateCache: function () { this.isReady = true; this.trigger('engine-ready', [this]); }, /** * Bind a listener to an event dispatched by this engine. * * @param event The event to bind on. * * @param listener The listener to notify when the event occurs. */ bind: function (event, listener) { _.bind(event, listener, this.jri); }, /** * Trigger an event, notifying all bound listeners. * * @param event The event to trigger. * * @param parameters An optional Array of parameters to pass to the listeners. */ trigger: function (event, parameters) { _.trigger(event, parameters, this.jri); }, /** * Bind a listener to the StorageEngine's ready event. * * @param listener The listener to notify whenever this engine is ready to transact data. */ ready: function (listener) { if (this.isReady) { notify(listener, this); } else { this.bind('engine-ready', listener); } }, /** * Get a property from the StorageEngine. * * @param key The property key of the data to retrieve. * * @return The property value, or "undefined" if the property isn't stored. */ get: function (key) { this.__interruptAccess(); key = _.activeEngine().__normalizeKey(key); if ( typeof(key) == "undefined" || key == null || key == "" ) { //just return if bad key return false; } /*******/ _.activeEngine().updateCache(); /*******/ return this.data[key]; }, /** * Sets a property in the StorageEngine. * * @param key The key of the property. * * @param value The value of the property. * * @return The new value of the property. */ set: function (key, value) { this.__interruptAccess(); key = _.activeEngine().__normalizeKey(key); if ( typeof(key) == "undefined" || key == null || key == "" ) { //just return if bad key return false; } try { this.__set(key, value); } catch (e) { _.trigger('jstore-error', ['JSTORE_STORAGE_FAILURE', this.jri, e]); } this.data[key] = value; return value; }, /** * Removes a property from the StorageEngine. * * @param key The property key of the data to remove. * * @return The value of the property, before it was removed. */ remove: function (key) { this.__interruptAccess(); key = _.activeEngine().__normalizeKey(key); if ( typeof(key) == "undefined" || key == null || key == "" ) { //just return if bad key return false; } try { this.__remove(key); } catch (e) { _.trigger('jstore-error', ['JSTORE_REMOVE_FAILURE', this.jri, e]); } var buffer = this.data[key]; this.data[key] = undefined; return buffer; }, //------------------------------ // Internal Methods //------------------------------ /** * Ensures the engine is in a stable state for transacting data. * * @throws EX_UNSTABLE */ __interruptAccess: function () { if (!this.isReady) { throw EX_UNSTABLE; } }, /** * Normalize a key before using it, to ensure it's valid. * * @param key The key to normalize. * * @return A normalized key, safe for storage. */ __normalizeKey: function (key) { //make key a string key += ''; return key.replace(/^\s+|\s+$/g, ""); }, /** * Sets a property in the StorageEngine. This method should be overloaded to provide actual * storage flavor integration. * * @param key The key of the property. * * @param value The value of the property. * * @return The new value of the property. */ __set: function (key, value) { return; }, /** * Removes a property from the StorageEngine. This method should be overloaded to provide actual * storage flavor integration. * * @param key The property key of the data to remove. * * @return The value of the property, before it was removed. */ __remove: function (key) { return; } }); //------------------------------ // // jQuery Hooks // //------------------------------ $.extend($.fn, { //------------------------------ // Methods //------------------------------ /** * A combined getter/setter for the active engine. * * @param key The key of the property to get, or set. * * @param value If a valid value is provided, sets the engine. * * @return jQuery */ store: function (key, value) { if (value === undefined) { _.get(key); } else { _.set(key, value); } return this; }, /** * Remove a property from the active engine. * * @param key The key of the property to remove. * * @return jQuery */ removeStore: function (key) { _.activeEngine().remove(key); return this; }, /** * Get a property from the active engine. * * @param key The key of the property to get. * * @return The value of the property. */ getStore: function (key) { return _.activeEngine().get(key); }, /** * Set a property on the active engine. * * @param key The key of the property to set. * * @param value The value to set the property to. * * @return jQuery */ setStore: function (key, value) { _.activeEngine().set(key, value); return this; } }); //------------------------------ // // Event Bindings // //------------------------------ //------------------------------ // // Startup Code // //------------------------------ //------------------------------ // Expose jStore through jQuery //------------------------------ .jStore = $.jStore = _; //------------------------------ // // Engine Definitions // //------------------------------ //------------------------------ // Local //------------------------------ define(FLAVOR_LOCAL, { //------------------------------ // Properties //------------------------------ limit: parseInt(5e5, 16), //------------------------------ // Constructor //------------------------------ init: function (project, name) { this.database = ! .globalStorage ? .localStorage : .globalStorage[ .hostname]; this._super(project, name); }, //------------------------------ // Methods //------------------------------ updateCache: function () { var key, value; for (key in this.database) { if (this.database.hasOwnProperty(key)) { value = this.database.getItem(key); try { // Gecko's getItem returns {value: 'the value'}, WebKit returns 'the value' this.data[key] = prepareForRevival(value && value.value ? value.value : value); } catch (e) { } } } this._super(); }, //------------------------------ // Internal methods //------------------------------ __set: function (key, value) { this.database.setItem(key, prepareForStorage(value)); }, __remove: function (key) { this.database.removeItem(key); } }, function () { return .localStorage !== undefined || .globalStorage !== undefined; }); //------------------------------ // SQL //------------------------------ define(FLAVOR_SQL, { //------------------------------ // Properties //------------------------------ limit: parseInt(32e3, 16), //------------------------------ // Constructor //------------------------------ init: function (project, name) { this.database = .openDatabase('jstore-' + project, '1.0', project, this.limit); if (!this.database) { throw 'JSTORE_SQL_NO_DB'; } this.database.transaction(function (database) { database.executeSql('CREATE TABLE IF NOT EXISTS jstore (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)'); }); this._super(project, name); }, //------------------------------ // Methods //------------------------------ updateCache: function () { var self = this, _super = this._super; this.database.transaction(function (database) { database.executeSql('SELECT k,v FROM jstore', [], function (database, result) { var rows = result.rows, index = 0, row; for (; index < rows.length; ++index) { row = rows.item(index); self.data[row.k] = prepareForRevival(row.v); } _super.apply(self); }); }); }, //------------------------------ // Internal methods //------------------------------ __set: function (key, value) { this.database.transaction(function (database) { database.executeSql('INSERT OR REPLACE INTO jstore(k, v) VALUES (?, ?)', [key, prepareForStorage(value)], function(tx,rs){ /*nothing to do here*/ }, function(tx,error){ _.trigger('jstore-error', ['JSTORE_STORAGE_FAILURE', this.jri, 'HTML5 SQL Store Exception']); } ); }); }, __remove: function (key) { this.database.transaction(function (database) { database.executeSql('DELETE FROM jstore WHERE k = ?', [key]); }); } }, function () { return .openDatabase !== undefined; }); //------------------------------ // Flash //------------------------------ define(FLAVOR_FLASH, { //------------------------------ // Properties //------------------------------ limit: -1, //------------------------------ // Constructor //------------------------------ init: function (project, name) { var self = this; _.bind('flash-ready', function () { self.__flashReadyListener(); }); this._super(project, name); }, //------------------------------ // Methods //------------------------------ updateCache: function (enable) { /** * The default call to updateCache passes no variable, so we can short circuit the * ready state until we explictly call this after flash ready. */ if (enable === true) { var key, dataset = this.database.jstore_get_all(); for (key in dataset) { if (dataset.hasOwnProperty(key)) { this.data[key] = prepareForRevival(this.database.jstore_get(key)); } } this._super(); } }, //------------------------------ // Internal methods //------------------------------ __set: function (key, value) { if (!this.database.jstore_set(key, prepareForStorage(value))) { _.trigger('jstore-error', ['JSTORE_STORAGE_FAILURE', this.jri, 'Flash Exception']); } }, __remove: function (key) { this.database.jstore_remove(key); }, /** * Triggered whenever flash is ready. */ __flashReadyListener: function () { var = $('#jStoreFlashFrame')[0], frameDocument; // MSIE if ( .Document !== undefined && typecheck( .Document.jStoreFlash.jstore_get, 'Function')) { this.database = .Document.jStoreFlash; } // Real Browsers else if ( .content && .content .document) { frameDocument = $( .content .document); // Webkit if (typecheck($(' ', frameDocument)[0].jstore_get, 'Function')) { this.database = $(' ', frameDocument)[0]; } // Gecko else if (typecheck($(' ', frameDocument)[0].jstore_get, 'Function')) { this.database = $(' ', frameDocument)[0]; } } if (this.database === undefined) { throw 'JSTORE_FLASH_REFERENCE_ISSUE'; } else { this.updateCache(true); } } }, function () { return hasFlashVersion('9.0.0'); }); //------------------------------ // Gears //------------------------------ define(FLAVOR_GEARS, { //------------------------------ // Properties //------------------------------ limit: -1, //------------------------------ // Constructor //------------------------------ init: function (project, name) { this.database = google.gears.factory.create('beta.database'); this.database.open('jstore-' + project); this.database.execute('CREATE TABLE IF NOT EXISTS jstore (k TEXT UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL)'); this._super(project, name); }, //------------------------------ // Methods //------------------------------ updateCache: function () { var result = this.database.execute('SELECT k,v FROM jstore'); while (result.isValidRow()) { this.data[result.field(0)] = prepareForRevival(result.field(1)); result.next(); } result.close(); this._super(); }, //------------------------------ // Internal methods //------------------------------ __set: function (key, value) { this.database.execute('BEGIN'); this.database.execute('INSERT OR REPLACE INTO jstore(k, v) VALUES (?, ?)', [key, prepareForStorage(value)]); this.database.execute('COMMIT'); }, __remove: function (key) { this.database.execute('BEGIN'); this.database.execute('DELETE FROM jstore WHERE k = ?', [key]); this.database.execute('COMMIT'); } }, function () { return .google !== undefined && .google.gears !== undefined; }); //------------------------------ // MSIE //------------------------------ define(FLAVOR_MSIE, { //------------------------------ // Properties //------------------------------ limit: parseInt(1e4, 16), //------------------------------ // Constructor //------------------------------ init: function (project, name) { this.database = $('') .appendTo(document.body).get(0); this._super(project, name); }, //------------------------------ // Methods //------------------------------ updateCache: function () { this.database.load(this.project); var node = document.getElementById('jstore-' + this.project), xmlDoc = node.XMLDocument, root, index = 0; if (xmlDoc && xmlDoc.documentElement && xmlDoc.documentElement.attributes) { root = xmlDoc.documentElement; for (; index < root.attributes.length; ++index) { this.data[root.attributes.item(index).nodeName] = prepareForRevival(root.attributes.item(index).nodeValue); } } this._super(); }, //------------------------------ // Internal methods //------------------------------ /** Keys in IE storage cannot start with a digit **/ __normalizeKey: function(key) { key = this._super(key); if (key.match(/^\d/) != null){ key = "jStore-" + key; } return key; }, __set: function (key, value) { this.database.setAttribute(key, prepareForStorage(value)); this.database.save(this.project); }, __remove: function (key) { this.database.removeAttribute(key); this.database.save(this.project); } }, function () { return .ActiveX !== undefined; }); }(jQuery, )); $.jStore.ready( function(engine) { lockAndWaitQueue(); // queue_data = jQuery.jStore.get("pulse-queue-data"); if (queue_data == null || queue_data == undefined || queue_data == "undefined") { queue_data = []; pulse_queue = new $.fn.queueCreate(queue_data); jQuery.jStore.set("pulse-queue-data", queue_data); } else { pulse_queue = new $.fn.queueCreate(queue_data); if (isNaN(pulse_queue.getLength())) { queue_data = []; pulse_queue = new $.fn.queueCreate(queue_data); jQuery.jStore.set("pulse-queue-data", queue_data); } if (pulse_queue.getLength() > 0) { // alert(pulse_queue.peek()); } } unlockQueue(); // main2(); }); disableFightButton(); $.jStore.init("pulse", "pulse"); })();

Report Abuse to: abuse(at)hostaim.com