(function(window,undefined){"use strict";var LIBVERSION="0.7.10",EMPTY="",UNKNOWN="?",FUNC_TYPE="function",UNDEF_TYPE="undefined",OBJ_TYPE="object",STR_TYPE="string",MAJOR="major",MODEL="model",NAME="name",TYPE="type",VENDOR="vendor",VERSION="version",ARCHITECTURE="architecture",CONSOLE="console",MOBILE="mobile",TABLET="tablet",SMARTTV="smarttv",WEARABLE="wearable",EMBEDDED="embedded";var util={extend:function(regexes,extensions){for(var i in extensions){if("browser cpu device engine os".indexOf(i)!==-1&&extensions[i].length%2===0){regexes[i]=extensions[i].concat(regexes[i])}}return regexes},has:function(str1,str2){if(typeof str1==="string"){return str2.toLowerCase().indexOf(str1.toLowerCase())!==-1}else{return false}},lowerize:function(str){return str.toLowerCase()},major:function(version){return typeof version===STR_TYPE?version.split(".")[0]:undefined}};var mapper={rgx:function(){var result,i=0,j,k,p,q,matches,match,args=arguments;while(i<args.length&&!matches){var regex=args[i],props=args[i+1];if(typeof result===UNDEF_TYPE){result={};for(p in props){if(props.hasOwnProperty(p)){q=props[p];if(typeof q===OBJ_TYPE){result[q[0]]=undefined}else{result[q]=undefined}}}}j=k=0;while(j<regex.length&&!matches){matches=regex[j++].exec(this.getUA());if(!!matches){for(p=0;p<props.length;p++){match=matches[++k];q=props[p];if(typeof q===OBJ_TYPE&&q.length>0){if(q.length==2){if(typeof q[1]==FUNC_TYPE){result[q[0]]=q[1].call(this,match)}else{result[q[0]]=q[1]}}else if(q.length==3){if(typeof q[1]===FUNC_TYPE&&!(q[1].exec&&q[1].test)){result[q[0]]=match?q[1].call(this,match,q[2]):undefined}else{result[q[0]]=match?match.replace(q[1],q[2]):undefined}}else if(q.length==4){result[q[0]]=match?q[3].call(this,match.replace(q[1],q[2])):undefined}}else{result[q]=match?match:undefined}}}}i+=2}return result},str:function(str,map){for(var i in map){if(typeof map[i]===OBJ_TYPE&&map[i].length>0){for(var j=0;j<map[i].length;j++){if(util.has(map[i][j],str)){return i===UNKNOWN?undefined:i}}}else if(util.has(map[i],str)){return i===UNKNOWN?undefined:i}}return str}};var maps={browser:{oldsafari:{version:{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}}},device:{amazon:{model:{"Fire Phone":["SD","KF"]}},sprint:{model:{"Evo Shift 4G":"7373KT"},vendor:{HTC:"APA",Sprint:"Sprint"}}},os:{windows:{version:{ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2000:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",10:["NT 6.4","NT 10.0"],RT:"ARM"}}}};var regexes={browser:[[/(opera\smini)\/([\w\.-]+)/i,/(opera\s[mobiletab]+).+version\/([\w\.-]+)/i,/(opera).+version\/([\w\.]+)/i,/(opera)[\/\s]+([\w\.]+)/i],[NAME,VERSION],[/(OPiOS)[\/\s]+([\w\.]+)/i],[[NAME,"Opera Mini"],VERSION],[/\s(opr)\/([\w\.]+)/i],[[NAME,"Opera"],VERSION],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]+)*/i,/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i,/(?:ms|\()(ie)\s([\w\.]+)/i,/(rekonq)\/([\w\.]+)*/i,/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs)\/([\w\.-]+)/i],[NAME,VERSION],[/(trident).+rv[:\s]([\w\.]+).+like\sgecko/i],[[NAME,"IE"],VERSION],[/(edge)\/((\d+)?[\w\.]+)/i],[NAME,VERSION],[/(yabrowser)\/([\w\.]+)/i],[[NAME,"Yandex"],VERSION],[/(comodo_dragon)\/([\w\.]+)/i],[[NAME,/_/g," "],VERSION],[/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i,/(qqbrowser)[\/\s]?([\w\.]+)/i],[NAME,VERSION],[/(uc\s?browser)[\/\s]?([\w\.]+)/i,/ucweb.+(ucbrowser)[\/\s]?([\w\.]+)/i,/JUC.+(ucweb)[\/\s]?([\w\.]+)/i],[[NAME,"UCBrowser"],VERSION],[/(dolfin)\/([\w\.]+)/i],[[NAME,"Dolphin"],VERSION],[/((?:android.+)crmo|crios)\/([\w\.]+)/i],[[NAME,"Chrome"],VERSION],[/XiaoMi\/MiuiBrowser\/([\w\.]+)/i],[VERSION,[NAME,"MIUI Browser"]],[/android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)/i],[VERSION,[NAME,"Android Browser"]],[/FBAV\/([\w\.]+);/i],[VERSION,[NAME,"Facebook"]],[/fxios\/([\w\.-]+)/i],[VERSION,[NAME,"Firefox"]],[/version\/([\w\.]+).+?mobile\/\w+\s(safari)/i],[VERSION,[NAME,"Mobile Safari"]],[/version\/([\w\.]+).+?(mobile\s?safari|safari)/i],[VERSION,NAME],[/webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i],[NAME,[VERSION,mapper.str,maps.browser.oldsafari.version]],[/(konqueror)\/([\w\.]+)/i,/(webkit|khtml)\/([\w\.]+)/i],[NAME,VERSION],[/(navigator|netscape)\/([\w\.-]+)/i],[[NAME,"Netscape"],VERSION],[/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i,/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/([\w\.-]+)/i,/(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i,/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir)[\/\s]?([\w\.]+)/i,/(links)\s\(([\w\.]+)/i,/(gobrowser)\/?([\w\.]+)*/i,/(ice\s?browser)\/v?([\w\._]+)/i,/(mosaic)[\/\s]([\w\.]+)/i],[NAME,VERSION]],cpu:[[/(?:(amd|x(?:(?:86|64)[_-])?|wow|win)64)[;\)]/i],[[ARCHITECTURE,"amd64"]],[/(ia32(?=;))/i],[[ARCHITECTURE,util.lowerize]],[/((?:i[346]|x)86)[;\)]/i],[[ARCHITECTURE,"ia32"]],[/windows\s(ce|mobile);\sppc;/i],[[ARCHITECTURE,"arm"]],[/((?:ppc|powerpc)(?:64)?)(?:\smac|;|\))/i],[[ARCHITECTURE,/ower/,"",util.lowerize]],[/(sun4\w)[;\)]/i],[[ARCHITECTURE,"sparc"]],[/((?:avr32|ia64(?=;))|68k(?=\))|arm(?:64|(?=v\d+;))|(?=atmel\s)avr|(?:irix|mips|sparc)(?:64)?(?=;)|pa-risc)/i],[[ARCHITECTURE,util.lowerize]]],device:[[/\((ipad|playbook);[\w\s\);-]+(rim|apple)/i],[MODEL,VENDOR,[TYPE,TABLET]],[/applecoremedia\/[\w\.]+ \((ipad)/],[MODEL,[VENDOR,"Apple"],[TYPE,TABLET]],[/(apple\s{0,1}tv)/i],[[MODEL,"Apple TV"],[VENDOR,"Apple"]],[/(archos)\s(gamepad2?)/i,/(hp).+(touchpad)/i,/(kindle)\/([\w\.]+)/i,/\s(nook)[\w\s]+build\/(\w+)/i,/(dell)\s(strea[kpr\s\d]*[\dko])/i],[VENDOR,MODEL,[TYPE,TABLET]],[/(kf[A-z]+)\sbuild\/[\w\.]+.*silk\//i],[MODEL,[VENDOR,"Amazon"],[TYPE,TABLET]],[/(sd|kf)[0349hijorstuw]+\sbuild\/[\w\.]+.*silk\//i],[[MODEL,mapper.str,maps.device.amazon.model],[VENDOR,"Amazon"],[TYPE,MOBILE]],[/\((ip[honed|\s\w*]+);.+(apple)/i],[MODEL,VENDOR,[TYPE,MOBILE]],[/\((ip[honed|\s\w*]+);/i],[MODEL,[VENDOR,"Apple"],[TYPE,MOBILE]],[/(blackberry)[\s-]?(\w+)/i,/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|huawei|meizu|motorola|polytron)[\s_-]?([\w-]+)*/i,/(hp)\s([\w\s]+\w)/i,/(asus)-?(\w+)/i],[VENDOR,MODEL,[TYPE,MOBILE]],[/\(bb10;\s(\w+)/i],[MODEL,[VENDOR,"BlackBerry"],[TYPE,MOBILE]],[/android.+(transfo[prime\s]{4,10}\s\w+|eeepc|slider\s\w+|nexus 7)/i],[MODEL,[VENDOR,"Asus"],[TYPE,TABLET]],[/(sony)\s(tablet\s[ps])\sbuild\//i,/(sony)?(?:sgp.+)\sbuild\//i],[[VENDOR,"Sony"],[MODEL,"Xperia Tablet"],[TYPE,TABLET]],[/(?:sony)?(?:(?:(?:c|d)\d{4})|(?:so[-l].+))\sbuild\//i],[[VENDOR,"Sony"],[MODEL,"Xperia Phone"],[TYPE,MOBILE]],[/\s(ouya)\s/i,/(nintendo)\s([wids3u]+)/i],[VENDOR,MODEL,[TYPE,CONSOLE]],[/android.+;\s(shield)\sbuild/i],[MODEL,[VENDOR,"Nvidia"],[TYPE,CONSOLE]],[/(playstation\s[34portablevi]+)/i],[MODEL,[VENDOR,"Sony"],[TYPE,CONSOLE]],[/(sprint\s(\w+))/i],[[VENDOR,mapper.str,maps.device.sprint.vendor],[MODEL,mapper.str,maps.device.sprint.model],[TYPE,MOBILE]],[/(lenovo)\s?(S(?:5000|6000)+(?:[-][\w+]))/i],[VENDOR,MODEL,[TYPE,TABLET]],[/(htc)[;_\s-]+([\w\s]+(?=\))|\w+)*/i,/(zte)-(\w+)*/i,/(alcatel|geeksphone|huawei|lenovo|nexian|panasonic|(?=;\s)sony)[_\s-]?([\w-]+)*/i],[VENDOR,[MODEL,/_/g," "],[TYPE,MOBILE]],[/(nexus\s9)/i],[MODEL,[VENDOR,"HTC"],[TYPE,TABLET]],[/[\s\(;](xbox(?:\sone)?)[\s\);]/i],[MODEL,[VENDOR,"Microsoft"],[TYPE,CONSOLE]],[/(kin\.[onetw]{3})/i],[[MODEL,/\./g," "],[VENDOR,"Microsoft"],[TYPE,MOBILE]],[/\s(milestone|droid(?:[2-4x]|\s(?:bionic|x2|pro|razr))?(:?\s4g)?)[\w\s]+build\//i,/mot[\s-]?(\w+)*/i,/(XT\d{3,4}) build\//i,/(nexus\s[6])/i],[MODEL,[VENDOR,"Motorola"],[TYPE,MOBILE]],[/android.+\s(mz60\d|xoom[\s2]{0,2})\sbuild\//i],[MODEL,[VENDOR,"Motorola"],[TYPE,TABLET]],[/android.+((sch-i[89]0\d|shw-m380s|gt-p\d{4}|gt-n8000|sgh-t8[56]9|nexus 10))/i,/((SM-T\w+))/i],[[VENDOR,"Samsung"],MODEL,[TYPE,TABLET]],[/((s[cgp]h-\w+|gt-\w+|galaxy\snexus|sm-n900))/i,/(sam[sung]*)[\s-]*(\w+-?[\w-]*)*/i,/sec-((sgh\w+))/i],[[VENDOR,"Samsung"],MODEL,[TYPE,MOBILE]],[/(samsung);smarttv/i],[VENDOR,MODEL,[TYPE,SMARTTV]],[/\(dtv[\);].+(aquos)/i],[MODEL,[VENDOR,"Sharp"],[TYPE,SMARTTV]],[/sie-(\w+)*/i],[MODEL,[VENDOR,"Siemens"],[TYPE,MOBILE]],[/(maemo|nokia).*(n900|lumia\s\d+)/i,/(nokia)[\s_-]?([\w-]+)*/i],[[VENDOR,"Nokia"],MODEL,[TYPE,MOBILE]],[/android\s3\.[\s\w;-]{10}(a\d{3})/i],[MODEL,[VENDOR,"Acer"],[TYPE,TABLET]],[/android\s3\.[\s\w;-]{10}(lg?)-([06cv9]{3,4})/i],[[VENDOR,"LG"],MODEL,[TYPE,TABLET]],[/(lg) netcast\.tv/i],[VENDOR,MODEL,[TYPE,SMARTTV]],[/(nexus\s[45])/i,/lg[e;\s\/-]+(\w+)*/i],[MODEL,[VENDOR,"LG"],[TYPE,MOBILE]],[/android.+(ideatab[a-z0-9\-\s]+)/i],[MODEL,[VENDOR,"Lenovo"],[TYPE,TABLET]],[/linux;.+((jolla));/i],[VENDOR,MODEL,[TYPE,MOBILE]],[/((pebble))app\/[\d\.]+\s/i],[VENDOR,MODEL,[TYPE,WEARABLE]],[/android.+;\s(glass)\s\d/i],[MODEL,[VENDOR,"Google"],[TYPE,WEARABLE]],[/android.+(\w+)\s+build\/hm\1/i,/android.+(hm[\s\-_]*note?[\s_]*(?:\d\w)?)\s+build/i,/android.+(mi[\s\-_]*(?:one|one[\s_]plus)?[\s_]*(?:\d\w)?)\s+build/i],[[MODEL,/_/g," "],[VENDOR,"Xiaomi"],[TYPE,MOBILE]],[/\s(tablet)[;\/\s]/i,/\s(mobile)[;\/\s]/i],[[TYPE,util.lowerize],VENDOR,MODEL]],engine:[[/windows.+\sedge\/([\w\.]+)/i],[VERSION,[NAME,"EdgeHTML"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,/(icab)[\/\s]([23]\.[\d\.]+)/i],[NAME,VERSION],[/rv\:([\w\.]+).*(gecko)/i],[VERSION,NAME]],os:[[/microsoft\s(windows)\s(vista|xp)/i],[NAME,VERSION],[/(windows)\snt\s6\.2;\s(arm)/i,/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i],[NAME,[VERSION,mapper.str,maps.os.windows.version]],[/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i],[[NAME,"Windows"],[VERSION,mapper.str,maps.os.windows.version]],[/\((bb)(10);/i],[[NAME,"BlackBerry"],VERSION],[/(blackberry)\w*\/?([\w\.]+)*/i,/(tizen)[\/\s]([\w\.]+)/i,/(android|webos|palm\sos|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]+)*/i,/linux;.+(sailfish);/i],[NAME,VERSION],[/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i],[[NAME,"Symbian"],VERSION],[/\((series40);/i],[NAME],[/mozilla.+\(mobile;.+gecko.+firefox/i],[[NAME,"Firefox OS"],VERSION],[/(nintendo|playstation)\s([wids34portablevu]+)/i],[NAME,VERSION],[/(mint)[\/\s\(]?(\w+)*/i,/(mageia|vectorlinux)[;\s]/i,/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|(?=\s)arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?([\w\.-]+)*/i,/(hurd|linux)\s?([\w\.]+)*/i,/(gnu)\s?([\w\.]+)*/i],[NAME,VERSION],[/(cros)\s[\w]+\s([\w\.]+\w)/i],[[NAME,"Chromium OS"],VERSION],[/(sunos)\s?([\w\.]+\d)*/i],[[NAME,"Solaris"],VERSION],[/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i],[NAME,VERSION],[/(ip[honead]+)(?:.*os\s([\w]+)*\slike\smac|;\sopera)/i],[[NAME,"iOS"],[VERSION,/_/g,"."]],[/(mac\sos\sx)\s?([\w\s\.]+\w)*/i,/(macintosh|mac(?=_powerpc)\s)/i],[[NAME,"Mac OS"],[VERSION,/_/g,"."]],[/((?:open)?solaris)[\/\s-]?([\w\.]+)*/i,/(haiku)\s(\w+)/i,/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i,/(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i,/(unix)\s?([\w\.]+)*/i],[NAME,VERSION]]};var UAParser=function(uastring,extensions){if(!(this instanceof UAParser)){return new UAParser(uastring,extensions).getResult()}var ua=uastring||(window&&window.navigator&&window.navigator.userAgent?window.navigator.userAgent:EMPTY);var rgxmap=extensions?util.extend(regexes,extensions):regexes;this.isLinux=function(){var linuxRegexes=rgxmap.os[18];for(var i=0;i<linuxRegexes.length;i++){if(ua.match(linuxRegexes[i])!=null)return true}return false};this.getBrowser=function(){var browser=mapper.rgx.apply(this,rgxmap.browser);browser.major=util.major(browser.version);return browser};this.getCPU=function(){return mapper.rgx.apply(this,rgxmap.cpu)};this.getDevice=function(){return mapper.rgx.apply(this,rgxmap.device)};this.getEngine=function(){return mapper.rgx.apply(this,rgxmap.engine)};this.getOS=function(){return mapper.rgx.apply(this,rgxmap.os)};this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS(),device:this.getDevice(),cpu:this.getCPU()}};this.getUA=function(){return ua};this.setUA=function(uastring){ua=uastring;return this};this.setUA(ua);return this};UAParser.VERSION=LIBVERSION;UAParser.BROWSER={NAME:NAME,MAJOR:MAJOR,VERSION:VERSION};UAParser.CPU={ARCHITECTURE:ARCHITECTURE};UAParser.DEVICE={MODEL:MODEL,VENDOR:VENDOR,TYPE:TYPE,CONSOLE:CONSOLE,MOBILE:MOBILE,SMARTTV:SMARTTV,TABLET:TABLET,WEARABLE:WEARABLE,EMBEDDED:EMBEDDED};UAParser.ENGINE={NAME:NAME,VERSION:VERSION};UAParser.OS={NAME:NAME,VERSION:VERSION};if(typeof exports!==UNDEF_TYPE){if(typeof module!==UNDEF_TYPE&&module.exports){exports=module.exports=UAParser}exports.UAParser=UAParser}else{if(typeof define===FUNC_TYPE&&define.amd){define(function(){return UAParser})}else{window.UAParser=UAParser}}var $=window.jQuery||window.Zepto;if(typeof $!==UNDEF_TYPE){var parser=new UAParser;$.ua=parser.getResult();$.ua.get=function(){return parser.getUA()};$.ua.set=function(uastring){parser.setUA(uastring);var result=parser.getResult();for(var prop in result){$.ua[prop]=result[prop]}}}})(typeof window==="object"?window:this);
(function(root,factory){"use strict";if(typeof define==="function"&&define.amd){define(factory)}else if(typeof exports!=="undefined"){module.exports=factory()}else{root.simpleStorage=factory()}})(this,function(){"use strict";var VERSION="0.2.0";var _storage=false;var _storage_size=0;var _storage_available=false;var _ttl_timeout=null;var _lsStatus="OK";var LS_NOT_AVAILABLE="LS_NOT_AVAILABLE";var LS_DISABLED="LS_DISABLED";var LS_QUOTA_EXCEEDED="LS_QUOTA_EXCEEDED";function _init(){_storage_available=_checkAvailability();_loadStorage();_handleTTL();_setupUpdateObserver();if("addEventListener"in window){window.addEventListener("pageshow",function(event){if(event.persisted){_reloadData()}},false)}_storage_available=true}function _setupUpdateObserver(){if("addEventListener"in window){window.addEventListener("storage",_reloadData,false)}else{document.attachEvent("onstorage",_reloadData)}}function _reloadData(){try{_loadStorage()}catch(E){_storage_available=false;return}_handleTTL()}function _loadStorage(){var source=localStorage.getItem("simpleStorage");try{_storage=JSON.parse(source)||{}}catch(E){_storage={}}_storage_size=_get_storage_size()}function _save(){try{localStorage.setItem("simpleStorage",JSON.stringify(_storage));_storage_size=_get_storage_size()}catch(E){return _formatError(E)}return true}function _get_storage_size(){var source=localStorage.getItem("simpleStorage");return source?String(source).length:0}function _handleTTL(){var curtime,i,len,expire,keys,nextExpire=Infinity,expiredKeysCount=0;clearTimeout(_ttl_timeout);if(!_storage||!_storage.__simpleStorage_meta||!_storage.__simpleStorage_meta.TTL){return}curtime=+new Date;keys=_storage.__simpleStorage_meta.TTL.keys||[];expire=_storage.__simpleStorage_meta.TTL.expire||{};for(i=0,len=keys.length;i<len;i++){if(expire[keys[i]]<=curtime){expiredKeysCount++;delete _storage[keys[i]];delete expire[keys[i]]}else{if(expire[keys[i]]<nextExpire){nextExpire=expire[keys[i]]}break}}if(nextExpire!==Infinity){_ttl_timeout=setTimeout(_handleTTL,Math.min(nextExpire-curtime,2147483647))}if(expiredKeysCount){keys.splice(0,expiredKeysCount);_cleanMetaObject();_save()}}function _setTTL(key,ttl){var curtime=+new Date,i,len,added=false;ttl=Number(ttl)||0;if(ttl!==0){if(_storage.hasOwnProperty(key)){if(!_storage.__simpleStorage_meta){_storage.__simpleStorage_meta={}}if(!_storage.__simpleStorage_meta.TTL){_storage.__simpleStorage_meta.TTL={expire:{},keys:[]}}_storage.__simpleStorage_meta.TTL.expire[key]=curtime+ttl;if(_storage.__simpleStorage_meta.TTL.expire.hasOwnProperty(key)){for(i=0,len=_storage.__simpleStorage_meta.TTL.keys.length;i<len;i++){if(_storage.__simpleStorage_meta.TTL.keys[i]===key){_storage.__simpleStorage_meta.TTL.keys.splice(i)}}}for(i=0,len=_storage.__simpleStorage_meta.TTL.keys.length;i<len;i++){if(_storage.__simpleStorage_meta.TTL.expire[_storage.__simpleStorage_meta.TTL.keys[i]]>curtime+ttl){_storage.__simpleStorage_meta.TTL.keys.splice(i,0,key);added=true;break}}if(!added){_storage.__simpleStorage_meta.TTL.keys.push(key)}}else{return false}}else{if(_storage&&_storage.__simpleStorage_meta&&_storage.__simpleStorage_meta.TTL){if(_storage.__simpleStorage_meta.TTL.expire.hasOwnProperty(key)){delete _storage.__simpleStorage_meta.TTL.expire[key];for(i=0,len=_storage.__simpleStorage_meta.TTL.keys.length;i<len;i++){if(_storage.__simpleStorage_meta.TTL.keys[i]===key){_storage.__simpleStorage_meta.TTL.keys.splice(i,1);break}}}_cleanMetaObject()}}clearTimeout(_ttl_timeout);if(_storage&&_storage.__simpleStorage_meta&&_storage.__simpleStorage_meta.TTL&&_storage.__simpleStorage_meta.TTL.keys.length){_ttl_timeout=setTimeout(_handleTTL,Math.min(Math.max(_storage.__simpleStorage_meta.TTL.expire[_storage.__simpleStorage_meta.TTL.keys[0]]-curtime,0),2147483647))}return true}function _cleanMetaObject(){var updated=false,hasProperties=false,i;if(!_storage||!_storage.__simpleStorage_meta){return updated}if(_storage.__simpleStorage_meta.TTL&&!_storage.__simpleStorage_meta.TTL.keys.length){delete _storage.__simpleStorage_meta.TTL;updated=true}for(i in _storage.__simpleStorage_meta){if(_storage.__simpleStorage_meta.hasOwnProperty(i)){hasProperties=true;break}}if(!hasProperties){delete _storage.__simpleStorage_meta;updated=true}return updated}function _checkAvailability(){var err;var items=0;if(window.localStorage===null||typeof window.localStorage==="unknown"){err=new Error("localStorage is disabled");err.code=LS_DISABLED;throw err}if(!window.localStorage){err=new Error("localStorage not supported");err.code=LS_NOT_AVAILABLE;throw err}try{items=window.localStorage.length}catch(E){throw _formatError(E)}try{window.localStorage.setItem("__simpleStorageInitTest",Date.now().toString(16));window.localStorage.removeItem("__simpleStorageInitTest")}catch(E){if(items){throw _formatError(E)}else{err=new Error("localStorage is disabled");err.code=LS_DISABLED;throw err}}return true}function _formatError(E){var err;if(E.code===22||E.code===1014||[-2147024882,-2146828281,-21474675259].indexOf(E.number)>0){err=new Error("localStorage quota exceeded");err.code=LS_QUOTA_EXCEEDED;return err}if(E.code===18||E.code===1e3){err=new Error("localStorage is disabled");err.code=LS_DISABLED;return err}if(E.name==="TypeError"){err=new Error("localStorage is disabled");err.code=LS_DISABLED;return err}return E}function _checkError(err){if(!err){_lsStatus="OK";return err}switch(err.code){case LS_NOT_AVAILABLE:case LS_DISABLED:case LS_QUOTA_EXCEEDED:_lsStatus=err.code;break;default:_lsStatus=err.code||err.number||err.message||err.name}return err}try{_init()}catch(E){_checkError(E)}return{version:VERSION,status:_lsStatus,canUse:function(){return _lsStatus==="OK"&&!!_storage_available},set:function(key,value,options){if(key==="__simpleStorage_meta"){return false}if(!_storage){return false}if(typeof value==="undefined"){return this.deleteKey(key)}options=options||{};try{value=JSON.parse(JSON.stringify(value))}catch(E){return _formatError(E)}_storage[key]=value;_setTTL(key,options.TTL||0);return _save()},get:function(key){if(!_storage){return false}if(_storage.hasOwnProperty(key)&&key!=="__simpleStorage_meta"){if(this.getTTL(key)){return _storage[key]}}},deleteKey:function(key){if(!_storage){return false}if(key in _storage){delete _storage[key];_setTTL(key,0);return _save()}return false},setTTL:function(key,ttl){if(!_storage){return false}_setTTL(key,ttl);return _save()},getTTL:function(key){var ttl;if(!_storage){return false}if(_storage.hasOwnProperty(key)){if(_storage.__simpleStorage_meta&&_storage.__simpleStorage_meta.TTL&&_storage.__simpleStorage_meta.TTL.expire&&_storage.__simpleStorage_meta.TTL.expire.hasOwnProperty(key)){ttl=Math.max(_storage.__simpleStorage_meta.TTL.expire[key]-+new Date||0,0);return ttl||false}else{return Infinity}}return false},flush:function(){if(!_storage){return false}_storage={};try{localStorage.removeItem("simpleStorage");return true}catch(E){return _formatError(E)}},index:function(){if(!_storage){return false}var index=[],i;for(i in _storage){if(_storage.hasOwnProperty(i)&&i!=="__simpleStorage_meta"){index.push(i)}}return index},storageSize:function(){return _storage_size}}});
/*! jQuery v1.8.2 jquery.com | jquery.org/license */
(function(a,b){function G(a){var b=F[a]={};return p.each(a.split(s),function(a,c){b[c]=!0}),b}function J(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(I,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:+d+""===d?+d:H.test(d)?p.parseJSON(d):d}catch(f){}p.data(a,c,d)}else d=b}return d}function K(a){var b;for(b in a){if(b==="data"&&p.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function ba(){return!1}function bb(){return!0}function bh(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function bi(a,b){do a=a[b];while(a&&a.nodeType!==1);return a}function bj(a,b,c){b=b||0;if(p.isFunction(b))return p.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return p.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=p.grep(a,function(a){return a.nodeType===1});if(be.test(b))return p.filter(b,d,!c);b=p.filter(b,d)}return p.grep(a,function(a,d){return p.inArray(a,b)>=0===c})}function bk(a){var b=bl.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function bC(a,b){return a.getElementsByTagName(b)[0]||a.appendChild(a.ownerDocument.createElement(b))}function bD(a,b){if(b.nodeType!==1||!p.hasData(a))return;var c,d,e,f=p._data(a),g=p._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;d<e;d++)p.event.add(b,c,h[c][d])}g.data&&(g.data=p.extend({},g.data))}function bE(a,b){var c;if(b.nodeType!==1)return;b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?(b.parentNode&&(b.outerHTML=a.outerHTML),p.support.html5Clone&&a.innerHTML&&!p.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):c==="input"&&bv.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text),b.removeAttribute(p.expando)}function bF(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bG(a){bv.test(a.type)&&(a.defaultChecked=a.checked)}function bY(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=bW.length;while(e--){b=bW[e]+c;if(b in a)return b}return d}function bZ(a,b){return a=b||a,p.css(a,"display")==="none"||!p.contains(a.ownerDocument,a)}function b$(a,b){var c,d,e=[],f=0,g=a.length;for(;f<g;f++){c=a[f];if(!c.style)continue;e[f]=p._data(c,"olddisplay"),b?(!e[f]&&c.style.display==="none"&&(c.style.display=""),c.style.display===""&&bZ(c)&&(e[f]=p._data(c,"olddisplay",cc(c.nodeName)))):(d=bH(c,"display"),!e[f]&&d!=="none"&&p._data(c,"olddisplay",d))}for(f=0;f<g;f++){c=a[f];if(!c.style)continue;if(!b||c.style.display==="none"||c.style.display==="")c.style.display=b?e[f]||"":"none"}return a}function b_(a,b,c){var d=bP.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function ca(a,b,c,d){var e=c===(d?"border":"content")?4:b==="width"?1:0,f=0;for(;e<4;e+=2)c==="margin"&&(f+=p.css(a,c+bV[e],!0)),d?(c==="content"&&(f-=parseFloat(bH(a,"padding"+bV[e]))||0),c!=="margin"&&(f-=parseFloat(bH(a,"border"+bV[e]+"Width"))||0)):(f+=parseFloat(bH(a,"padding"+bV[e]))||0,c!=="padding"&&(f+=parseFloat(bH(a,"border"+bV[e]+"Width"))||0));return f}function cb(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=!0,f=p.support.boxSizing&&p.css(a,"boxSizing")==="border-box";if(d<=0||d==null){d=bH(a,b);if(d<0||d==null)d=a.style[b];if(bQ.test(d))return d;e=f&&(p.support.boxSizingReliable||d===a.style[b]),d=parseFloat(d)||0}return d+ca(a,b,c||(f?"border":"content"),e)+"px"}function cc(a){if(bS[a])return bS[a];var b=p("<"+a+">").appendTo(e.body),c=b.css("display");b.remove();if(c==="none"||c===""){bI=e.body.appendChild(bI||p.extend(e.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!bJ||!bI.createElement)bJ=(bI.contentWindow||bI.contentDocument).document,bJ.write("<!doctype html><html><body>"),bJ.close();b=bJ.body.appendChild(bJ.createElement(a)),c=bH(b,"display"),e.body.removeChild(bI)}return bS[a]=c,c}function ci(a,b,c,d){var e;if(p.isArray(b))p.each(b,function(b,e){c||ce.test(a)?d(a,e):ci(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&p.type(b)==="object")for(e in b)ci(a+"["+e+"]",b[e],c,d);else d(a,b)}function cz(a){return function(b,c){typeof b!="string"&&(c=b,b="*");var d,e,f,g=b.toLowerCase().split(s),h=0,i=g.length;if(p.isFunction(c))for(;h<i;h++)d=g[h],f=/^\+/.test(d),f&&(d=d.substr(1)||"*"),e=a[d]=a[d]||[],e[f?"unshift":"push"](c)}}function cA(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h,i=a[f],j=0,k=i?i.length:0,l=a===cv;for(;j<k&&(l||!h);j++)h=i[j](c,d,e),typeof h=="string"&&(!l||g[h]?h=b:(c.dataTypes.unshift(h),h=cA(a,c,d,e,h,g)));return(l||!h)&&!g["*"]&&(h=cA(a,c,d,e,"*",g)),h}function cB(a,c){var d,e,f=p.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((f[d]?a:e||(e={}))[d]=c[d]);e&&p.extend(!0,a,e)}function cC(a,c,d){var e,f,g,h,i=a.contents,j=a.dataTypes,k=a.responseFields;for(f in k)f in d&&(c[k[f]]=d[f]);while(j[0]==="*")j.shift(),e===b&&(e=a.mimeType||c.getResponseHeader("content-type"));if(e)for(f in i)if(i[f]&&i[f].test(e)){j.unshift(f);break}if(j[0]in d)g=j[0];else{for(f in d){if(!j[0]||a.converters[f+" "+j[0]]){g=f;break}h||(h=f)}g=g||h}if(g)return g!==j[0]&&j.unshift(g),d[g]}function cD(a,b){var c,d,e,f,g=a.dataTypes.slice(),h=g[0],i={},j=0;a.dataFilter&&(b=a.dataFilter(b,a.dataType));if(g[1])for(c in a.converters)i[c.toLowerCase()]=a.converters[c];for(;e=g[++j];)if(e!=="*"){if(h!=="*"&&h!==e){c=i[h+" "+e]||i["* "+e];if(!c)for(d in i){f=d.split(" ");if(f[1]===e){c=i[h+" "+f[0]]||i["* "+f[0]];if(c){c===!0?c=i[d]:i[d]!==!0&&(e=f[0],g.splice(j--,0,e));break}}}if(c!==!0)if(c&&a["throws"])b=c(b);else try{b=c(b)}catch(k){return{state:"parsererror",error:c?k:"No conversion from "+h+" to "+e}}}h=e}return{state:"success",data:b}}function cL(){try{return new a.XMLHttpRequest}catch(b){}}function cM(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function cU(){return setTimeout(function(){cN=b},0),cN=p.now()}function cV(a,b){p.each(b,function(b,c){var d=(cT[b]||[]).concat(cT["*"]),e=0,f=d.length;for(;e<f;e++)if(d[e].call(a,b,c))return})}function cW(a,b,c){var d,e=0,f=0,g=cS.length,h=p.Deferred().always(function(){delete i.elem}),i=function(){var b=cN||cU(),c=Math.max(0,j.startTime+j.duration-b),d=1-(c/j.duration||0),e=0,f=j.tweens.length;for(;e<f;e++)j.tweens[e].run(d);return h.notifyWith(a,[j,d,c]),d<1&&f?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:p.extend({},b),opts:p.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:cN||cU(),duration:c.duration,tweens:[],createTween:function(b,c,d){var e=p.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(e),e},stop:function(b){var c=0,d=b?j.tweens.length:0;for(;c<d;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;cX(k,j.opts.specialEasing);for(;e<g;e++){d=cS[e].call(j,a,k,j.opts);if(d)return d}return cV(j,k),p.isFunction(j.opts.start)&&j.opts.start.call(a,j),p.fx.timer(p.extend(i,{anim:j,queue:j.opts.queue,elem:a})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}function cX(a,b){var c,d,e,f,g;for(c in a){d=p.camelCase(c),e=b[d],f=a[c],p.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=p.cssHooks[d];if(g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}}function cY(a,b,c){var d,e,f,g,h,i,j,k,l=this,m=a.style,n={},o=[],q=a.nodeType&&bZ(a);c.queue||(j=p._queueHooks(a,"fx"),j.unqueued==null&&(j.unqueued=0,k=j.empty.fire,j.empty.fire=function(){j.unqueued||k()}),j.unqueued++,l.always(function(){l.always(function(){j.unqueued--,p.queue(a,"fx").length||j.empty.fire()})})),a.nodeType===1&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],p.css(a,"display")==="inline"&&p.css(a,"float")==="none"&&(!p.support.inlineBlockNeedsLayout||cc(a.nodeName)==="inline"?m.display="inline-block":m.zoom=1)),c.overflow&&(m.overflow="hidden",p.support.shrinkWrapBlocks||l.done(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b){f=b[d];if(cP.exec(f)){delete b[d];if(f===(q?"hide":"show"))continue;o.push(d)}}g=o.length;if(g){h=p._data(a,"fxshow")||p._data(a,"fxshow",{}),q?p(a).show():l.done(function(){p(a).hide()}),l.done(function(){var b;p.removeData(a,"fxshow",!0);for(b in n)p.style(a,b,n[b])});for(d=0;d<g;d++)e=o[d],i=l.createTween(e,q?h[e]:0),n[e]=h[e]||p.style(a,e),e in h||(h[e]=i.start,q&&(i.end=i.start,i.start=e==="width"||e==="height"?1:0))}}function cZ(a,b,c,d,e){return new cZ.prototype.init(a,b,c,d,e)}function c$(a,b){var c,d={height:a},e=0;b=b?1:0;for(;e<4;e+=2-b)c=bV[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function da(a){return p.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}var c,d,e=a.document,f=a.location,g=a.navigator,h=a.jQuery,i=a.$,j=Array.prototype.push,k=Array.prototype.slice,l=Array.prototype.indexOf,m=Object.prototype.toString,n=Object.prototype.hasOwnProperty,o=String.prototype.trim,p=function(a,b){return new p.fn.init(a,b,c)},q=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,r=/\S/,s=/\s+/,t=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,u=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,y=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,z=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,A=/^-ms-/,B=/-([\da-z])/gi,C=function(a,b){return(b+"").toUpperCase()},D=function(){e.addEventListener?(e.removeEventListener("DOMContentLoaded",D,!1),p.ready()):e.readyState==="complete"&&(e.detachEvent("onreadystatechange",D),p.ready())},E={};p.fn=p.prototype={constructor:p,init:function(a,c,d){var f,g,h,i;if(!a)return this;if(a.nodeType)return this.context=this[0]=a,this.length=1,this;if(typeof a=="string"){a.charAt(0)==="<"&&a.charAt(a.length-1)===">"&&a.length>=3?f=[null,a,null]:f=u.exec(a);if(f&&(f[1]||!c)){if(f[1])return c=c instanceof p?c[0]:c,i=c&&c.nodeType?c.ownerDocument||c:e,a=p.parseHTML(f[1],i,!0),v.test(f[1])&&p.isPlainObject(c)&&this.attr.call(a,c,!0),p.merge(this,a);g=e.getElementById(f[2]);if(g&&g.parentNode){if(g.id!==f[2])return d.find(a);this.length=1,this[0]=g}return this.context=e,this.selector=a,this}return!c||c.jquery?(c||d).find(a):this.constructor(c).find(a)}return p.isFunction(a)?d.ready(a):(a.selector!==b&&(this.selector=a.selector,this.context=a.context),p.makeArray(a,this))},selector:"",jquery:"1.8.2",length:0,size:function(){return this.length},toArray:function(){return k.call(this)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=p.merge(this.constructor(),a);return d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d},each:function(a,b){return p.each(this,a,b)},ready:function(a){return p.ready.promise().done(a),this},eq:function(a){return a=+a,a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(k.apply(this,arguments),"slice",k.call(arguments).join(","))},map:function(a){return this.pushStack(p.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:j,sort:[].sort,splice:[].splice},p.fn.init.prototype=p.fn,p.extend=p.fn.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;typeof h=="boolean"&&(k=h,h=arguments[1]||{},i=2),typeof h!="object"&&!p.isFunction(h)&&(h={}),j===i&&(h=this,--i);for(;i<j;i++)if((a=arguments[i])!=null)for(c in a){d=h[c],e=a[c];if(h===e)continue;k&&e&&(p.isPlainObject(e)||(f=p.isArray(e)))?(f?(f=!1,g=d&&p.isArray(d)?d:[]):g=d&&p.isPlainObject(d)?d:{},h[c]=p.extend(k,g,e)):e!==b&&(h[c]=e)}return h},p.extend({noConflict:function(b){return a.$===p&&(a.$=i),b&&a.jQuery===p&&(a.jQuery=h),p},isReady:!1,readyWait:1,holdReady:function(a){a?p.readyWait++:p.ready(!0)},ready:function(a){if(a===!0?--p.readyWait:p.isReady)return;if(!e.body)return setTimeout(p.ready,1);p.isReady=!0;if(a!==!0&&--p.readyWait>0)return;d.resolveWith(e,[p]),p.fn.trigger&&p(e).trigger("ready").off("ready")},isFunction:function(a){return p.type(a)==="function"},isArray:Array.isArray||function(a){return p.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):E[m.call(a)]||"object"},isPlainObject:function(a){if(!a||p.type(a)!=="object"||a.nodeType||p.isWindow(a))return!1;try{if(a.constructor&&!n.call(a,"constructor")&&!n.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||n.call(a,d)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},error:function(a){throw new Error(a)},parseHTML:function(a,b,c){var d;return!a||typeof a!="string"?null:(typeof b=="boolean"&&(c=b,b=0),b=b||e,(d=v.exec(a))?[b.createElement(d[1])]:(d=p.buildFragment([a],b,c?null:[]),p.merge([],(d.cacheable?p.clone(d.fragment):d.fragment).childNodes)))},parseJSON:function(b){if(!b||typeof b!="string")return null;b=p.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(w.test(b.replace(y,"@").replace(z,"]").replace(x,"")))return(new Function("return "+b))();p.error("Invalid JSON: "+b)},parseXML:function(c){var d,e;if(!c||typeof c!="string")return null;try{a.DOMParser?(e=new DOMParser,d=e.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(f){d=b}return(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&p.error("Invalid XML: "+c),d},noop:function(){},globalEval:function(b){b&&r.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(A,"ms-").replace(B,C)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,c,d){var e,f=0,g=a.length,h=g===b||p.isFunction(a);if(d){if(h){for(e in a)if(c.apply(a[e],d)===!1)break}else for(;f<g;)if(c.apply(a[f++],d)===!1)break}else if(h){for(e in a)if(c.call(a[e],e,a[e])===!1)break}else for(;f<g;)if(c.call(a[f],f,a[f++])===!1)break;return a},trim:o&&!o.call(" ")?function(a){return a==null?"":o.call(a)}:function(a){return a==null?"":(a+"").replace(t,"")},makeArray:function(a,b){var c,d=b||[];return a!=null&&(c=p.type(a),a.length==null||c==="string"||c==="function"||c==="regexp"||p.isWindow(a)?j.call(d,a):p.merge(d,a)),d},inArray:function(a,b,c){var d;if(b){if(l)return l.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=c.length,e=a.length,f=0;if(typeof d=="number")for(;f<d;f++)a[e++]=c[f];else while(c[f]!==b)a[e++]=c[f++];return a.length=e,a},grep:function(a,b,c){var d,e=[],f=0,g=a.length;c=!!c;for(;f<g;f++)d=!!b(a[f],f),c!==d&&e.push(a[f]);return e},map:function(a,c,d){var e,f,g=[],h=0,i=a.length,j=a instanceof p||i!==b&&typeof i=="number"&&(i>0&&a[0]&&a[i-1]||i===0||p.isArray(a));if(j)for(;h<i;h++)e=c(a[h],h,d),e!=null&&(g[g.length]=e);else for(f in a)e=c(a[f],f,d),e!=null&&(g[g.length]=e);return g.concat.apply([],g)},guid:1,proxy:function(a,c){var d,e,f;return typeof c=="string"&&(d=a[c],c=a,a=d),p.isFunction(a)?(e=k.call(arguments,2),f=function(){return a.apply(c,e.concat(k.call(arguments)))},f.guid=a.guid=a.guid||p.guid++,f):b},access:function(a,c,d,e,f,g,h){var i,j=d==null,k=0,l=a.length;if(d&&typeof d=="object"){for(k in d)p.access(a,c,k,d[k],1,g,e);f=1}else if(e!==b){i=h===b&&p.isFunction(e),j&&(i?(i=c,c=function(a,b,c){return i.call(p(a),c)}):(c.call(a,e),c=null));if(c)for(;k<l;k++)c(a[k],d,i?e.call(a[k],k,c(a[k],d)):e,h);f=1}return f?a:j?c.call(a):l?c(a[0],d):g},now:function(){return(new Date).getTime()}}),p.ready.promise=function(b){if(!d){d=p.Deferred();if(e.readyState==="complete")setTimeout(p.ready,1);else if(e.addEventListener)e.addEventListener("DOMContentLoaded",D,!1),a.addEventListener("load",p.ready,!1);else{e.attachEvent("onreadystatechange",D),a.attachEvent("onload",p.ready);var c=!1;try{c=a.frameElement==null&&e.documentElement}catch(f){}c&&c.doScroll&&function g(){if(!p.isReady){try{c.doScroll("left")}catch(a){return setTimeout(g,50)}p.ready()}}()}}return d.promise(b)},p.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){E["[object "+b+"]"]=b.toLowerCase()}),c=p(e);var F={};p.Callbacks=function(a){a=typeof a=="string"?F[a]||G(a):p.extend({},a);var c,d,e,f,g,h,i=[],j=!a.once&&[],k=function(b){c=a.memory&&b,d=!0,h=f||0,f=0,g=i.length,e=!0;for(;i&&h<g;h++)if(i[h].apply(b[0],b[1])===!1&&a.stopOnFalse){c=!1;break}e=!1,i&&(j?j.length&&k(j.shift()):c?i=[]:l.disable())},l={add:function(){if(i){var b=i.length;(function d(b){p.each(b,function(b,c){var e=p.type(c);e==="function"&&(!a.unique||!l.has(c))?i.push(c):c&&c.length&&e!=="string"&&d(c)})})(arguments),e?g=i.length:c&&(f=b,k(c))}return this},remove:function(){return i&&p.each(arguments,function(a,b){var c;while((c=p.inArray(b,i,c))>-1)i.splice(c,1),e&&(c<=g&&g--,c<=h&&h--)}),this},has:function(a){return p.inArray(a,i)>-1},empty:function(){return i=[],this},disable:function(){return i=j=c=b,this},disabled:function(){return!i},lock:function(){return j=b,c||l.disable(),this},locked:function(){return!j},fireWith:function(a,b){return b=b||[],b=[a,b.slice?b.slice():b],i&&(!d||j)&&(e?j.push(b):k(b)),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!d}};return l},p.extend({Deferred:function(a){var b=[["resolve","done",p.Callbacks("once memory"),"resolved"],["reject","fail",p.Callbacks("once memory"),"rejected"],["notify","progress",p.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return p.Deferred(function(c){p.each(b,function(b,d){var f=d[0],g=a[b];e[d[1]](p.isFunction(g)?function(){var a=g.apply(this,arguments);a&&p.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f+"With"](this===e?c:this,[a])}:c[f])}),a=null}).promise()},promise:function(a){return a!=null?p.extend(a,d):d}},e={};return d.pipe=d.then,p.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[a^1][2].disable,b[2][2].lock),e[f[0]]=g.fire,e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=k.call(arguments),d=c.length,e=d!==1||a&&p.isFunction(a.promise)?d:0,f=e===1?a:p.Deferred(),g=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?k.call(arguments):d,c===h?f.notifyWith(b,c):--e||f.resolveWith(b,c)}},h,i,j;if(d>1){h=new Array(d),i=new Array(d),j=new Array(d);for(;b<d;b++)c[b]&&p.isFunction(c[b].promise)?c[b].promise().done(g(b,j,c)).fail(f.reject).progress(g(b,i,h)):--e}return e||f.resolveWith(j,c),f.promise()}}),p.support=function(){var b,c,d,f,g,h,i,j,k,l,m,n=e.createElement("div");n.setAttribute("className","t"),n.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",c=n.getElementsByTagName("*"),d=n.getElementsByTagName("a")[0],d.style.cssText="top:1px;float:left;opacity:.5";if(!c||!c.length)return{};f=e.createElement("select"),g=f.appendChild(e.createElement("option")),h=n.getElementsByTagName("input")[0],b={leadingWhitespace:n.firstChild.nodeType===3,tbody:!n.getElementsByTagName("tbody").length,htmlSerialize:!!n.getElementsByTagName("link").length,style:/top/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:/^0.5/.test(d.style.opacity),cssFloat:!!d.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:n.className!=="t",enctype:!!e.createElement("form").enctype,html5Clone:e.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:e.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},h.checked=!0,b.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,b.optDisabled=!g.disabled;try{delete n.test}catch(o){b.deleteExpando=!1}!n.addEventListener&&n.attachEvent&&n.fireEvent&&(n.attachEvent("onclick",m=function(){b.noCloneEvent=!1}),n.cloneNode(!0).fireEvent("onclick"),n.detachEvent("onclick",m)),h=e.createElement("input"),h.value="t",h.setAttribute("type","radio"),b.radioValue=h.value==="t",h.setAttribute("checked","checked"),h.setAttribute("name","t"),n.appendChild(h),i=e.createDocumentFragment(),i.appendChild(n.lastChild),b.checkClone=i.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=h.checked,i.removeChild(h),i.appendChild(n);if(n.attachEvent)for(k in{submit:!0,change:!0,focusin:!0})j="on"+k,l=j in n,l||(n.setAttribute(j,"return;"),l=typeof n[j]=="function"),b[k+"Bubbles"]=l;return p(function(){var c,d,f,g,h="padding:0;margin:0;border:0;display:block;overflow:hidden;",i=e.getElementsByTagName("body")[0];if(!i)return;c=e.createElement("div"),c.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",i.insertBefore(c,i.firstChild),d=e.createElement("div"),c.appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",f=d.getElementsByTagName("td"),f[0].style.cssText="padding:0;margin:0;border:0;display:none",l=f[0].offsetHeight===0,f[0].style.display="",f[1].style.display="none",b.reliableHiddenOffsets=l&&f[0].offsetHeight===0,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",b.boxSizing=d.offsetWidth===4,b.doesNotIncludeMarginInBodyOffset=i.offsetTop!==1,a.getComputedStyle&&(b.pixelPosition=(a.getComputedStyle(d,null)||{}).top!=="1%",b.boxSizingReliable=(a.getComputedStyle(d,null)||{width:"4px"}).width==="4px",g=e.createElement("div"),g.style.cssText=d.style.cssText=h,g.style.marginRight=g.style.width="0",d.style.width="1px",d.appendChild(g),b.reliableMarginRight=!parseFloat((a.getComputedStyle(g,null)||{}).marginRight)),typeof d.style.zoom!="undefined"&&(d.innerHTML="",d.style.cssText=h+"width:1px;padding:1px;display:inline;zoom:1",b.inlineBlockNeedsLayout=d.offsetWidth===3,d.style.display="block",d.style.overflow="visible",d.innerHTML="<div></div>",d.firstChild.style.width="5px",b.shrinkWrapBlocks=d.offsetWidth!==3,c.style.zoom=1),i.removeChild(c),c=d=f=g=null}),i.removeChild(n),c=d=f=g=h=i=n=null,b}();var H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,I=/([A-Z])/g;p.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(p.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){return a=a.nodeType?p.cache[a[p.expando]]:a[p.expando],!!a&&!K(a)},data:function(a,c,d,e){if(!p.acceptData(a))return;var f,g,h=p.expando,i=typeof c=="string",j=a.nodeType,k=j?p.cache:a,l=j?a[h]:a[h]&&h;if((!l||!k[l]||!e&&!k[l].data)&&i&&d===b)return;l||(j?a[h]=l=p.deletedIds.pop()||p.guid++:l=h),k[l]||(k[l]={},j||(k[l].toJSON=p.noop));if(typeof c=="object"||typeof c=="function")e?k[l]=p.extend(k[l],c):k[l].data=p.extend(k[l].data,c);return f=k[l],e||(f.data||(f.data={}),f=f.data),d!==b&&(f[p.camelCase(c)]=d),i?(g=f[c],g==null&&(g=f[p.camelCase(c)])):g=f,g},removeData:function(a,b,c){if(!p.acceptData(a))return;var d,e,f,g=a.nodeType,h=g?p.cache:a,i=g?a[p.expando]:p.expando;if(!h[i])return;if(b){d=c?h[i]:h[i].data;if(d){p.isArray(b)||(b in d?b=[b]:(b=p.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,f=b.length;e<f;e++)delete d[b[e]];if(!(c?K:p.isEmptyObject)(d))return}}if(!c){delete h[i].data;if(!K(h[i]))return}g?p.cleanData([a],!0):p.support.deleteExpando||h!=h.window?delete h[i]:h[i]=null},_data:function(a,b,c){return p.data(a,b,c,!0)},acceptData:function(a){var b=a.nodeName&&p.noData[a.nodeName.toLowerCase()];return!b||b!==!0&&a.getAttribute("classid")===b}}),p.fn.extend({data:function(a,c){var d,e,f,g,h,i=this[0],j=0,k=null;if(a===b){if(this.length){k=p.data(i);if(i.nodeType===1&&!p._data(i,"parsedAttrs")){f=i.attributes;for(h=f.length;j<h;j++)g=f[j].name,g.indexOf("data-")||(g=p.camelCase(g.substring(5)),J(i,g,k[g]));p._data(i,"parsedAttrs",!0)}}return k}return typeof a=="object"?this.each(function(){p.data(this,a)}):(d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!",p.access(this,function(c){if(c===b)return k=this.triggerHandler("getData"+e,[d[0]]),k===b&&i&&(k=p.data(i,a),k=J(i,a,k)),k===b&&d[1]?this.data(d[0]):k;d[1]=c,this.each(function(){var b=p(this);b.triggerHandler("setData"+e,d),p.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1))},removeData:function(a){return this.each(function(){p.removeData(this,a)})}}),p.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=p._data(a,b),c&&(!d||p.isArray(c)?d=p._data(a,b,p.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=p.queue(a,b),d=c.length,e=c.shift(),f=p._queueHooks(a,b),g=function(){p.dequeue(a,b)};e==="inprogress"&&(e=c.shift(),d--),e&&(b==="fx"&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return p._data(a,c)||p._data(a,c,{empty:p.Callbacks("once memory").add(function(){p.removeData(a,b+"queue",!0),p.removeData(a,c,!0)})})}}),p.fn.extend({queue:function(a,c){var d=2;return typeof a!="string"&&(c=a,a="fx",d--),arguments.length<d?p.queue(this[0],a):c===b?this:this.each(function(){var b=p.queue(this,a,c);p._queueHooks(this,a),a==="fx"&&b[0]!=="inprogress"&&p.dequeue(this,a)})},dequeue:function(a){return this.each(function(){p.dequeue(this,a)})},delay:function(a,b){return a=p.fx?p.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){var d,e=1,f=p.Deferred(),g=this,h=this.length,i=function(){--e||f.resolveWith(g,[g])};typeof a!="string"&&(c=a,a=b),a=a||"fx";while(h--)d=p._data(g[h],a+"queueHooks"),d&&d.empty&&(e++,d.empty.add(i));return i(),f.promise(c)}});var L,M,N,O=/[\t\r\n]/g,P=/\r/g,Q=/^(?:button|input)$/i,R=/^(?:button|input|object|select|textarea)$/i,S=/^a(?:rea|)$/i,T=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,U=p.support.getSetAttribute;p.fn.extend({attr:function(a,b){return p.access(this,p.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){p.removeAttr(this,a)})},prop:function(a,b){return p.access(this,p.prop,a,b,arguments.length>1)},removeProp:function(a){return a=p.propFix[a]||a,this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,f,g,h;if(p.isFunction(a))return this.each(function(b){p(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(s);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{f=" "+e.className+" ";for(g=0,h=b.length;g<h;g++)f.indexOf(" "+b[g]+" ")<0&&(f+=b[g]+" ");e.className=p.trim(f)}}}return this},removeClass:function(a){var c,d,e,f,g,h,i;if(p.isFunction(a))return this.each(function(b){p(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(s);for(h=0,i=this.length;h<i;h++){e=this[h];if(e.nodeType===1&&e.className){d=(" "+e.className+" ").replace(O," ");for(f=0,g=c.length;f<g;f++)while(d.indexOf(" "+c[f]+" ")>=0)d=d.replace(" "+c[f]+" "," ");e.className=a?p.trim(d):""}}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";return p.isFunction(a)?this.each(function(c){p(this).toggleClass(a.call(this,c,this.className,b),b)}):this.each(function(){if(c==="string"){var e,f=0,g=p(this),h=b,i=a.split(s);while(e=i[f++])h=d?h:!g.hasClass(e),g[h?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&p._data(this,"__className__",this.className),this.className=this.className||a===!1?"":p._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(O," ").indexOf(b)>=0)return!0;return!1},val:function(a){var c,d,e,f=this[0];if(!arguments.length){if(f)return c=p.valHooks[f.type]||p.valHooks[f.nodeName.toLowerCase()],c&&"get"in c&&(d=c.get(f,"value"))!==b?d:(d=f.value,typeof d=="string"?d.replace(P,""):d==null?"":d);return}return e=p.isFunction(a),this.each(function(d){var f,g=p(this);if(this.nodeType!==1)return;e?f=a.call(this,d,g.val()):f=a,f==null?f="":typeof f=="number"?f+="":p.isArray(f)&&(f=p.map(f,function(a){return a==null?"":a+""})),c=p.valHooks[this.type]||p.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,f,"value")===b)this.value=f})}}),p.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,f=a.selectedIndex,g=[],h=a.options,i=a.type==="select-one";if(f<0)return null;c=i?f:0,d=i?f+1:h.length;for(;c<d;c++){e=h[c];if(e.selected&&(p.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!p.nodeName(e.parentNode,"optgroup"))){b=p(e).val();if(i)return b;g.push(b)}}return i&&!g.length&&h.length?p(h[f]).val():g},set:function(a,b){var c=p.makeArray(b);return p(a).find("option").each(function(){this.selected=p.inArray(p(this).val(),c)>=0}),c.length||(a.selectedIndex=-1),c}}},attrFn:{},attr:function(a,c,d,e){var f,g,h,i=a.nodeType;if(!a||i===3||i===8||i===2)return;if(e&&p.isFunction(p.fn[c]))return p(a)[c](d);if(typeof a.getAttribute=="undefined")return p.prop(a,c,d);h=i!==1||!p.isXMLDoc(a),h&&(c=c.toLowerCase(),g=p.attrHooks[c]||(T.test(c)?M:L));if(d!==b){if(d===null){p.removeAttr(a,c);return}return g&&"set"in g&&h&&(f=g.set(a,d,c))!==b?f:(a.setAttribute(c,d+""),d)}return g&&"get"in g&&h&&(f=g.get(a,c))!==null?f:(f=a.getAttribute(c),f===null?b:f)},removeAttr:function(a,b){var c,d,e,f,g=0;if(b&&a.nodeType===1){d=b.split(s);for(;g<d.length;g++)e=d[g],e&&(c=p.propFix[e]||e,f=T.test(e),f||p.attr(a,e,""),a.removeAttribute(U?e:c),f&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(Q.test(a.nodeName)&&a.parentNode)p.error("type property can't be changed");else if(!p.support.radioValue&&b==="radio"&&p.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}},value:{get:function(a,b){return L&&p.nodeName(a,"button")?L.get(a,b):b in a?a.value:null},set:function(a,b,c){if(L&&p.nodeName(a,"button"))return L.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,f,g,h=a.nodeType;if(!a||h===3||h===8||h===2)return;return g=h!==1||!p.isXMLDoc(a),g&&(c=p.propFix[c]||c,f=p.propHooks[c]),d!==b?f&&"set"in f&&(e=f.set(a,d,c))!==b?e:a[c]=d:f&&"get"in f&&(e=f.get(a,c))!==null?e:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):R.test(a.nodeName)||S.test(a.nodeName)&&a.href?0:b}}}}),M={get:function(a,c){var d,e=p.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;return b===!1?p.removeAttr(a,c):(d=p.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase())),c}},U||(N={name:!0,id:!0,coords:!0},L=p.valHooks.button={get:function(a,c){var d;return d=a.getAttributeNode(c),d&&(N[c]?d.value!=="":d.specified)?d.value:b},set:function(a,b,c){var d=a.getAttributeNode(c);return d||(d=e.createAttribute(c),a.setAttributeNode(d)),d.value=b+""}},p.each(["width","height"],function(a,b){p.attrHooks[b]=p.extend(p.attrHooks[b],{set:function(a,c){if(c==="")return a.setAttribute(b,"auto"),c}})}),p.attrHooks.contenteditable={get:L.get,set:function(a,b,c){b===""&&(b="false"),L.set(a,b,c)}}),p.support.hrefNormalized||p.each(["href","src","width","height"],function(a,c){p.attrHooks[c]=p.extend(p.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),p.support.style||(p.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=b+""}}),p.support.optSelected||(p.propHooks.selected=p.extend(p.propHooks.selected,{get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}})),p.support.enctype||(p.propFix.enctype="encoding"),p.support.checkOn||p.each(["radio","checkbox"],function(){p.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),p.each(["radio","checkbox"],function(){p.valHooks[this]=p.extend(p.valHooks[this],{set:function(a,b){if(p.isArray(b))return a.checked=p.inArray(p(a).val(),b)>=0}})});var V=/^(?:textarea|input|select)$/i,W=/^([^\.]*|)(?:\.(.+)|)$/,X=/(?:^|\s)hover(\.\S+|)\b/,Y=/^key/,Z=/^(?:mouse|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=function(a){return p.event.special.hover?a:a.replace(X,"mouseenter$1 mouseleave$1")};p.event={add:function(a,c,d,e,f){var g,h,i,j,k,l,m,n,o,q,r;if(a.nodeType===3||a.nodeType===8||!c||!d||!(g=p._data(a)))return;d.handler&&(o=d,d=o.handler,f=o.selector),d.guid||(d.guid=p.guid++),i=g.events,i||(g.events=i={}),h=g.handle,h||(g.handle=h=function(a){return typeof p!="undefined"&&(!a||p.event.triggered!==a.type)?p.event.dispatch.apply(h.elem,arguments):b},h.elem=a),c=p.trim(_(c)).split(" ");for(j=0;j<c.length;j++){k=W.exec(c[j])||[],l=k[1],m=(k[2]||"").split(".").sort(),r=p.event.special[l]||{},l=(f?r.delegateType:r.bindType)||l,r=p.event.special[l]||{},n=p.extend({type:l,origType:k[1],data:e,handler:d,guid:d.guid,selector:f,needsContext:f&&p.expr.match.needsContext.test(f),namespace:m.join(".")},o),q=i[l];if(!q){q=i[l]=[],q.delegateCount=0;if(!r.setup||r.setup.call(a,e,m,h)===!1)a.addEventListener?a.addEventListener(l,h,!1):a.attachEvent&&a.attachEvent("on"+l,h)}r.add&&(r.add.call(a,n),n.handler.guid||(n.handler.guid=d.guid)),f?q.splice(q.delegateCount++,0,n):q.push(n),p.event.global[l]=!0}a=null},global:{},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,q,r=p.hasData(a)&&p._data(a);if(!r||!(m=r.events))return;b=p.trim(_(b||"")).split(" ");for(f=0;f<b.length;f++){g=W.exec(b[f])||[],h=i=g[1],j=g[2];if(!h){for(h in m)p.event.remove(a,h+b[f],c,d,!0);continue}n=p.event.special[h]||{},h=(d?n.delegateType:n.bindType)||h,o=m[h]||[],k=o.length,j=j?new RegExp("(^|\\.)"+j.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(l=0;l<o.length;l++)q=o[l],(e||i===q.origType)&&(!c||c.guid===q.guid)&&(!j||j.test(q.namespace))&&(!d||d===q.selector||d==="**"&&q.selector)&&(o.splice(l--,1),q.selector&&o.delegateCount--,n.remove&&n.remove.call(a,q));o.length===0&&k!==o.length&&((!n.teardown||n.teardown.call(a,j,r.handle)===!1)&&p.removeEvent(a,h,r.handle),delete m[h])}p.isEmptyObject(m)&&(delete r.handle,p.removeData(a,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,f,g){if(!f||f.nodeType!==3&&f.nodeType!==8){var h,i,j,k,l,m,n,o,q,r,s=c.type||c,t=[];if($.test(s+p.event.triggered))return;s.indexOf("!")>=0&&(s=s.slice(0,-1),i=!0),s.indexOf(".")>=0&&(t=s.split("."),s=t.shift(),t.sort());if((!f||p.event.customEvent[s])&&!p.event.global[s])return;c=typeof c=="object"?c[p.expando]?c:new p.Event(s,c):new p.Event(s),c.type=s,c.isTrigger=!0,c.exclusive=i,c.namespace=t.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,m=s.indexOf(":")<0?"on"+s:"";if(!f){h=p.cache;for(j in h)h[j].events&&h[j].events[s]&&p.event.trigger(c,d,h[j].handle.elem,!0);return}c.result=b,c.target||(c.target=f),d=d!=null?p.makeArray(d):[],d.unshift(c),n=p.event.special[s]||{};if(n.trigger&&n.trigger.apply(f,d)===!1)return;q=[[f,n.bindType||s]];if(!g&&!n.noBubble&&!p.isWindow(f)){r=n.delegateType||s,k=$.test(r+s)?f:f.parentNode;for(l=f;k;k=k.parentNode)q.push([k,r]),l=k;l===(f.ownerDocument||e)&&q.push([l.defaultView||l.parentWindow||a,r])}for(j=0;j<q.length&&!c.isPropagationStopped();j++)k=q[j][0],c.type=q[j][1],o=(p._data(k,"events")||{})[c.type]&&p._data(k,"handle"),o&&o.apply(k,d),o=m&&k[m],o&&p.acceptData(k)&&o.apply&&o.apply(k,d)===!1&&c.preventDefault();return c.type=s,!g&&!c.isDefaultPrevented()&&(!n._default||n._default.apply(f.ownerDocument,d)===!1)&&(s!=="click"||!p.nodeName(f,"a"))&&p.acceptData(f)&&m&&f[s]&&(s!=="focus"&&s!=="blur"||c.target.offsetWidth!==0)&&!p.isWindow(f)&&(l=f[m],l&&(f[m]=null),p.event.triggered=s,f[s](),p.event.triggered=b,l&&(f[m]=l)),c.result}return},dispatch:function(c){c=p.event.fix(c||a.event);var d,e,f,g,h,i,j,l,m,n,o=(p._data(this,"events")||{})[c.type]||[],q=o.delegateCount,r=k.call(arguments),s=!c.exclusive&&!c.namespace,t=p.event.special[c.type]||{},u=[];r[0]=c,c.delegateTarget=this;if(t.preDispatch&&t.preDispatch.call(this,c)===!1)return;if(q&&(!c.button||c.type!=="click"))for(f=c.target;f!=this;f=f.parentNode||this)if(f.disabled!==!0||c.type!=="click"){h={},j=[];for(d=0;d<q;d++)l=o[d],m=l.selector,h[m]===b&&(h[m]=l.needsContext?p(m,this).index(f)>=0:p.find(m,this,null,[f]).length),h[m]&&j.push(l);j.length&&u.push({elem:f,matches:j})}o.length>q&&u.push({elem:this,matches:o.slice(q)});for(d=0;d<u.length&&!c.isPropagationStopped();d++){i=u[d],c.currentTarget=i.elem;for(e=0;e<i.matches.length&&!c.isImmediatePropagationStopped();e++){l=i.matches[e];if(s||!c.namespace&&!l.namespace||c.namespace_re&&c.namespace_re.test(l.namespace))c.data=l.data,c.handleObj=l,g=((p.event.special[l.origType]||{}).handle||l.handler).apply(i.elem,r),g!==b&&(c.result=g,g===!1&&(c.preventDefault(),c.stopPropagation()))}}return t.postDispatch&&t.postDispatch.call(this,c),c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,c){var d,f,g,h=c.button,i=c.fromElement;return a.pageX==null&&c.clientX!=null&&(d=a.target.ownerDocument||e,f=d.documentElement,g=d.body,a.pageX=c.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=c.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?c.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0),a}},fix:function(a){if(a[p.expando])return a;var b,c,d=a,f=p.event.fixHooks[a.type]||{},g=f.props?this.props.concat(f.props):this.props;a=p.Event(d);for(b=g.length;b;)c=g[--b],a[c]=d[c];return a.target||(a.target=d.srcElement||e),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,f.filter?f.filter(a,d):a},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){p.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=p.extend(new p.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?p.event.trigger(e,null,b):p.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},p.event.handle=p.event.dispatch,p.removeEvent=e.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]=="undefined"&&(a[d]=null),a.detachEvent(d,c))},p.Event=function(a,b){if(this instanceof p.Event)a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?bb:ba):this.type=a,b&&p.extend(this,b),this.timeStamp=a&&a.timeStamp||p.now(),this[p.expando]=!0;else return new p.Event(a,b)},p.Event.prototype={preventDefault:function(){this.isDefaultPrevented=bb;var a=this.originalEvent;if(!a)return;a.preventDefault?a.preventDefault():a.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=bb;var a=this.originalEvent;if(!a)return;a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=bb,this.stopPropagation()},isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba},p.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){p.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj,g=f.selector;if(!e||e!==d&&!p.contains(d,e))a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b;return c}}}),p.support.submitBubbles||(p.event.special.submit={setup:function(){if(p.nodeName(this,"form"))return!1;p.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=p.nodeName(c,"input")||p.nodeName(c,"button")?c.form:b;d&&!p._data(d,"_submit_attached")&&(p.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),p._data(d,"_submit_attached",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&p.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(p.nodeName(this,"form"))return!1;p.event.remove(this,"._submit")}}),p.support.changeBubbles||(p.event.special.change={setup:function(){if(V.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")p.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),p.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),p.event.simulate("change",this,a,!0)});return!1}p.event.add(this,"beforeactivate._change",function(a){var b=a.target;V.test(b.nodeName)&&!p._data(b,"_change_attached")&&(p.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&p.event.simulate("change",this.parentNode,a,!0)}),p._data(b,"_change_attached",!0))})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){return p.event.remove(this,"._change"),!V.test(this.nodeName)}}),p.support.focusinBubbles||p.each({focus:"focusin",blur:"focusout"},function(a,b){var c=0,d=function(a){p.event.simulate(b,a.target,p.event.fix(a),!0)};p.event.special[b]={setup:function(){c++===0&&e.addEventListener(a,d,!0)},teardown:function(){--c===0&&e.removeEventListener(a,d,!0)}}}),p.fn.extend({on:function(a,c,d,e,f){var g,h;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(h in a)this.on(h,c,d,a[h],f);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=ba;else if(!e)return this;return f===1&&(g=e,e=function(a){return p().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=p.guid++)),this.each(function(){p.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){var e,f;if(a&&a.preventDefault&&a.handleObj)return e=a.handleObj,p(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler),this;if(typeof a=="object"){for(f in a)this.off(f,c,a[f]);return this}if(c===!1||typeof c=="function")d=c,c=b;return d===!1&&(d=ba),this.each(function(){p.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){return p(this.context).on(a,this.selector,b,c),this},die:function(a,b){return p(this.context).off(a,this.selector||"**",b),this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length===1?this.off(a,"**"):this.off(b,a||"**",c)},trigger:function(a,b){return this.each(function(){p.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return p.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||p.guid++,d=0,e=function(c){var e=(p._data(this,"lastToggle"+a.guid)||0)%d;return p._data(this,"lastToggle"+a.guid,e+1),c.preventDefault(),b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),p.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){p.fn[b]=function(a,c){return c==null&&(c=a,a=null),arguments.length>0?this.on(b,null,a,c):this.trigger(b)},Y.test(b)&&(p.event.fixHooks[b]=p.event.keyHooks),Z.test(b)&&(p.event.fixHooks[b]=p.event.mouseHooks)}),function(a,b){function bc(a,b,c,d){c=c||[],b=b||r;var e,f,i,j,k=b.nodeType;if(!a||typeof a!="string")return c;if(k!==1&&k!==9)return[];i=g(b);if(!i&&!d)if(e=P.exec(a))if(j=e[1]){if(k===9){f=b.getElementById(j);if(!f||!f.parentNode)return c;if(f.id===j)return c.push(f),c}else if(b.ownerDocument&&(f=b.ownerDocument.getElementById(j))&&h(b,f)&&f.id===j)return c.push(f),c}else{if(e[2])return w.apply(c,x.call(b.getElementsByTagName(a),0)),c;if((j=e[3])&&_&&b.getElementsByClassName)return w.apply(c,x.call(b.getElementsByClassName(j),0)),c}return bp(a.replace(L,"$1"),b,c,d,i)}function bd(a){return function(b){var c=b.nodeName.toLowerCase();return c==="input"&&b.type===a}}function be(a){return function(b){var c=b.nodeName.toLowerCase();return(c==="input"||c==="button")&&b.type===a}}function bf(a){return z(function(b){return b=+b,z(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function bg(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}function bh(a,b){var c,d,f,g,h,i,j,k=C[o][a];if(k)return b?0:k.slice(0);h=a,i=[],j=e.preFilter;while(h){if(!c||(d=M.exec(h)))d&&(h=h.slice(d[0].length)),i.push(f=[]);c=!1;if(d=N.exec(h))f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=d[0].replace(L," ");for(g in e.filter)(d=W[g].exec(h))&&(!j[g]||(d=j[g](d,r,!0)))&&(f.push(c=new q(d.shift())),h=h.slice(c.length),c.type=g,c.matches=d);if(!c)break}return b?h.length:h?bc.error(a):C(a,i).slice(0)}function bi(a,b,d){var e=b.dir,f=d&&b.dir==="parentNode",g=u++;return b.first?function(b,c,d){while(b=b[e])if(f||b.nodeType===1)return a(b,c,d)}:function(b,d,h){if(!h){var i,j=t+" "+g+" ",k=j+c;while(b=b[e])if(f||b.nodeType===1){if((i=b[o])===k)return b.sizset;if(typeof i=="string"&&i.indexOf(j)===0){if(b.sizset)return b}else{b[o]=k;if(a(b,d,h))return b.sizset=!0,b;b.sizset=!1}}}else while(b=b[e])if(f||b.nodeType===1)if(a(b,d,h))return b}}function bj(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function bk(a,b,c,d,e){var f,g=[],h=0,i=a.length,j=b!=null;for(;h<i;h++)if(f=a[h])if(!c||c(f,d,e))g.push(f),j&&b.push(h);return g}function bl(a,b,c,d,e,f){return d&&!d[o]&&(d=bl(d)),e&&!e[o]&&(e=bl(e,f)),z(function(f,g,h,i){if(f&&e)return;var j,k,l,m=[],n=[],o=g.length,p=f||bo(b||"*",h.nodeType?[h]:h,[],f),q=a&&(f||!b)?bk(p,m,a,h,i):p,r=c?e||(f?a:o||d)?[]:g:q;c&&c(q,r,h,i);if(d){l=bk(r,n),d(l,[],h,i),j=l.length;while(j--)if(k=l[j])r[n[j]]=!(q[n[j]]=k)}if(f){j=a&&r.length;while(j--)if(k=r[j])f[m[j]]=!(g[m[j]]=k)}else r=bk(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):w.apply(g,r)})}function bm(a){var b,c,d,f=a.length,g=e.relative[a[0].type],h=g||e.relative[" "],i=g?1:0,j=bi(function(a){return a===b},h,!0),k=bi(function(a){return y.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==l)||((b=c).nodeType?j(a,c,d):k(a,c,d))}];for(;i<f;i++)if(c=e.relative[a[i].type])m=[bi(bj(m),c)];else{c=e.filter[a[i].type].apply(null,a[i].matches);if(c[o]){d=++i;for(;d<f;d++)if(e.relative[a[d].type])break;return bl(i>1&&bj(m),i>1&&a.slice(0,i-1).join("").replace(L,"$1"),c,i<d&&bm(a.slice(i,d)),d<f&&bm(a=a.slice(d)),d<f&&a.join(""))}m.push(c)}return bj(m)}function bn(a,b){var d=b.length>0,f=a.length>0,g=function(h,i,j,k,m){var n,o,p,q=[],s=0,u="0",x=h&&[],y=m!=null,z=l,A=h||f&&e.find.TAG("*",m&&i.parentNode||i),B=t+=z==null?1:Math.E;y&&(l=i!==r&&i,c=g.el);for(;(n=A[u])!=null;u++){if(f&&n){for(o=0;p=a[o];o++)if(p(n,i,j)){k.push(n);break}y&&(t=B,c=++g.el)}d&&((n=!p&&n)&&s--,h&&x.push(n))}s+=u;if(d&&u!==s){for(o=0;p=b[o];o++)p(x,q,i,j);if(h){if(s>0)while(u--)!x[u]&&!q[u]&&(q[u]=v.call(k));q=bk(q)}w.apply(k,q),y&&!h&&q.length>0&&s+b.length>1&&bc.uniqueSort(k)}return y&&(t=B,l=z),x};return g.el=0,d?z(g):g}function bo(a,b,c,d){var e=0,f=b.length;for(;e<f;e++)bc(a,b[e],c,d);return c}function bp(a,b,c,d,f){var g,h,j,k,l,m=bh(a),n=m.length;if(!d&&m.length===1){h=m[0]=m[0].slice(0);if(h.length>2&&(j=h[0]).type==="ID"&&b.nodeType===9&&!f&&e.relative[h[1].type]){b=e.find.ID(j.matches[0].replace(V,""),b,f)[0];if(!b)return c;a=a.slice(h.shift().length)}for(g=W.POS.test(a)?-1:h.length-1;g>=0;g--){j=h[g];if(e.relative[k=j.type])break;if(l=e.find[k])if(d=l(j.matches[0].replace(V,""),R.test(h[0].type)&&b.parentNode||b,f)){h.splice(g,1),a=d.length&&h.join("");if(!a)return w.apply(c,x.call(d,0)),c;break}}}return i(a,m)(d,b,f,c,R.test(a)),c}function bq(){}var c,d,e,f,g,h,i,j,k,l,m=!0,n="undefined",o=("sizcache"+Math.random()).replace(".",""),q=String,r=a.document,s=r.documentElement,t=0,u=0,v=[].pop,w=[].push,x=[].slice,y=[].indexOf||function(a){var b=0,c=this.length;for(;b<c;b++)if(this[b]===a)return b;return-1},z=function(a,b){return a[o]=b==null||b,a},A=function(){var a={},b=[];return z(function(c,d){return b.push(c)>e.cacheLength&&delete a[b.shift()],a[c]=d},a)},B=A(),C=A(),D=A(),E="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",G=F.replace("w","w#"),H="([*^$|!~]?=)",I="\\["+E+"*("+F+")"+E+"*(?:"+H+E+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+G+")|)|)"+E+"*\\]",J=":("+F+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+I+")|[^:]|\\\\.)*|.*))\\)|)",K=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+E+"*((?:-\\d)?\\d*)"+E+"*\\)|)(?=[^-]|$)",L=new RegExp("^"+E+"+|((?:^|[^\\\\])(?:\\\\.)*)"+E+"+$","g"),M=new RegExp("^"+E+"*,"+E+"*"),N=new RegExp("^"+E+"*([\\x20\\t\\r\\n\\f>+~])"+E+"*"),O=new RegExp(J),P=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,Q=/^:not/,R=/[\x20\t\r\n\f]*[+~]/,S=/:not\($/,T=/h\d/i,U=/input|select|textarea|button/i,V=/\\(?!\\)/g,W={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),NAME:new RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:new RegExp("^("+F.replace("w","w*")+")"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+J),POS:new RegExp(K,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+E+"*(even|odd|(([+-]|)(\\d*)n|)"+E+"*(?:([+-]|)"+E+"*(\\d+)|))"+E+"*\\)|)","i"),needsContext:new RegExp("^"+E+"*[>+~]|"+K,"i")},X=function(a){var b=r.createElement("div");try{return a(b)}catch(c){return!1}finally{b=null}},Y=X(function(a){return a.appendChild(r.createComment("")),!a.getElementsByTagName("*").length}),Z=X(function(a){return a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!==n&&a.firstChild.getAttribute("href")==="#"}),$=X(function(a){a.innerHTML="<select></select>";var b=typeof a.lastChild.getAttribute("multiple");return b!=="boolean"&&b!=="string"}),_=X(function(a){return a.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!a.getElementsByClassName||!a.getElementsByClassName("e").length?!1:(a.lastChild.className="e",a.getElementsByClassName("e").length===2)}),ba=X(function(a){a.id=o+0,a.innerHTML="<a name='"+o+"'></a><div name='"+o+"'></div>",s.insertBefore(a,s.firstChild);var b=r.getElementsByName&&r.getElementsByName(o).length===2+r.getElementsByName(o+0).length;return d=!r.getElementById(o),s.removeChild(a),b});try{x.call(s.childNodes,0)[0].nodeType}catch(bb){x=function(a){var b,c=[];for(;b=this[a];a++)c.push(b);return c}}bc.matches=function(a,b){return bc(a,null,null,b)},bc.matchesSelector=function(a,b){return bc(b,null,null,[a]).length>0},f=bc.getText=function(a){var b,c="",d=0,e=a.nodeType;if(e){if(e===1||e===9||e===11){if(typeof a.textContent=="string")return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=f(a)}else if(e===3||e===4)return a.nodeValue}else for(;b=a[d];d++)c+=f(b);return c},g=bc.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?b.nodeName!=="HTML":!1},h=bc.contains=s.contains?function(a,b){var c=a.nodeType===9?a.documentElement:a,d=b&&b.parentNode;return a===d||!!(d&&d.nodeType===1&&c.contains&&c.contains(d))}:s.compareDocumentPosition?function(a,b){return b&&!!(a.compareDocumentPosition(b)&16)}:function(a,b){while(b=b.parentNode)if(b===a)return!0;return!1},bc.attr=function(a,b){var c,d=g(a);return d||(b=b.toLowerCase()),(c=e.attrHandle[b])?c(a):d||$?a.getAttribute(b):(c=a.getAttributeNode(b),c?typeof a[b]=="boolean"?a[b]?b:null:c.specified?c.value:null:null)},e=bc.selectors={cacheLength:50,createPseudo:z,match:W,attrHandle:Z?{}:{href:function(a){return a.getAttribute("href",2)},type:function(a){return a.getAttribute("type")}},find:{ID:d?function(a,b,c){if(typeof b.getElementById!==n&&!c){var d=b.getElementById(a);return d&&d.parentNode?[d]:[]}}:function(a,c,d){if(typeof c.getElementById!==n&&!d){var e=c.getElementById(a);return e?e.id===a||typeof e.getAttributeNode!==n&&e.getAttributeNode("id").value===a?[e]:b:[]}},TAG:Y?function(a,b){if(typeof b.getElementsByTagName!==n)return b.getElementsByTagName(a)}:function(a,b){var c=b.getElementsByTagName(a);if(a==="*"){var d,e=[],f=0;for(;d=c[f];f++)d.nodeType===1&&e.push(d);return e}return c},NAME:ba&&function(a,b){if(typeof b.getElementsByName!==n)return b.getElementsByName(name)},CLASS:_&&function(a,b,c){if(typeof b.getElementsByClassName!==n&&!c)return b.getElementsByClassName(a)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(V,""),a[3]=(a[4]||a[5]||"").replace(V,""),a[2]==="~="&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),a[1]==="nth"?(a[2]||bc.error(a[0]),a[3]=+(a[3]?a[4]+(a[5]||1):2*(a[2]==="even"||a[2]==="odd")),a[4]=+(a[6]+a[7]||a[2]==="odd")):a[2]&&bc.error(a[0]),a},PSEUDO:function(a){var b,c;if(W.CHILD.test(a[0]))return null;if(a[3])a[2]=a[3];else if(b=a[4])O.test(b)&&(c=bh(b,!0))&&(c=b.indexOf(")",b.length-c)-b.length)&&(b=b.slice(0,c),a[0]=a[0].slice(0,c)),a[2]=b;return a.slice(0,3)}},filter:{ID:d?function(a){return a=a.replace(V,""),function(b){return b.getAttribute("id")===a}}:function(a){return a=a.replace(V,""),function(b){var c=typeof b.getAttributeNode!==n&&b.getAttributeNode("id");return c&&c.value===a}},TAG:function(a){return a==="*"?function(){return!0}:(a=a.replace(V,"").toLowerCase(),function(b){return b.nodeName&&b.nodeName.toLowerCase()===a})},CLASS:function(a){var b=B[o][a];return b||(b=B(a,new RegExp("(^|"+E+")"+a+"("+E+"|$)"))),function(a){return b.test(a.className||typeof a.getAttribute!==n&&a.getAttribute("class")||"")}},ATTR:function(a,b,c){return function(d,e){var f=bc.attr(d,a);return f==null?b==="!=":b?(f+="",b==="="?f===c:b==="!="?f!==c:b==="^="?c&&f.indexOf(c)===0:b==="*="?c&&f.indexOf(c)>-1:b==="$="?c&&f.substr(f.length-c.length)===c:b==="~="?(" "+f+" ").indexOf(c)>-1:b==="|="?f===c||f.substr(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d){return a==="nth"?function(a){var b,e,f=a.parentNode;if(c===1&&d===0)return!0;if(f){e=0;for(b=f.firstChild;b;b=b.nextSibling)if(b.nodeType===1){e++;if(a===b)break}}return e-=d,e===c||e%c===0&&e/c>=0}:function(b){var c=b;switch(a){case"only":case"first":while(c=c.previousSibling)if(c.nodeType===1)return!1;if(a==="first")return!0;c=b;case"last":while(c=c.nextSibling)if(c.nodeType===1)return!1;return!0}}},PSEUDO:function(a,b){var c,d=e.pseudos[a]||e.setFilters[a.toLowerCase()]||bc.error("unsupported pseudo: "+a);return d[o]?d(b):d.length>1?(c=[a,a,"",b],e.setFilters.hasOwnProperty(a.toLowerCase())?z(function(a,c){var e,f=d(a,b),g=f.length;while(g--)e=y.call(a,f[g]),a[e]=!(c[e]=f[g])}):function(a){return d(a,0,c)}):d}},pseudos:{not:z(function(a){var b=[],c=[],d=i(a.replace(L,"$1"));return d[o]?z(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)if(f=g[h])a[h]=!(b[h]=f)}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:z(function(a){return function(b){return bc(a,b).length>0}}),contains:z(function(a){return function(b){return(b.textContent||b.innerText||f(b)).indexOf(a)>-1}}),enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&!!a.checked||b==="option"&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},parent:function(a){return!e.pseudos.empty(a)},empty:function(a){var b;a=a.firstChild;while(a){if(a.nodeName>"@"||(b=a.nodeType)===3||b===4)return!1;a=a.nextSibling}return!0},header:function(a){return T.test(a.nodeName)},text:function(a){var b,c;return a.nodeName.toLowerCase()==="input"&&(b=a.type)==="text"&&((c=a.getAttribute("type"))==null||c.toLowerCase()===b)},radio:bd("radio"),checkbox:bd("checkbox"),file:bd("file"),password:bd("password"),image:bd("image"),submit:be("submit"),reset:be("reset"),button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&a.type==="button"||b==="button"},input:function(a){return U.test(a.nodeName)},focus:function(a){var b=a.ownerDocument;return a===b.activeElement&&(!b.hasFocus||b.hasFocus())&&(!!a.type||!!a.href)},active:function(a){return a===a.ownerDocument.activeElement},first:bf(function(a,b,c){return[0]}),last:bf(function(a,b,c){return[b-1]}),eq:bf(function(a,b,c){return[c<0?c+b:c]}),even:bf(function(a,b,c){for(var d=0;d<b;d+=2)a.push(d);return a}),odd:bf(function(a,b,c){for(var d=1;d<b;d+=2)a.push(d);return a}),lt:bf(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:bf(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},j=s.compareDocumentPosition?function(a,b){return a===b?(k=!0,0):(!a.compareDocumentPosition||!b.compareDocumentPosition?a.compareDocumentPosition:a.compareDocumentPosition(b)&4)?-1:1}:function(a,b){if(a===b)return k=!0,0;if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,h=b.parentNode,i=g;if(g===h)return bg(a,b);if(!g)return-1;if(!h)return 1;while(i)e.unshift(i),i=i.parentNode;i=h;while(i)f.unshift(i),i=i.parentNode;c=e.length,d=f.length;for(var j=0;j<c&&j<d;j++)if(e[j]!==f[j])return bg(e[j],f[j]);return j===c?bg(a,f[j],-1):bg(e[j],b,1)},[0,0].sort(j),m=!k,bc.uniqueSort=function(a){var b,c=1;k=m,a.sort(j);if(k)for(;b=a[c];c++)b===a[c-1]&&a.splice(c--,1);return a},bc.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},i=bc.compile=function(a,b){var c,d=[],e=[],f=D[o][a];if(!f){b||(b=bh(a)),c=b.length;while(c--)f=bm(b[c]),f[o]?d.push(f):e.push(f);f=D(a,bn(e,d))}return f},r.querySelectorAll&&function(){var a,b=bp,c=/'|\\/g,d=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,e=[":focus"],f=[":active",":focus"],h=s.matchesSelector||s.mozMatchesSelector||s.webkitMatchesSelector||s.oMatchesSelector||s.msMatchesSelector;X(function(a){a.innerHTML="<select><option selected=''></option></select>",a.querySelectorAll("[selected]").length||e.push("\\["+E+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),a.querySelectorAll(":checked").length||e.push(":checked")}),X(function(a){a.innerHTML="<p test=''></p>",a.querySelectorAll("[test^='']").length&&e.push("[*^$]="+E+"*(?:\"\"|'')"),a.innerHTML="<input type='hidden'/>",a.querySelectorAll(":enabled").length||e.push(":enabled",":disabled")}),e=new RegExp(e.join("|")),bp=function(a,d,f,g,h){if(!g&&!h&&(!e||!e.test(a))){var i,j,k=!0,l=o,m=d,n=d.nodeType===9&&a;if(d.nodeType===1&&d.nodeName.toLowerCase()!=="object"){i=bh(a),(k=d.getAttribute("id"))?l=k.replace(c,"\\$&"):d.setAttribute("id",l),l="[id='"+l+"'] ",j=i.length;while(j--)i[j]=l+i[j].join("");m=R.test(a)&&d.parentNode||d,n=i.join(",")}if(n)try{return w.apply(f,x.call(m.querySelectorAll(n),0)),f}catch(p){}finally{k||d.removeAttribute("id")}}return b(a,d,f,g,h)},h&&(X(function(b){a=h.call(b,"div");try{h.call(b,"[test!='']:sizzle"),f.push("!=",J)}catch(c){}}),f=new RegExp(f.join("|")),bc.matchesSelector=function(b,c){c=c.replace(d,"='$1']");if(!g(b)&&!f.test(c)&&(!e||!e.test(c)))try{var i=h.call(b,c);if(i||a||b.document&&b.document.nodeType!==11)return i}catch(j){}return bc(c,null,null,[b]).length>0})}(),e.pseudos.nth=e.pseudos.eq,e.filters=bq.prototype=e.pseudos,e.setFilters=new bq,bc.attr=p.attr,p.find=bc,p.expr=bc.selectors,p.expr[":"]=p.expr.pseudos,p.unique=bc.uniqueSort,p.text=bc.getText,p.isXMLDoc=bc.isXML,p.contains=bc.contains}(a);var bc=/Until$/,bd=/^(?:parents|prev(?:Until|All))/,be=/^.[^:#\[\.,]*$/,bf=p.expr.match.needsContext,bg={children:!0,contents:!0,next:!0,prev:!0};p.fn.extend({find:function(a){var b,c,d,e,f,g,h=this;if(typeof a!="string")return p(a).filter(function(){for(b=0,c=h.length;b<c;b++)if(p.contains(h[b],this))return!0});g=this.pushStack("","find",a);for(b=0,c=this.length;b<c;b++){d=g.length,p.find(a,this[b],g);if(b>0)for(e=d;e<g.length;e++)for(f=0;f<d;f++)if(g[f]===g[e]){g.splice(e--,1);break}}return g},has:function(a){var b,c=p(a,this),d=c.length;return this.filter(function(){for(b=0;b<d;b++)if(p.contains(this,c[b]))return!0})},not:function(a){return this.pushStack(bj(this,a,!1),"not",a)},filter:function(a){return this.pushStack(bj(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?bf.test(a)?p(a,this.context).index(this[0])>=0:p.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c,d=0,e=this.length,f=[],g=bf.test(a)||typeof a!="string"?p(a,b||this.context):0;for(;d<e;d++){c=this[d];while(c&&c.ownerDocument&&c!==b&&c.nodeType!==11){if(g?g.index(c)>-1:p.find.matchesSelector(c,a)){f.push(c);break}c=c.parentNode}}return f=f.length>1?p.unique(f):f,this.pushStack(f,"closest",a)},index:function(a){return a?typeof a=="string"?p.inArray(this[0],p(a)):p.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?d:p.unique(d))},addBack:function(a){return this.add(a==null?this.prevObject:this.prevObject.filter(a))}}),p.fn.andSelf=p.fn.addBack,p.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return p.dir(a,"parentNode")},parentsUntil:function(a,b,c){return p.dir(a,"parentNode",c)},next:function(a){return bi(a,"nextSibling")},prev:function(a){return bi(a,"previousSibling")},nextAll:function(a){return p.dir(a,"nextSibling")},prevAll:function(a){return p.dir(a,"previousSibling")},nextUntil:function(a,b,c){return p.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return p.dir(a,"previousSibling",c)},siblings:function(a){return p.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return p.sibling(a.firstChild)},contents:function(a){return p.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:p.merge([],a.childNodes)}},function(a,b){p.fn[a]=function(c,d){var e=p.map(this,b,c);return bc.test(a)||(d=c),d&&typeof d=="string"&&(e=p.filter(d,e)),e=this.length>1&&!bg[a]?p.unique(e):e,this.length>1&&bd.test(a)&&(e=e.reverse()),this.pushStack(e,a,k.call(arguments).join(","))}}),p.extend({filter:function(a,b,c){return c&&(a=":not("+a+")"),b.length===1?p.find.matchesSelector(b[0],a)?[b[0]]:[]:p.find.matches(a,b)},dir:function(a,c,d){var e=[],f=a[c];while(f&&f.nodeType!==9&&(d===b||f.nodeType!==1||!p(f).is(d)))f.nodeType===1&&e.push(f),f=f[c];return e},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var bl="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",bm=/ jQuery\d+="(?:null|\d+)"/g,bn=/^\s+/,bo=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bp=/<([\w:]+)/,bq=/<tbody/i,br=/<|&#?\w+;/,bs=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,bu=new RegExp("<(?:"+bl+")[\\s/>]","i"),bv=/^(?:checkbox|radio)$/,bw=/checked\s*(?:[^=]|=\s*.checked.)/i,bx=/\/(java|ecma)script/i,by=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,bz={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bA=bk(e),bB=bA.appendChild(e.createElement("div"));bz.optgroup=bz.option,bz.tbody=bz.tfoot=bz.colgroup=bz.caption=bz.thead,bz.th=bz.td,p.support.htmlSerialize||(bz._default=[1,"X<div>","</div>"]),p.fn.extend({text:function(a){return p.access(this,function(a){return a===b?p.text(this):this.empty().append((this[0]&&this[0].ownerDocument||e).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(p.isFunction(a))return this.each(function(b){p(this).wrapAll(a.call(this,b))});if(this[0]){var b=p(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return p.isFunction(a)?this.each(function(b){p(this).wrapInner(a.call(this,b))}):this.each(function(){var b=p(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=p.isFunction(a);return this.each(function(c){p(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){p.nodeName(this,"body")||p(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(a,this.firstChild)})},before:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(a,this),"before",this.selector)}},after:function(){if(!bh(this[0]))return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=p.clean(arguments);return this.pushStack(p.merge(this,a),"after",this.selector)}},remove:function(a,b){var c,d=0;for(;(c=this[d])!=null;d++)if(!a||p.filter(a,[c]).length)!b&&c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),p.cleanData([c])),c.parentNode&&c.parentNode.removeChild(c);return this},empty:function(){var a,b=0;for(;(a=this[b])!=null;b++){a.nodeType===1&&p.cleanData(a.getElementsByTagName("*"));while(a.firstChild)a.removeChild(a.firstChild)}return this},clone:function(a,b){return a=a==null?!1:a,b=b==null?a:b,this.map(function(){return p.clone(this,a,b)})},html:function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(a))&&!bz[(bp.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(bo,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(p.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(f){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){return bh(this[0])?this.length?this.pushStack(p(p.isFunction(a)?a():a),"replaceWith",a):this:p.isFunction(a)?this.each(function(b){var c=p(this),d=c.html();c.replaceWith(a.call(this,b,d))}):(typeof a!="string"&&(a=p(a).detach()),this.each(function(){var b=this.nextSibling,c=this.parentNode;p(this).remove(),b?p(b).before(a):p(c).append(a)}))},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){a=[].concat.apply([],a);var e,f,g,h,i=0,j=a[0],k=[],l=this.length;if(!p.support.checkClone&&l>1&&typeof j=="string"&&bw.test(j))return this.each(function(){p(this).domManip(a,c,d)});if(p.isFunction(j))return this.each(function(e){var f=p(this);a[0]=j.call(this,e,c?f.html():b),f.domManip(a,c,d)});if(this[0]){e=p.buildFragment(a,this,k),g=e.fragment,f=g.firstChild,g.childNodes.length===1&&(g=f);if(f){c=c&&p.nodeName(f,"tr");for(h=e.cacheable||l-1;i<l;i++)d.call(c&&p.nodeName(this[i],"table")?bC(this[i],"tbody"):this[i],i===h?g:p.clone(g,!0,!0))}g=f=null,k.length&&p.each(k,function(a,b){b.src?p.ajax?p.ajax({url:b.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):p.error("no ajax"):p.globalEval((b.text||b.textContent||b.innerHTML||"").replace(by,"")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),p.buildFragment=function(a,c,d){var f,g,h,i=a[0];return c=c||e,c=!c.nodeType&&c[0]||c,c=c.ownerDocument||c,a.length===1&&typeof i=="string"&&i.length<512&&c===e&&i.charAt(0)==="<"&&!bt.test(i)&&(p.support.checkClone||!bw.test(i))&&(p.support.html5Clone||!bu.test(i))&&(g=!0,f=p.fragments[i],h=f!==b),f||(f=c.createDocumentFragment(),p.clean(a,c,f,d),g&&(p.fragments[i]=h&&f)),{fragment:f,cacheable:g}},p.fragments={},p.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){p.fn[a]=function(c){var d,e=0,f=[],g=p(c),h=g.length,i=this.length===1&&this[0].parentNode;if((i==null||i&&i.nodeType===11&&i.childNodes.length===1)&&h===1)return g[b](this[0]),this;for(;e<h;e++)d=(e>0?this.clone(!0):this).get(),p(g[e])[b](d),f=f.concat(d);return this.pushStack(f,a,g.selector)}}),p.extend({clone:function(a,b,c){var d,e,f,g;p.support.html5Clone||p.isXMLDoc(a)||!bu.test("<"+a.nodeName+">")?g=a.cloneNode(!0):(bB.innerHTML=a.outerHTML,bB.removeChild(g=bB.firstChild));if((!p.support.noCloneEvent||!p.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!p.isXMLDoc(a)){bE(a,g),d=bF(a),e=bF(g);for(f=0;d[f];++f)e[f]&&bE(d[f],e[f])}if(b){bD(a,g);if(c){d=bF(a),e=bF(g);for(f=0;d[f];++f)bD(d[f],e[f])}}return d=e=null,g},clean:function(a,b,c,d){var f,g,h,i,j,k,l,m,n,o,q,r,s=b===e&&bA,t=[];if(!b||typeof b.createDocumentFragment=="undefined")b=e;for(f=0;(h=a[f])!=null;f++){typeof h=="number"&&(h+="");if(!h)continue;if(typeof h=="string")if(!br.test(h))h=b.createTextNode(h);else{s=s||bk(b),l=b.createElement("div"),s.appendChild(l),h=h.replace(bo,"<$1></$2>"),i=(bp.exec(h)||["",""])[1].toLowerCase(),j=bz[i]||bz._default,k=j[0],l.innerHTML=j[1]+h+j[2];while(k--)l=l.lastChild;if(!p.support.tbody){m=bq.test(h),n=i==="table"&&!m?l.firstChild&&l.firstChild.childNodes:j[1]==="<table>"&&!m?l.childNodes:[];for(g=n.length-1;g>=0;--g)p.nodeName(n[g],"tbody")&&!n[g].childNodes.length&&n[g].parentNode.removeChild(n[g])}!p.support.leadingWhitespace&&bn.test(h)&&l.insertBefore(b.createTextNode(bn.exec(h)[0]),l.firstChild),h=l.childNodes,l.parentNode.removeChild(l)}h.nodeType?t.push(h):p.merge(t,h)}l&&(h=l=s=null);if(!p.support.appendChecked)for(f=0;(h=t[f])!=null;f++)p.nodeName(h,"input")?bG(h):typeof h.getElementsByTagName!="undefined"&&p.grep(h.getElementsByTagName("input"),bG);if(c){q=function(a){if(!a.type||bx.test(a.type))return d?d.push(a.parentNode?a.parentNode.removeChild(a):a):c.appendChild(a)};for(f=0;(h=t[f])!=null;f++)if(!p.nodeName(h,"script")||!q(h))c.appendChild(h),typeof h.getElementsByTagName!="undefined"&&(r=p.grep(p.merge([],h.getElementsByTagName("script")),q),t.splice.apply(t,[f+1,0].concat(r)),f+=r.length)}return t},cleanData:function(a,b){var c,d,e,f,g=0,h=p.expando,i=p.cache,j=p.support.deleteExpando,k=p.event.special;for(;(e=a[g])!=null;g++)if(b||p.acceptData(e)){d=e[h],c=d&&i[d];if(c){if(c.events)for(f in c.events)k[f]?p.event.remove(e,f):p.removeEvent(e,f,c.handle);i[d]&&(delete i[d],j?delete e[h]:e.removeAttribute?e.removeAttribute(h):e[h]=null,p.deletedIds.push(d))}}}}),function(){var a,b;p.uaMatch=function(a){a=a.toLowerCase();var b=/(chrome)[ \/]([\w.]+)/.exec(a)||/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||a.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},a=p.uaMatch(g.userAgent),b={},a.browser&&(b[a.browser]=!0,b.version=a.version),b.chrome?b.webkit=!0:b.webkit&&(b.safari=!0),p.browser=b,p.sub=function(){function a(b,c){return new a.fn.init(b,c)}p.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function c(c,d){return d&&d instanceof p&&!(d instanceof a)&&(d=a(d)),p.fn.init.call(this,c,d,b)},a.fn.init.prototype=a.fn;var b=a(e);return a}}();var bH,bI,bJ,bK=/alpha\([^)]*\)/i,bL=/opacity=([^)]*)/,bM=/^(top|right|bottom|left)$/,bN=/^(none|table(?!-c[ea]).+)/,bO=/^margin/,bP=new RegExp("^("+q+")(.*)$","i"),bQ=new RegExp("^("+q+")(?!px)[a-z%]+$","i"),bR=new RegExp("^([-+])=("+q+")","i"),bS={},bT={position:"absolute",visibility:"hidden",display:"block"},bU={letterSpacing:0,fontWeight:400},bV=["Top","Right","Bottom","Left"],bW=["Webkit","O","Moz","ms"],bX=p.fn.toggle;p.fn.extend({css:function(a,c){return p.access(this,function(a,c,d){return d!==b?p.style(a,c,d):p.css(a,c)},a,c,arguments.length>1)},show:function(){return b$(this,!0)},hide:function(){return b$(this)},toggle:function(a,b){var c=typeof a=="boolean";return p.isFunction(a)&&p.isFunction(b)?bX.apply(this,arguments):this.each(function(){(c?a:bZ(this))?p(this).show():p(this).hide()})}}),p.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bH(a,"opacity");return c===""?"1":c}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":p.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!a||a.nodeType===3||a.nodeType===8||!a.style)return;var f,g,h,i=p.camelCase(c),j=a.style;c=p.cssProps[i]||(p.cssProps[i]=bY(j,i)),h=p.cssHooks[c]||p.cssHooks[i];if(d===b)return h&&"get"in h&&(f=h.get(a,!1,e))!==b?f:j[c];g=typeof d,g==="string"&&(f=bR.exec(d))&&(d=(f[1]+1)*f[2]+parseFloat(p.css(a,c)),g="number");if(d==null||g==="number"&&isNaN(d))return;g==="number"&&!p.cssNumber[i]&&(d+="px");if(!h||!("set"in h)||(d=h.set(a,d,e))!==b)try{j[c]=d}catch(k){}},css:function(a,c,d,e){var f,g,h,i=p.camelCase(c);return c=p.cssProps[i]||(p.cssProps[i]=bY(a.style,i)),h=p.cssHooks[c]||p.cssHooks[i],h&&"get"in h&&(f=h.get(a,!0,e)),f===b&&(f=bH(a,c)),f==="normal"&&c in bU&&(f=bU[c]),d||e!==b?(g=parseFloat(f),d||p.isNumeric(g)?g||0:f):f},swap:function(a,b,c){var d,e,f={};for(e in b)f[e]=a.style[e],a.style[e]=b[e];d=c.call(a);for(e in b)a.style[e]=f[e];return d}}),a.getComputedStyle?bH=function(b,c){var d,e,f,g,h=a.getComputedStyle(b,null),i=b.style;return h&&(d=h[c],d===""&&!p.contains(b.ownerDocument,b)&&(d=p.style(b,c)),bQ.test(d)&&bO.test(c)&&(e=i.width,f=i.minWidth,g=i.maxWidth,i.minWidth=i.maxWidth=i.width=d,d=h.width,i.width=e,i.minWidth=f,i.maxWidth=g)),d}:e.documentElement.currentStyle&&(bH=function(a,b){var c,d,e=a.currentStyle&&a.currentStyle[b],f=a.style;return e==null&&f&&f[b]&&(e=f[b]),bQ.test(e)&&!bM.test(b)&&(c=f.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":e,e=f.pixelLeft+"px",f.left=c,d&&(a.runtimeStyle.left=d)),e===""?"auto":e}),p.each(["height","width"],function(a,b){p.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth===0&&bN.test(bH(a,"display"))?p.swap(a,bT,function(){return cb(a,b,d)}):cb(a,b,d)},set:function(a,c,d){return b_(a,c,d?ca(a,b,d,p.support.boxSizing&&p.css(a,"boxSizing")==="border-box"):0)}}}),p.support.opacity||(p.cssHooks.opacity={get:function(a,b){return bL.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=p.isNumeric(b)?"alpha(opacity="+b*100+")":"",f=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&p.trim(f.replace(bK,""))===""&&c.removeAttribute){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bK.test(f)?f.replace(bK,e):f+" "+e}}),p(function(){p.support.reliableMarginRight||(p.cssHooks.marginRight={get:function(a,b){return p.swap(a,{display:"inline-block"},function(){if(b)return bH(a,"marginRight")})}}),!p.support.pixelPosition&&p.fn.position&&p.each(["top","left"],function(a,b){p.cssHooks[b]={get:function(a,c){if(c){var d=bH(a,b);return bQ.test(d)?p(a).position()[b]+"px":d}}}})}),p.expr&&p.expr.filters&&(p.expr.filters.hidden=function(a){return a.offsetWidth===0&&a.offsetHeight===0||!p.support.reliableHiddenOffsets&&(a.style&&a.style.display||bH(a,"display"))==="none"},p.expr.filters.visible=function(a){return!p.expr.filters.hidden(a)}),p.each({margin:"",padding:"",border:"Width"},function(a,b){p.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bV[d]+b]=e[d]||e[d-2]||e[0];return f}},bO.test(a)||(p.cssHooks[a+b].set=b_)});var cd=/%20/g,ce=/\[\]$/,cf=/\r?\n/g,cg=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,ch=/^(?:select|textarea)/i;p.fn.extend({serialize:function(){return p.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?p.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ch.test(this.nodeName)||cg.test(this.type))}).map(function(a,b){var c=p(this).val();return c==null?null:p.isArray(c)?p.map(c,function(a,c){return{name:b.name,value:a.replace(cf,"\r\n")}}):{name:b.name,value:c.replace(cf,"\r\n")}}).get()}}),p.param=function(a,c){var d,e=[],f=function(a,b){b=p.isFunction(b)?b():b==null?"":b,e[e.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=p.ajaxSettings&&p.ajaxSettings.traditional);if(p.isArray(a)||a.jquery&&!p.isPlainObject(a))p.each(a,function(){f(this.name,this.value)});else for(d in a)ci(d,a[d],c,f);return e.join("&").replace(cd,"+")};var cj,ck,cl=/#.*$/,cm=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,cn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,co=/^(?:GET|HEAD)$/,cp=/^\/\//,cq=/\?/,cr=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,cs=/([?&])_=[^&]*/,ct=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,cu=p.fn.load,cv={},cw={},cx=["*/"]+["*"];try{ck=f.href}catch(cy){ck=e.createElement("a"),ck.href="",ck=ck.href}cj=ct.exec(ck.toLowerCase())||[],p.fn.load=function(a,c,d){if(typeof a!="string"&&cu)return cu.apply(this,arguments);if(!this.length)return this;var e,f,g,h=this,i=a.indexOf(" ");return i>=0&&(e=a.slice(i,a.length),a=a.slice(0,i)),p.isFunction(c)?(d=c,c=b):c&&typeof c=="object"&&(f="POST"),p.ajax({url:a,type:f,dataType:"html",data:c,complete:function(a,b){d&&h.each(d,g||[a.responseText,b,a])}}).done(function(a){g=arguments,h.html(e?p("<div>").append(a.replace(cr,"")).find(e):a)}),this},p.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){p.fn[b]=function(a){return this.on(b,a)}}),p.each(["get","post"],function(a,c){p[c]=function(a,d,e,f){return p.isFunction(d)&&(f=f||e,e=d,d=b),p.ajax({type:c,url:a,data:d,success:e,dataType:f})}}),p.extend({getScript:function(a,c){return p.get(a,b,c,"script")},getJSON:function(a,b,c){return p.get(a,b,c,"json")},ajaxSetup:function(a,b){return b?cB(a,p.ajaxSettings):(b=a,a=p.ajaxSettings),cB(a,b),a},ajaxSettings:{url:ck,isLocal:cn.test(cj[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":cx},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":p.parseJSON,"text xml":p.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:cz(cv),ajaxTransport:cz(cw),ajax:function(a,c){function y(a,c,f,i){var k,s,t,u,w,y=c;if(v===2)return;v=2,h&&clearTimeout(h),g=b,e=i||"",x.readyState=a>0?4:0,f&&(u=cC(l,x,f));if(a>=200&&a<300||a===304)l.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(p.lastModified[d]=w),w=x.getResponseHeader("Etag"),w&&(p.etag[d]=w)),a===304?(y="notmodified",k=!0):(k=cD(l,u),y=k.state,s=k.data,t=k.error,k=!t);else{t=y;if(!y||a)y="error",a<0&&(a=0)}x.status=a,x.statusText=(c||y)+"",k?o.resolveWith(m,[s,y,x]):o.rejectWith(m,[x,y,t]),x.statusCode(r),r=b,j&&n.trigger("ajax"+(k?"Success":"Error"),[x,l,k?s:t]),q.fireWith(m,[x,y]),j&&(n.trigger("ajaxComplete",[x,l]),--p.active||p.event.trigger("ajaxStop"))}typeof a=="object"&&(c=a,a=b),c=c||{};var d,e,f,g,h,i,j,k,l=p.ajaxSetup({},c),m=l.context||l,n=m!==l&&(m.nodeType||m instanceof p)?p(m):p.event,o=p.Deferred(),q=p.Callbacks("once memory"),r=l.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,setRequestHeader:function(a,b){if(!v){var c=a.toLowerCase();a=u[c]=u[c]||a,t[a]=b}return this},getAllResponseHeaders:function(){return v===2?e:null},getResponseHeader:function(a){var c;if(v===2){if(!f){f={};while(c=cm.exec(e))f[c[1].toLowerCase()]=c[2]}c=f[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){return v||(l.mimeType=a),this},abort:function(a){return a=a||w,g&&g.abort(a),y(0,a),this}};o.promise(x),x.success=x.done,x.error=x.fail,x.complete=q.add,x.statusCode=function(a){if(a){var b;if(v<2)for(b in a)r[b]=[r[b],a[b]];else b=a[x.status],x.always(b)}return this},l.url=((a||l.url)+"").replace(cl,"").replace(cp,cj[1]+"//"),l.dataTypes=p.trim(l.dataType||"*").toLowerCase().split(s),l.crossDomain==null&&(i=ct.exec(l.url.toLowerCase())||!1,l.crossDomain=i&&i.join(":")+(i[3]?"":i[1]==="http:"?80:443)!==cj.join(":")+(cj[3]?"":cj[1]==="http:"?80:443)),l.data&&l.processData&&typeof l.data!="string"&&(l.data=p.param(l.data,l.traditional)),cA(cv,l,c,x);if(v===2)return x;j=l.global,l.type=l.type.toUpperCase(),l.hasContent=!co.test(l.type),j&&p.active++===0&&p.event.trigger("ajaxStart");if(!l.hasContent){l.data&&(l.url+=(cq.test(l.url)?"&":"?")+l.data,delete l.data),d=l.url;if(l.cache===!1){var z=p.now(),A=l.url.replace(cs,"$1_="+z);l.url=A+(A===l.url?(cq.test(l.url)?"&":"?")+"_="+z:"")}}(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",l.contentType),l.ifModified&&(d=d||l.url,p.lastModified[d]&&x.setRequestHeader("If-Modified-Since",p.lastModified[d]),p.etag[d]&&x.setRequestHeader("If-None-Match",p.etag[d])),x.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(l.dataTypes[0]!=="*"?", "+cx+"; q=0.01":""):l.accepts["*"]);for(k in l.headers)x.setRequestHeader(k,l.headers[k]);if(!l.beforeSend||l.beforeSend.call(m,x,l)!==!1&&v!==2){w="abort";for(k in{success:1,error:1,complete:1})x[k](l[k]);g=cA(cw,l,c,x);if(!g)y(-1,"No Transport");else{x.readyState=1,j&&n.trigger("ajaxSend",[x,l]),l.async&&l.timeout>0&&(h=setTimeout(function(){x.abort("timeout")},l.timeout));try{v=1,g.send(t,y)}catch(B){if(v<2)y(-1,B);else throw B}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var cE=[],cF=/\?/,cG=/(=)\?(?=&|$)|\?\?/,cH=p.now();p.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=cE.pop()||p.expando+"_"+cH++;return this[a]=!0,a}}),p.ajaxPrefilter("json jsonp",function(c,d,e){var f,g,h,i=c.data,j=c.url,k=c.jsonp!==!1,l=k&&cG.test(j),m=k&&!l&&typeof i=="string"&&!(c.contentType||"").indexOf("application/x-www-form-urlencoded")&&cG.test(i);if(c.dataTypes[0]==="jsonp"||l||m)return f=c.jsonpCallback=p.isFunction(c.jsonpCallback)?c.jsonpCallback():c.jsonpCallback,g=a[f],l?c.url=j.replace(cG,"$1"+f):m?c.data=i.replace(cG,"$1"+f):k&&(c.url+=(cF.test(j)?"&":"?")+c.jsonp+"="+f),c.converters["script json"]=function(){return h||p.error(f+" was not called"),h[0]},c.dataTypes[0]="json",a[f]=function(){h=arguments},e.always(function(){a[f]=g,c[f]&&(c.jsonpCallback=d.jsonpCallback,cE.push(f)),h&&p.isFunction(g)&&g(h[0]),h=g=b}),"script"}),p.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){return p.globalEval(a),a}}}),p.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),p.ajaxTransport("script",function(a){if(a.crossDomain){var c,d=e.head||e.getElementsByTagName("head")[0]||e.documentElement;return{send:function(f,g){c=e.createElement("script"),c.async="async",a.scriptCharset&&(c.charset=a.scriptCharset),c.src=a.url,c.onload=c.onreadystatechange=function(a,e){if(e||!c.readyState||/loaded|complete/.test(c.readyState))c.onload=c.onreadystatechange=null,d&&c.parentNode&&d.removeChild(c),c=b,e||g(200,"success")},d.insertBefore(c,d.firstChild)},abort:function(){c&&c.onload(0,1)}}}});var cI,cJ=a.ActiveXObject?function(){for(var a in cI)cI[a](0,1)}:!1,cK=0;p.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&cL()||cM()}:cL,function(a){p.extend(p.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(p.ajaxSettings.xhr()),p.support.ajax&&p.ajaxTransport(function(c){if(!c.crossDomain||p.support.cors){var d;return{send:function(e,f){var g,h,i=c.xhr();c.username?i.open(c.type,c.url,c.async,c.username,c.password):i.open(c.type,c.url,c.async);if(c.xhrFields)for(h in c.xhrFields)i[h]=c.xhrFields[h];c.mimeType&&i.overrideMimeType&&i.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(h in e)i.setRequestHeader(h,e[h])}catch(j){}i.send(c.hasContent&&c.data||null),d=function(a,e){var h,j,k,l,m;try{if(d&&(e||i.readyState===4)){d=b,g&&(i.onreadystatechange=p.noop,cJ&&delete cI[g]);if(e)i.readyState!==4&&i.abort();else{h=i.status,k=i.getAllResponseHeaders(),l={},m=i.responseXML,m&&m.documentElement&&(l.xml=m);try{l.text=i.responseText}catch(a){}try{j=i.statusText}catch(n){j=""}!h&&c.isLocal&&!c.crossDomain?h=l.text?200:404:h===1223&&(h=204)}}}catch(o){e||f(-1,o)}l&&f(h,j,l,k)},c.async?i.readyState===4?setTimeout(d,0):(g=++cK,cJ&&(cI||(cI={},p(a).unload(cJ)),cI[g]=d),i.onreadystatechange=d):d()},abort:function(){d&&d(0,1)}}}});var cN,cO,cP=/^(?:toggle|show|hide)$/,cQ=new RegExp("^(?:([-+])=|)("+q+")([a-z%]*)$","i"),cR=/queueHooks$/,cS=[cY],cT={"*":[function(a,b){var c,d,e=this.createTween(a,b),f=cQ.exec(b),g=e.cur(),h=+g||0,i=1,j=20;if(f){c=+f[2],d=f[3]||(p.cssNumber[a]?"":"px");if(d!=="px"&&h){h=p.css(e.elem,a,!0)||c||1;do i=i||".5",h=h/i,p.style(e.elem,a,h+d);while(i!==(i=e.cur()/g)&&i!==1&&--j)}e.unit=d,e.start=h,e.end=f[1]?h+(f[1]+1)*c:c}return e}]};p.Animation=p.extend(cW,{tweener:function(a,b){p.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");var c,d=0,e=a.length;for(;d<e;d++)c=a[d],cT[c]=cT[c]||[],cT[c].unshift(b)},prefilter:function(a,b){b?cS.unshift(a):cS.push(a)}}),p.Tween=cZ,cZ.prototype={constructor:cZ,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(p.cssNumber[c]?"":"px")},cur:function(){var a=cZ.propHooks[this.prop];return a&&a.get?a.get(this):cZ.propHooks._default.get(this)},run:function(a){var b,c=cZ.propHooks[this.prop];return this.options.duration?this.pos=b=p.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):cZ.propHooks._default.set(this),this}},cZ.prototype.init.prototype=cZ.prototype,cZ.propHooks={_default:{get:function(a){var b;return a.elem[a.prop]==null||!!a.elem.style&&a.elem.style[a.prop]!=null?(b=p.css(a.elem,a.prop,!1,""),!b||b==="auto"?0:b):a.elem[a.prop]},set:function(a){p.fx.step[a.prop]?p.fx.step[a.prop](a):a.elem.style&&(a.elem.style[p.cssProps[a.prop]]!=null||p.cssHooks[a.prop])?p.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},cZ.propHooks.scrollTop=cZ.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},p.each(["toggle","show","hide"],function(a,b){var c=p.fn[b];p.fn[b]=function(d,e,f){return d==null||typeof d=="boolean"||!a&&p.isFunction(d)&&p.isFunction(e)?c.apply(this,arguments):this.animate(c$(b,!0),d,e,f)}}),p.fn.extend({fadeTo:function(a,b,c,d){return this.filter(bZ).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=p.isEmptyObject(a),f=p.speed(b,c,d),g=function(){var b=cW(this,p.extend({},a),f);e&&b.stop(!0)};return e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,c,d){var e=function(a){var b=a.stop;delete a.stop,b(d)};return typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,c=a!=null&&a+"queueHooks",f=p.timers,g=p._data(this);if(c)g[c]&&g[c].stop&&e(g[c]);else for(c in g)g[c]&&g[c].stop&&cR.test(c)&&e(g[c]);for(c=f.length;c--;)f[c].elem===this&&(a==null||f[c].queue===a)&&(f[c].anim.stop(d),b=!1,f.splice(c,1));(b||!d)&&p.dequeue(this,a)})}}),p.each({slideDown:c$("show"),slideUp:c$("hide"),slideToggle:c$("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){p.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),p.speed=function(a,b,c){var d=a&&typeof a=="object"?p.extend({},a):{complete:c||!c&&b||p.isFunction(a)&&a,duration:a,easing:c&&b||b&&!p.isFunction(b)&&b};d.duration=p.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in p.fx.speeds?p.fx.speeds[d.duration]:p.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";return d.old=d.complete,d.complete=function(){p.isFunction(d.old)&&d.old.call(this),d.queue&&p.dequeue(this,d.queue)},d},p.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},p.timers=[],p.fx=cZ.prototype.init,p.fx.tick=function(){var a,b=p.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||p.fx.stop()},p.fx.timer=function(a){a()&&p.timers.push(a)&&!cO&&(cO=setInterval(p.fx.tick,p.fx.interval))},p.fx.interval=13,p.fx.stop=function(){clearInterval(cO),cO=null},p.fx.speeds={slow:600,fast:200,_default:400},p.fx.step={},p.expr&&p.expr.filters&&(p.expr.filters.animated=function(a){return p.grep(p.timers,function(b){return a===b.elem}).length});var c_=/^(?:body|html)$/i;p.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){p.offset.setOffset(this,a,b)});var c,d,e,f,g,h,i,j={top:0,left:0},k=this[0],l=k&&k.ownerDocument;if(!l)return;return(d=l.body)===k?p.offset.bodyOffset(k):(c=l.documentElement,p.contains(c,k)?(typeof k.getBoundingClientRect!="undefined"&&(j=k.getBoundingClientRect()),e=da(l),f=c.clientTop||d.clientTop||0,g=c.clientLeft||d.clientLeft||0,h=e.pageYOffset||c.scrollTop,i=e.pageXOffset||c.scrollLeft,{top:j.top+h-f,left:j.left+i-g}):j)},p.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;return p.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(p.css(a,"marginTop"))||0,c+=parseFloat(p.css(a,"marginLeft"))||0),{top:b,left:c}},setOffset:function(a,b,c){var d=p.css(a,"position");d==="static"&&(a.style.position="relative");var e=p(a),f=e.offset(),g=p.css(a,"top"),h=p.css(a,"left"),i=(d==="absolute"||d==="fixed")&&p.inArray("auto",[g,h])>-1,j={},k={},l,m;i?(k=e.position(),l=k.top,m=k.left):(l=parseFloat(g)||0,m=parseFloat(h)||0),p.isFunction(b)&&(b=b.call(a,c,f)),b.top!=null&&(j.top=b.top-f.top+l),b.left!=null&&(j.left=b.left-f.left+m),"using"in b?b.using.call(a,j):e.css(j)}},p.fn.extend({position:function(){if(!this[0])return;var a=this[0],b=this.offsetParent(),c=this.offset(),d=c_.test(b[0].nodeName)?{top:0,left:0}:b.offset();return c.top-=parseFloat(p.css(a,"marginTop"))||0,c.left-=parseFloat(p.css(a,"marginLeft"))||0,d.top+=parseFloat(p.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(p.css(b[0],"borderLeftWidth"))||0,{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||e.body;while(a&&!c_.test(a.nodeName)&&p.css(a,"position")==="static")a=a.offsetParent;return a||e.body})}}),p.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);p.fn[a]=function(e){return p.access(this,function(a,e,f){var g=da(a);if(f===b)return g?c in g?g[c]:g.document.documentElement[e]:a[e];g?g.scrollTo(d?p(g).scrollLeft():f,d?f:p(g).scrollTop()):a[e]=f},a,e,arguments.length,null)}}),p.each({Height:"height",Width:"width"},function(a,c){p.each({padding:"inner"+a,content:c,"":"outer"+a},function(d,e){p.fn[e]=function(e,f){var g=arguments.length&&(d||typeof e!="boolean"),h=d||(e===!0||f===!0?"margin":"border");return p.access(this,function(c,d,e){var f;return p.isWindow(c)?c.document.documentElement["client"+a]:c.nodeType===9?(f=c.documentElement,Math.max(c.body["scroll"+a],f["scroll"+a],c.body["offset"+a],f["offset"+a],f["client"+a])):e===b?p.css(c,d,e,h):p.style(c,d,e,h)},c,g?e:b,g,null)}})}),a.jQuery=a.$=p,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return p})})(window);

(function($){var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.toJSON=typeof JSON==='object'&&JSON.stringify?JSON.stringify:function(o){if(o===null){return'null';}
var type=typeof o;if(type==='undefined'){return undefined;}
if(type==='number'||type==='boolean'){return''+o;}
if(type==='string'){return $.quoteString(o);}
if(type==='object'){if(typeof o.toJSON==='function'){return $.toJSON(o.toJSON());}
if(o.constructor===Date){var month=o.getUTCMonth()+1,day=o.getUTCDate(),year=o.getUTCFullYear(),hours=o.getUTCHours(),minutes=o.getUTCMinutes(),seconds=o.getUTCSeconds(),milli=o.getUTCMilliseconds();if(month<10){month='0'+month;}
if(day<10){day='0'+day;}
if(hours<10){hours='0'+hours;}
if(minutes<10){minutes='0'+minutes;}
if(seconds<10){seconds='0'+seconds;}
if(milli<100){milli='0'+milli;}
if(milli<10){milli='0'+milli;}
return'"'+year+'-'+month+'-'+day+'T'+
hours+':'+minutes+':'+seconds+'.'+milli+'Z"';}
if(o.constructor===Array){var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i])||'null');}
return'['+ret.join(',')+']';}
var name,val,pairs=[];for(var k in o){type=typeof k;if(type==='number'){name='"'+k+'"';}else if(type==='string'){name=$.quoteString(k);}else{continue;}
type=typeof o[k];if(type==='function'||type==='undefined'){continue;}
val=$.toJSON(o[k]);pairs.push(name+':'+val);}
return'{'+pairs.join(',')+'}';}};$.evalJSON=typeof JSON==='object'&&JSON.parse?JSON.parse:function(src){return eval('('+src+')');};$.secureEvalJSON=typeof JSON==='object'&&JSON.parse?JSON.parse:function(src){var filtered=src.replace(/\\["\\\/bfnrtu]/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered)){return eval('('+src+')');}else{throw new SyntaxError('Error parsing JSON, source is not valid.');}};$.quoteString=function(string){if(string.match(escapeable)){return'"'+string.replace(escapeable,function(a){var c=meta[a];if(typeof c==='string'){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
return'"'+string+'"';};})(jQuery);
(function(e){e.expander={version:"1.4.5",defaults:{slicePoint:100,preserveWords:!0,widow:4,expandText:"Show more",expandPrefix:"&hellip; ",expandAfterSummary:!1,summaryClass:"summary",detailClass:"details",moreClass:"read-more",lessClass:"read-less",collapseTimer:0,expandEffect:"slideDown",expandSpeed:250,collapseEffect:"slideUp",collapseSpeed:200,userCollapse:!0,userCollapseText:"Show less",userCollapsePrefix:" ",onSlice:null,beforeExpand:null,afterExpand:null,onCollapse:null,afterCollapse:null}},e.fn.expander=function(a){function l(e,a){var l="span",s=e.summary;return a?(l="div",x.test(s)&&!e.expandAfterSummary?s=s.replace(x,e.moreLabel+"$1"):s+=e.moreLabel,s='<div class="'+e.summaryClass+'">'+s+"</div>"):s+=e.moreLabel,[s,"<",l+' class="'+e.detailClass+'"',">",e.details,"</"+l+">"].join("")}function s(e){var a='<span class="'+e.moreClass+'">'+e.expandPrefix;return a+='<a href="#">'+e.expandText+"</a></span>"}function n(a,l){return a.lastIndexOf("<")>a.lastIndexOf(">")&&(a=a.slice(0,a.lastIndexOf("<"))),l&&(a=a.replace(c,"")),e.trim(a)}function t(e,a){a.stop(!0,!0)[e.collapseEffect](e.collapseSpeed,function(){var l=a.prev("span."+e.moreClass).show();l.length||a.parent().children("div."+e.summaryClass).show().find("span."+e.moreClass).show(),e.afterCollapse&&e.afterCollapse.call(a)})}function r(a,l,s){a.collapseTimer&&(o=setTimeout(function(){t(a,l),e.isFunction(a.onCollapse)&&a.onCollapse.call(s,!1)},a.collapseTimer))}var i="init";"string"==typeof a&&(i=a,a={});var o,d=e.extend({},e.expander.defaults,a),p=/^<(?:area|br|col|embed|hr|img|input|link|meta|param).*>$/i,c=d.wordEnd||/(&(?:[^;]+;)?|[a-zA-Z\u00C0-\u0100]+)$/,f=/<\/?(\w+)[^>]*>/g,u=/<(\w+)[^>]*>/g,m=/<\/(\w+)>/g,x=/(<\/[^>]+>)\s*$/,h=/^(<[^>]+>)+.?/,C={init:function(){this.each(function(){var a,i,c,x,C,v,S,g,b,y,E,w,T,I,P=[],j=[],k={},D=this,$=e(this),A=e([]),L=e.extend({},d,$.data("expander")||e.meta&&$.data()||{}),O=!!$.find("."+L.detailClass).length,z=!!$.find("*").filter(function(){var a=e(this).css("display");return/^block|table|list/.test(a)}).length,F=z?"div":"span",U=F+"."+L.detailClass,W=L.moreClass+"",Q=L.lessClass+"",Z=L.expandSpeed||0,q=e.trim($.html()),B=(e.trim($.text()),q.slice(0,L.slicePoint));if(L.moreSelector="span."+W.split(" ").join("."),L.lessSelector="span."+Q.split(" ").join("."),!e.data(this,"expanderInit")){for(e.data(this,"expanderInit",!0),e.data(this,"expander",L),e.each(["onSlice","beforeExpand","afterExpand","onCollapse","afterCollapse"],function(a,l){k[l]=e.isFunction(L[l])}),B=n(B),C=B.replace(f,"").length;L.slicePoint>C;)x=q.charAt(B.length),"<"===x&&(x=q.slice(B.length).match(h)[0]),B+=x,C++;for(B=n(B,L.preserveWords),v=B.match(u)||[],S=B.match(m)||[],c=[],e.each(v,function(e,a){p.test(a)||c.push(a)}),v=c,i=S.length,a=0;i>a;a++)S[a]=S[a].replace(m,"$1");if(e.each(v,function(a,l){var s=l.replace(u,"$1"),n=e.inArray(s,S);-1===n?(P.push(l),j.push("</"+s+">")):S.splice(n,1)}),j.reverse(),O)b=$.find(U).remove().html(),B=$.html(),q=B+b,g="";else{if(b=q.slice(B.length),y=e.trim(b.replace(f,"")),""===y||y.split(/\s+/).length<L.widow)return;g=j.pop()||"",B+=j.join(""),b=P.join("")+b}L.moreLabel=$.find(L.moreSelector).length?"":s(L),z&&(b=q),B+=g,L.summary=B,L.details=b,L.lastCloseTag=g,k.onSlice&&(c=L.onSlice.call(D,L),L=c&&c.details?c:L),E=l(L,z),$.html(E),T=$.find(U),I=$.find(L.moreSelector),"slideUp"===L.collapseEffect&&"slideDown"!==L.expandEffect||$.is(":hidden")?T.css({display:"none"}):T[L.collapseEffect](0),A=$.find("div."+L.summaryClass),w=function(e){e.preventDefault(),I.hide(),A.hide(),k.beforeExpand&&L.beforeExpand.call(D),T.stop(!1,!0)[L.expandEffect](Z,function(){T.css({zoom:""}),k.afterExpand&&L.afterExpand.call(D),r(L,T,D)})},I.find("a").unbind("click.expander").bind("click.expander",w),L.userCollapse&&!$.find(L.lessSelector).length&&$.find(U).append('<span class="'+L.lessClass+'">'+L.userCollapsePrefix+'<a href="#">'+L.userCollapseText+"</a></span>"),$.find(L.lessSelector+" a").unbind("click.expander").bind("click.expander",function(a){a.preventDefault(),clearTimeout(o);var l=e(this).closest(U);t(L,l),k.onCollapse&&L.onCollapse.call(D,!0)})}})},destroy:function(){this.each(function(){var a,l,s=e(this);s.data("expanderInit")&&(a=e.extend({},s.data("expander")||{},d),l=s.find("."+a.detailClass).contents(),s.removeData("expanderInit"),s.removeData("expander"),s.find(a.moreSelector).remove(),s.find("."+a.summaryClass).remove(),s.find("."+a.detailClass).after(l).remove(),s.find(a.lessSelector).remove())})}};return C[i]&&C[i].call(this),this},e.fn.expander.defaults=e.expander.defaults})(jQuery);


$.fn.fitText = function () {
  var el, elements, _i, _len, _results;
  elements = $(this);
  if (elements.length < 0) {
    return;
  }
  _results = [];
  for (_i = 0, _len = elements.length; _i < _len; _i++) {
    el = elements[_i];
    _results.push((function(el) {
      var resizeText, _results1;
      resizeText = function() {
        var elNewFontSize;
        elNewFontSize = (parseInt($(el).css('font-size').slice(0, -2)) - 1) + 'px';
        return $(el).css('font-size', elNewFontSize);
      };
      _results1 = [];
      while (el.scrollWidth > el.offsetWidth) {
        _results1.push(resizeText());
      }
      return _results1;
    })(el));
  }
  return $(this);
};

(function($) {

$.extend($.fn, {
	// http://docs.jquery.com/Plugins/Validation/validate
	validate: function( options ) {

		// if nothing is selected, return nothing; can't chain anyway
		if ( !this.length ) {
			if ( options && options.debug && window.console ) {
				console.warn( "Nothing selected, can't validate, returning nothing." );
			}
			return;
		}

		// check if a validator for this form was already created
		var validator = $.data( this[0], "validator" );
		if ( validator ) {
			return validator;
		}

		// Add novalidate tag if HTML5.
		this.attr( "novalidate", "novalidate" );

		validator = new $.validator( options, this[0] );
		$.data( this[0], "validator", validator );

		if ( validator.settings.onsubmit ) {

			this.validateDelegate( ":submit", "click", function( event ) {
				if ( validator.settings.submitHandler ) {
					validator.submitButton = event.target;
				}
				// allow suppressing validation by adding a cancel class to the submit button
				if ( $(event.target).hasClass("cancel") ) {
					validator.cancelSubmit = true;
				}
			});

			// validate the form on submit
			this.submit( function( event ) {
				if ( validator.settings.debug ) {
					// prevent form submit to be able to see console output
					event.preventDefault();
				}
				function handle() {
					var hidden;
					if ( validator.settings.submitHandler ) {
						if ( validator.submitButton ) {
							// insert a hidden input as a replacement for the missing submit button
							hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
						}
						validator.settings.submitHandler.call( validator, validator.currentForm, event );
						if ( validator.submitButton ) {
							// and clean up afterwards; thanks to no-block-scope, hidden can be referenced
							hidden.remove();
						}
						return false;
					}
					return true;
				}

				// prevent submit for invalid forms or custom submit handlers
				if ( validator.cancelSubmit ) {
					validator.cancelSubmit = false;
					return handle();
				}
				if ( validator.form() ) {
					if ( validator.pendingRequest ) {
						validator.formSubmitted = true;
						return false;
					}
					return handle();
				} else {
					validator.focusInvalid();
					return false;
				}
			});
		}

		return validator;
	},
	// http://docs.jquery.com/Plugins/Validation/valid
	valid: function() {
		if ( $(this[0]).is("form")) {
			return this.validate().form();
		} else {
			var valid = true;
			var validator = $(this[0].form).validate();
			this.each(function() {
				valid &= validator.element(this);
			});
			return valid;
		}
	},
	// attributes: space seperated list of attributes to retrieve and remove
	removeAttrs: function( attributes ) {
		var result = {},
			$element = this;
		$.each(attributes.split(/\s/), function( index, value ) {
			result[value] = $element.attr(value);
			$element.removeAttr(value);
		});
		return result;
	},
	// http://docs.jquery.com/Plugins/Validation/rules
	rules: function( command, argument ) {
		var element = this[0];

		if ( command ) {
			var settings = $.data(element.form, "validator").settings;
			var staticRules = settings.rules;
			var existingRules = $.validator.staticRules(element);
			switch(command) {
			case "add":
				$.extend(existingRules, $.validator.normalizeRule(argument));
				staticRules[element.name] = existingRules;
				if ( argument.messages ) {
					settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
				}
				break;
			case "remove":
				if ( !argument ) {
					delete staticRules[element.name];
					return existingRules;
				}
				var filtered = {};
				$.each(argument.split(/\s/), function( index, method ) {
					filtered[method] = existingRules[method];
					delete existingRules[method];
				});
				return filtered;
			}
		}

		var data = $.validator.normalizeRules(
		$.extend(
			{},
			$.validator.classRules(element),
			$.validator.attributeRules(element),
			$.validator.dataRules(element),
			$.validator.staticRules(element)
		), element);

		// make sure required is at front
		if ( data.required ) {
			var param = data.required;
			delete data.required;
			data = $.extend({required: param}, data);
		}

		return data;
	}
});

// Custom selectors
$.extend($.expr[":"], {
	// http://docs.jquery.com/Plugins/Validation/blank
	blank: function( a ) { return !$.trim("" + a.value); },
	// http://docs.jquery.com/Plugins/Validation/filled
	filled: function( a ) { return !!$.trim("" + a.value); },
	// http://docs.jquery.com/Plugins/Validation/unchecked
	unchecked: function( a ) { return !a.checked; }
});

// constructor for validator
$.validator = function( options, form ) {
	this.settings = $.extend( true, {}, $.validator.defaults, options );
	this.currentForm = form;
	this.init();
};

$.validator.format = function( source, params ) {
	if ( arguments.length === 1 ) {
		return function() {
			var args = $.makeArray(arguments);
			args.unshift(source);
			return $.validator.format.apply( this, args );
		};
	}
	if ( arguments.length > 2 && params.constructor !== Array  ) {
		params = $.makeArray(arguments).slice(1);
	}
	if ( params.constructor !== Array ) {
		params = [ params ];
	}
	$.each(params, function( i, n ) {
		source = source.replace( new RegExp("\\{" + i + "\\}", "g"), function() {
			return n;
		});
	});
	return source;
};

$.extend($.validator, {

	defaults: {
		messages: {},
		groups: {},
		rules: {},
		errorClass: "error",
		validClass: "valid",
		errorElement: "label",
		focusInvalid: true,
		errorContainer: $([]),
		errorLabelContainer: $([]),
		onsubmit: true,
		ignore: ":hidden",
		ignoreTitle: false,
		onfocusin: function( element, event ) {
			this.lastActive = element;

			// hide error label and remove error class on focus if enabled
			if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
				if ( this.settings.unhighlight ) {
					this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
				}
				this.addWrapper(this.errorsFor(element)).hide();
			}
		},
		onfocusout: function( element, event ) {
			if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
				this.element(element);
			}
		},
		onkeyup: function( element, event ) {
			if ( event.which === 9 && this.elementValue(element) === "" ) {
				return;
			} else if ( element.name in this.submitted || element === this.lastElement ) {
				this.element(element);
			}
		},
		onclick: function( element, event ) {
			// click on selects, radiobuttons and checkboxes
			if ( element.name in this.submitted ) {
				this.element(element);
			}
			// or option elements, check parent select in that case
			else if ( element.parentNode.name in this.submitted ) {
				this.element(element.parentNode);
			}
		},
		highlight: function( element, errorClass, validClass ) {
			if ( element.type === "radio" ) {
				this.findByName(element.name).addClass(errorClass).removeClass(validClass);
			} else {
				$(element).addClass(errorClass).removeClass(validClass);
			}
		},
		unhighlight: function( element, errorClass, validClass ) {
			if ( element.type === "radio" ) {
				this.findByName(element.name).removeClass(errorClass).addClass(validClass);
			} else {
				$(element).removeClass(errorClass).addClass(validClass);
			}
		}
	},

	// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
	setDefaults: function( settings ) {
		$.extend( $.validator.defaults, settings );
	},

	messages: {
		required: "This field is required.",
		remote: "Please fix this field.",
		email: "Please enter a valid email address.",
		url: "Please enter a valid URL.",
		date: "Please enter a valid date.",
		dateISO: "Please enter a valid date (ISO).",
		number: "Please enter a valid number.",
		digits: "Enter digits only.",
		creditcard: "Please enter a valid credit card number.",
		equalTo: "Please enter the same value again.",
		maxlength: $.validator.format("Please enter no more than {0} characters."),
		minlength: $.validator.format("Please enter at least {0} characters."),
		rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
		range: $.validator.format("Please enter a value between {0} and {1}."),
		max: $.validator.format("Please enter a value less than or equal to {0}."),
		min: $.validator.format("Please enter a value greater than or equal to {0}.")
	},

	autoCreateRanges: false,

	prototype: {

		init: function() {
			this.labelContainer = $(this.settings.errorLabelContainer);
			this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
			this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
			this.submitted = {};
			this.valueCache = {};
			this.pendingRequest = 0;
			this.pending = {};
			this.invalid = {};
			this.reset();

			var groups = (this.groups = {});
			$.each(this.settings.groups, function( key, value ) {
				if ( typeof value === "string" ) {
					value = value.split(/\s/);
				}
				$.each(value, function( index, name ) {
					groups[name] = key;
				});
			});
			var rules = this.settings.rules;
			$.each(rules, function( key, value ) {
				rules[key] = $.validator.normalizeRule(value);
			});

			function delegate(event) {
				var validator = $.data(this[0].form, "validator"),
					eventType = "on" + event.type.replace(/^validate/, "");
				if ( validator.settings[eventType] ) {
					validator.settings[eventType].call(validator, this[0], event);
				}
			}
			$(this.currentForm)
				.validateDelegate(":text, [type='password'], [type='file'], select, textarea, " +
					"[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
					"[type='email'], [type='datetime'], [type='date'], [type='month'], " +
					"[type='week'], [type='time'], [type='datetime-local'], " +
					"[type='range'], [type='color'] ",
					"focusin focusout keyup", delegate)
				.validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate);

			if ( this.settings.invalidHandler ) {
				$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
			}
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/form
		form: function() {
			this.checkForm();
			$.extend(this.submitted, this.errorMap);
			this.invalid = $.extend({}, this.errorMap);
			if ( !this.valid() ) {
				$(this.currentForm).triggerHandler("invalid-form", [this]);
			}
			this.showErrors();
			return this.valid();
		},

		checkForm: function() {
			this.prepareForm();
			for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
				this.check( elements[i] );
			}
			return this.valid();
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/element
		element: function( element ) {
			element = this.validationTargetFor( this.clean( element ) );
			this.lastElement = element;
			this.prepareElement( element );
			this.currentElements = $(element);
			var result = this.check( element ) !== false;
			if ( result ) {
				delete this.invalid[element.name];
			} else {
				this.invalid[element.name] = true;
			}
			if ( !this.numberOfInvalids() ) {
				// Hide error containers on last error
				this.toHide = this.toHide.add( this.containers );
			}
			this.showErrors();
			return result;
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/showErrors
		showErrors: function( errors ) {
			if ( errors ) {
				// add items to error list and map
				$.extend( this.errorMap, errors );
				this.errorList = [];
				for ( var name in errors ) {
					this.errorList.push({
						message: errors[name],
						element: this.findByName(name)[0]
					});
				}
				// remove items from success list
				this.successList = $.grep( this.successList, function( element ) {
					return !(element.name in errors);
				});
			}
			if ( this.settings.showErrors ) {
				this.settings.showErrors.call( this, this.errorMap, this.errorList );
			} else {
				this.defaultShowErrors();
			}
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/resetForm
		resetForm: function() {
			if ( $.fn.resetForm ) {
				$(this.currentForm).resetForm();
			}
			this.submitted = {};
			this.lastElement = null;
			this.prepareForm();
			this.hideErrors();
			this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" );
		},

		numberOfInvalids: function() {
			return this.objectLength(this.invalid);
		},

		objectLength: function( obj ) {
			var count = 0;
			for ( var i in obj ) {
				count++;
			}
			return count;
		},

		hideErrors: function() {
			this.addWrapper( this.toHide ).hide();
		},

		valid: function() {
			return this.size() === 0;
		},

		size: function() {
			return this.errorList.length;
		},

		focusInvalid: function() {
			if ( this.settings.focusInvalid ) {
				try {
					$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
					.filter(":visible")
					.focus()
					// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
					.trigger("focusin");
				} catch(e) {
					// ignore IE throwing errors when focusing hidden elements
				}
			}
		},

		findLastActive: function() {
			var lastActive = this.lastActive;
			return lastActive && $.grep(this.errorList, function( n ) {
				return n.element.name === lastActive.name;
			}).length === 1 && lastActive;
		},

		elements: function() {
			var validator = this,
				rulesCache = {};

			// select all valid inputs inside the form (no submit or reset buttons)
			return $(this.currentForm)
			.find("input, select, textarea")
			.not(":submit, :reset, :image, [disabled]")
			.not( this.settings.ignore )
			.filter(function() {
				if ( !this.name && validator.settings.debug && window.console ) {
					console.error( "%o has no name assigned", this);
				}

				// select only the first element for each name, and only those with rules specified
				if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) {
					return false;
				}

				rulesCache[this.name] = true;
				return true;
			});
		},

		clean: function( selector ) {
			return $(selector)[0];
		},

		errors: function() {
			var errorClass = this.settings.errorClass.replace(" ", ".");
			return $(this.settings.errorElement + "." + errorClass, this.errorContext);
		},

		reset: function() {
			this.successList = [];
			this.errorList = [];
			this.errorMap = {};
			this.toShow = $([]);
			this.toHide = $([]);
			this.currentElements = $([]);
		},

		prepareForm: function() {
			this.reset();
			this.toHide = this.errors().add( this.containers );
		},

		prepareElement: function( element ) {
			this.reset();
			this.toHide = this.errorsFor(element);
		},

		elementValue: function( element ) {
			var type = $(element).attr("type"),
				val = $(element).val();

			if ( type === "radio" || type === "checkbox" ) {
				return $("input[name='" + $(element).attr("name") + "']:checked").val();
			}

			if ( typeof val === "string" ) {
				return val.replace(/\r/g, "");
			}
			return val;
		},

		check: function( element ) {
			element = this.validationTargetFor( this.clean( element ) );

			var rules = $(element).rules();
			var dependencyMismatch = false;
			var val = this.elementValue(element);
			var result;

			for (var method in rules ) {
				var rule = { method: method, parameters: rules[method] };
				try {

					result = $.validator.methods[method].call( this, val, element, rule.parameters );

					// if a method indicates that the field is optional and therefore valid,
					// don't mark it as valid when there are no other rules
					if ( result === "dependency-mismatch" ) {
						dependencyMismatch = true;
						continue;
					}
					dependencyMismatch = false;

					if ( result === "pending" ) {
						this.toHide = this.toHide.not( this.errorsFor(element) );
						return;
					}

					if ( !result ) {
						this.formatAndAdd( element, rule );
						return false;
					}
				} catch(e) {
					if ( this.settings.debug && window.console ) {
						console.log( "Exception occured when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
					}
					throw e;
				}
			}
			if ( dependencyMismatch ) {
				return;
			}
			if ( this.objectLength(rules) ) {
				this.successList.push(element);
			}
			return true;
		},

		// return the custom message for the given element and validation method
		// specified in the element's HTML5 data attribute
		customDataMessage: function( element, method ) {
			return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase()));
		},

		// return the custom message for the given element name and validation method
		customMessage: function( name, method ) {
			var m = this.settings.messages[name];
			return m && (m.constructor === String ? m : m[method]);
		},

		// return the first defined argument, allowing empty strings
		findDefined: function() {
			for(var i = 0; i < arguments.length; i++) {
				if ( arguments[i] !== undefined ) {
					return arguments[i];
				}
			}
			return undefined;
		},

		defaultMessage: function( element, method ) {
			return this.findDefined(
				this.customMessage( element.name, method ),
				this.customDataMessage( element, method ),
				// title is never undefined, so handle empty string as undefined
				!this.settings.ignoreTitle && element.title || undefined,
				$.validator.messages[method],
				"<strong>Warning: No message defined for " + element.name + "</strong>"
			);
		},

		formatAndAdd: function( element, rule ) {
			var message = this.defaultMessage( element, rule.method ),
				theregex = /\$?\{(\d+)\}/g;
			if ( typeof message === "function" ) {
				message = message.call(this, rule.parameters, element);
			} else if (theregex.test(message)) {
				message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters);
			}
			this.errorList.push({
				message: message,
				element: element
			});

			this.errorMap[element.name] = message;
			this.submitted[element.name] = message;
		},

		addWrapper: function( toToggle ) {
			if ( this.settings.wrapper ) {
				toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
			}
			return toToggle;
		},

		defaultShowErrors: function() {
			var i, elements;
			for ( i = 0; this.errorList[i]; i++ ) {
				var error = this.errorList[i];
				if ( this.settings.highlight ) {
					this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
				}

				if (error.message != "") {
					this.showLabel( error.element, error.message );
				}
			}
			if ( this.errorList.length ) {
				this.toShow = this.toShow.add( this.containers );
			}
			if ( this.settings.success ) {
				for ( i = 0; this.successList[i]; i++ ) {
					this.showLabel( this.successList[i] );
				}
			}
			if ( this.settings.unhighlight ) {
				for ( i = 0, elements = this.validElements(); elements[i]; i++ ) {
					this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
				}
			}
			this.toHide = this.toHide.not( this.toShow );
			this.hideErrors();
			this.addWrapper( this.toShow ).show();
		},

		validElements: function() {
			return this.currentElements.not(this.invalidElements());
		},

		invalidElements: function() {
			return $(this.errorList).map(function() {
				return this.element;
			});
		},

		showLabel: function( element, message ) {
			var label = this.errorsFor( element );
			if ( label.length ) {
				// refresh error/success class
				label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
				// replace message on existing label
				label.html(message);
			} else {
				// create label
				label = $("<" + this.settings.errorElement + ">")
					.attr("for", this.idOrName(element))
					.addClass(this.settings.errorClass)
					.html(message || "");
				if ( this.settings.wrapper ) {
					// make sure the element is visible, even in IE
					// actually showing the wrapped element is handled elsewhere
					label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
				}
				if ( !this.labelContainer.append(label).length ) {
					if ( this.settings.errorPlacement ) {
						this.settings.errorPlacement(label, $(element) );
					} else {
						label.insertAfter(element);
					}
				}
			}
			if ( !message && this.settings.success ) {
				label.text("");
				if ( typeof this.settings.success === "string" ) {
					label.addClass( this.settings.success );
				} else {
					this.settings.success( label, element );
				}
			}
			this.toShow = this.toShow.add(label);
		},

		errorsFor: function( element ) {
			var name = this.idOrName(element);
			return this.errors().filter(function() {
				return $(this).attr("for") === name;
			});
		},

		idOrName: function( element ) {
			return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
		},

		validationTargetFor: function( element ) {
			// if radio/checkbox, validate first element in group instead
			if ( this.checkable(element) ) {
				element = this.findByName( element.name ).not(this.settings.ignore)[0];
			}
			return element;
		},

		checkable: function( element ) {
			return (/radio|checkbox/i).test(element.type);
		},

		findByName: function( name ) {
			return $(this.currentForm).find("[name='" + name + "']");
		},

		getLength: function( value, element ) {
			switch( element.nodeName.toLowerCase() ) {
			case "select":
				return $("option:selected", element).length;
			case "input":
				if ( this.checkable( element) ) {
					return this.findByName(element.name).filter(":checked").length;
				}
			}
			return value.length;
		},

		depend: function( param, element ) {
			return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true;
		},

		dependTypes: {
			"boolean": function( param, element ) {
				return param;
			},
			"string": function( param, element ) {
				return !!$(param, element.form).length;
			},
			"function": function( param, element ) {
				return param(element);
			}
		},

		optional: function( element ) {
			var val = this.elementValue(element);
			return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch";
		},

		startRequest: function( element ) {
			if ( !this.pending[element.name] ) {
				this.pendingRequest++;
				this.pending[element.name] = true;
			}
		},

		stopRequest: function( element, valid ) {
			this.pendingRequest--;
			// sometimes synchronization fails, make sure pendingRequest is never < 0
			if ( this.pendingRequest < 0 ) {
				this.pendingRequest = 0;
			}
			delete this.pending[element.name];
			if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
				$(this.currentForm).submit();
				this.formSubmitted = false;
			} else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
				$(this.currentForm).triggerHandler("invalid-form", [this]);
				this.formSubmitted = false;
			}
		},

		previousValue: function( element ) {
			return $.data(element, "previousValue") || $.data(element, "previousValue", {
				old: null,
				valid: true,
				message: this.defaultMessage( element, "remote" )
			});
		}

	},

	classRuleSettings: {
		required: {required: true},
		email: {email: true},
		url: {url: true},
		date: {date: true},
		dateISO: {dateISO: true},
		number: {number: true},
		digits: {digits: true},
		creditcard: {creditcard: true}
	},

	addClassRules: function( className, rules ) {
		if ( className.constructor === String ) {
			this.classRuleSettings[className] = rules;
		} else {
			$.extend(this.classRuleSettings, className);
		}
	},

	classRules: function( element ) {
		var rules = {};
		var classes = $(element).attr("class");
		if ( classes ) {
			$.each(classes.split(" "), function() {
				if ( this in $.validator.classRuleSettings ) {
					$.extend(rules, $.validator.classRuleSettings[this]);
				}
			});
		}
		return rules;
	},

	attributeRules: function( element ) {
		var rules = {};
		var $element = $(element);

		for (var method in $.validator.methods) {
			var value;

			// support for <input required> in both html5 and older browsers
			if ( method === "required" ) {
				value = $element.get(0).getAttribute(method);
				// Some browsers return an empty string for the required attribute
				// and non-HTML5 browsers might have required="" markup
				if ( value === "" ) {
					value = true;
				}
				// force non-HTML5 browsers to return bool
				value = !!value;
			} else {
				value = $element.attr(method);
			}

			if ( value ) {
				rules[method] = value;
			} else if ( $element[0].getAttribute("type") === method ) {
				rules[method] = true;
			}
		}

		// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
		if ( rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength) ) {
			delete rules.maxlength;
		}

		return rules;
	},

	dataRules: function( element ) {
		var method, value,
			rules = {}, $element = $(element);
		for (method in $.validator.methods) {
			value = $element.data("rule-" + method.toLowerCase());
			if ( value !== undefined ) {
				rules[method] = value;
			}
		}
		return rules;
	},

	staticRules: function( element ) {
		var rules = {};
		var validator = $.data(element.form, "validator");
		if ( validator.settings.rules ) {
			rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
		}
		return rules;
	},

	normalizeRules: function( rules, element ) {
		// handle dependency check
		$.each(rules, function( prop, val ) {
			// ignore rule when param is explicitly false, eg. required:false
			if ( val === false ) {
				delete rules[prop];
				return;
			}
			if ( val.param || val.depends ) {
				var keepRule = true;
				switch (typeof val.depends) {
				case "string":
					keepRule = !!$(val.depends, element.form).length;
					break;
				case "function":
					keepRule = val.depends.call(element, element);
					break;
				}
				if ( keepRule ) {
					rules[prop] = val.param !== undefined ? val.param : true;
				} else {
					delete rules[prop];
				}
			}
		});

		// evaluate parameters
		$.each(rules, function( rule, parameter ) {
			rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
		});

		// clean number parameters
		$.each(['minlength', 'maxlength'], function() {
			if ( rules[this] ) {
				rules[this] = Number(rules[this]);
			}
		});
		$.each(['rangelength'], function() {
			var parts;
			if ( rules[this] ) {
				if ( $.isArray(rules[this]) ) {
					rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
				} else if ( typeof rules[this] === "string" ) {
					parts = rules[this].split(/[\s,]+/);
					rules[this] = [Number(parts[0]), Number(parts[1])];
				}
			}
		});

		if ( $.validator.autoCreateRanges ) {
			// auto-create ranges
			if ( rules.min && rules.max ) {
				rules.range = [rules.min, rules.max];
				delete rules.min;
				delete rules.max;
			}
			if ( rules.minlength && rules.maxlength ) {
				rules.rangelength = [rules.minlength, rules.maxlength];
				delete rules.minlength;
				delete rules.maxlength;
			}
		}

		return rules;
	},

	// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
	normalizeRule: function( data ) {
		if ( typeof data === "string" ) {
			var transformed = {};
			$.each(data.split(/\s/), function() {
				transformed[this] = true;
			});
			data = transformed;
		}
		return data;
	},

	// http://docs.jquery.com/Plugins/Validation/Validator/addMethod
	addMethod: function( name, method, message ) {
		$.validator.methods[name] = method;
		$.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
		if ( method.length < 3 ) {
			$.validator.addClassRules(name, $.validator.normalizeRule(name));
		}
	},

	methods: {

		// http://docs.jquery.com/Plugins/Validation/Methods/required
		required: function( value, element, param ) {
			// check if dependency is met
			if ( !this.depend(param, element) ) {
				return "dependency-mismatch";
			}
			if ( element.nodeName.toLowerCase() === "select" ) {
				// could be an array for select-multiple or a string, both are fine this way
				var val = $(element).val();
				return val && val.length > 0;
			}
			if ( this.checkable(element) ) {
				return this.getLength(value, element) > 0;
			}
			return $.trim(value).length > 0;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/remote
		remote: function( value, element, param ) {
			if ( this.optional(element) ) {
				return "dependency-mismatch";
			}

			var previous = this.previousValue(element);
			if (!this.settings.messages[element.name] ) {
				this.settings.messages[element.name] = {};
			}
			previous.originalMessage = this.settings.messages[element.name].remote;
			this.settings.messages[element.name].remote = previous.message;

			param = typeof param === "string" && {url:param} || param;

			if ( previous.old === value ) {
				return previous.valid;
			}

			previous.old = value;
			var validator = this;
			this.startRequest(element);
			var data = {};
			data[element.name] = value;
			$.ajax($.extend(true, {
				url: param,
				mode: "abort",
				port: "validate" + element.name,
				dataType: "json",
				data: data,
				success: function( response ) {
					validator.settings.messages[element.name].remote = previous.originalMessage;
					var valid = response === true || response === "true";
					if ( valid ) {
						var submitted = validator.formSubmitted;
						validator.prepareElement(element);
						validator.formSubmitted = submitted;
						validator.successList.push(element);
						delete validator.invalid[element.name];
						validator.showErrors();
					} else {
						var errors = {};
						var message = response || validator.defaultMessage( element, "remote" );
						errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
						validator.invalid[element.name] = true;
						validator.showErrors(errors);
					}
					previous.valid = valid;
					validator.stopRequest(element, valid);
				}
			}, param));
			return "pending";
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/minlength
		minlength: function( value, element, param ) {
			var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
			return this.optional(element) || length >= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/maxlength
		maxlength: function( value, element, param ) {
			var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
			return this.optional(element) || length <= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/rangelength
		rangelength: function( value, element, param ) {
			var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
			return this.optional(element) || ( length >= param[0] && length <= param[1] );
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/min
		min: function( value, element, param ) {
			return this.optional(element) || value >= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/max
		max: function( value, element, param ) {
			return this.optional(element) || value <= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/range
		range: function( value, element, param ) {
			return this.optional(element) || ( value >= param[0] && value <= param[1] );
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/email
		email: function( value, element ) {
			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
			return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/url
		url: function( value, element ) {
			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
			return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/date
		date: function( value, element ) {
			return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/dateISO
		dateISO: function( value, element ) {
			return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/number
		number: function( value, element ) {
			return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/digits
		digits: function( value, element ) {
			return this.optional(element) || /^\d+$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/creditcard
		// based on http://en.wikipedia.org/wiki/Luhn
		creditcard: function( value, element ) {
			if ( this.optional(element) ) {
				return "dependency-mismatch";
			}
			// accept only spaces, digits and dashes
			if ( /[^0-9 \-]+/.test(value) ) {
				return false;
			}
			var nCheck = 0,
				nDigit = 0,
				bEven = false;

			value = value.replace(/\D/g, "");

			for (var n = value.length - 1; n >= 0; n--) {
				var cDigit = value.charAt(n);
				nDigit = parseInt(cDigit, 10);
				if ( bEven ) {
					if ( (nDigit *= 2) > 9 ) {
						nDigit -= 9;
					}
				}
				nCheck += nDigit;
				bEven = !bEven;
			}

			return (nCheck % 10) === 0;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
		equalTo: function( value, element, param ) {
			// bind to the blur event of the target in order to revalidate whenever the target field is updated
			// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
			var target = $(param);
			if ( this.settings.onfocusout ) {
				target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
					$(element).valid();
				});
			}
			return value === target.val();
		}

	}

});

// deprecated, use $.validator.format instead
$.format = $.validator.format;

}(jQuery));

// ajax mode: abort
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
(function($) {
	var pendingRequests = {};
	// Use a prefilter if available (1.5+)
	if ( $.ajaxPrefilter ) {
		$.ajaxPrefilter(function( settings, _, xhr ) {
			var port = settings.port;
			if ( settings.mode === "abort" ) {
				if ( pendingRequests[port] ) {
					pendingRequests[port].abort();
				}
				pendingRequests[port] = xhr;
			}
		});
	} else {
		// Proxy ajax
		var ajax = $.ajax;
		$.ajax = function( settings ) {
			var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
				port = ( "port" in settings ? settings : $.ajaxSettings ).port;
			if ( mode === "abort" ) {
				if ( pendingRequests[port] ) {
					pendingRequests[port].abort();
				}
				return (pendingRequests[port] = ajax.apply(this, arguments));
			}
			return ajax.apply(this, arguments);
		};
	}
}(jQuery));

// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
(function($) {
	$.extend($.fn, {
		validateDelegate: function( delegate, type, handler ) {
			return this.bind(type, function( event ) {
				var target = $(event.target);
				if ( target.is(delegate) ) {
					return handler.apply(target, arguments);
				}
			});
		}
	});
}(jQuery));

/*
jquery.flash v1.3.1 -  02/01/10
(c)2009 Stephen Belanger - MIT/GPL.
http://docs.jquery.com/License
*/
Array.prototype.indexOf=function(o,i){for(var j=this.length,i=i<0?i+j<0?0:i+j:i||0;i<j&&this[i]!==o;i++);return j<=i?-1:i;};$.fn.extend({flash:function(opt){var has,cv,ie;function attr(a,b){return' '+a+'="'+b+'"';}function param(a,b){return'<param name="'+a+'" value="'+b+'" />';}var p=navigator.plugins;if(p&&p.length){var f=p['Shockwave Flash'];if(f){has=true;if(f.description)cv=f.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split(".");}if(p['Shockwave Flash 2.0']){has=true;cv='2.0.0.11';}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");cv=[6,0,21];has=true;}catch(e){};try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){};}if(axo!=null){cv=axo.GetVariable("$version").split(" ")[1].split(",");has=true;ie=true;}}$(this).each(function(){if(has){var e=$(this),s=$.extend({'id':e.attr('id'),'class':e.attr('class'),'width':e.width(),'height':e.height(),'src':e.attr('href'),'classid':'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000','pluginspace':'http://get.adobe.com/flashplayer','availattrs':['id','class','width','height','src'],'availparams':['src','bgcolor','quality','allowscriptaccess','allowfullscreen','flashvars','wmode'],'version':'9.0.24'},opt),a=s.availattrs,b=s.availparams,rv=s.version.split('.'),o='<object';if(!s.codebase){s.codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version='+rv.join(',');}if(s.express){for(var i in cv){if(parseInt(cv[i])>parseInt(rv[i])){break;}if(parseInt(cv[i])<parseInt(rv[i])){s.src=s.express;}}}if(s.flashvars){s.flashvars=unescape($.param(s.flashvars));}a=ie?a.concat(['classid','codebase']):a.concat(['pluginspage']);for(k in a){var n=(k==a.indexOf('src'))?'data':a[k];o+=s[a[k]]?attr(n,s[a[k]]):'';};o+='>';for(k in b){var n=(k==b.indexOf('src'))?'movie':b[k];o+=s[b[k]]?param(n,s[b[k]]):'';};o+='</object>';e.replaceWith(o);}return this;});}});
/*! jQuery Color v@2.1.2 http://github.com/jquery/jquery-color | jquery.org/license */
(function(a,b){function m(a,b,c){var d=h[b.type]||{};return a==null?c||!b.def?null:b.def:(a=d.floor?~~a:parseFloat(a),isNaN(a)?b.def:d.mod?(a+d.mod)%d.mod:0>a?0:d.max<a?d.max:a)}function n(b){var c=f(),d=c._rgba=[];return b=b.toLowerCase(),l(e,function(a,e){var f,h=e.re.exec(b),i=h&&e.parse(h),j=e.space||"rgba";if(i)return f=c[j](i),c[g[j].cache]=f[g[j].cache],d=c._rgba=f._rgba,!1}),d.length?(d.join()==="0,0,0,0"&&a.extend(d,k.transparent),c):k[b]}function o(a,b,c){return c=(c+1)%1,c*6<1?a+(b-a)*c*6:c*2<1?b:c*3<2?a+(b-a)*(2/3-c)*6:a}var c="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",d=/^([\-+])=\s*(\d+\.?\d*)/,e=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1],a[2],a[3],a[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1]*2.55,a[2]*2.55,a[3]*2.55,a[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(a){return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(a){return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(a){return[a[1],a[2]/100,a[3]/100,a[4]]}}],f=a.Color=function(b,c,d,e){return new a.Color.fn.parse(b,c,d,e)},g={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},h={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},i=f.support={},j=a("<p>")[0],k,l=a.each;j.style.cssText="background-color:rgba(1,1,1,.5)",i.rgba=j.style.backgroundColor.indexOf("rgba")>-1,l(g,function(a,b){b.cache="_"+a,b.props.alpha={idx:3,type:"percent",def:1}}),f.fn=a.extend(f.prototype,{parse:function(c,d,e,h){if(c===b)return this._rgba=[null,null,null,null],this;if(c.jquery||c.nodeType)c=a(c).css(d),d=b;var i=this,j=a.type(c),o=this._rgba=[];d!==b&&(c=[c,d,e,h],j="array");if(j==="string")return this.parse(n(c)||k._default);if(j==="array")return l(g.rgba.props,function(a,b){o[b.idx]=m(c[b.idx],b)}),this;if(j==="object")return c instanceof f?l(g,function(a,b){c[b.cache]&&(i[b.cache]=c[b.cache].slice())}):l(g,function(b,d){var e=d.cache;l(d.props,function(a,b){if(!i[e]&&d.to){if(a==="alpha"||c[a]==null)return;i[e]=d.to(i._rgba)}i[e][b.idx]=m(c[a],b,!0)}),i[e]&&a.inArray(null,i[e].slice(0,3))<0&&(i[e][3]=1,d.from&&(i._rgba=d.from(i[e])))}),this},is:function(a){var b=f(a),c=!0,d=this;return l(g,function(a,e){var f,g=b[e.cache];return g&&(f=d[e.cache]||e.to&&e.to(d._rgba)||[],l(e.props,function(a,b){if(g[b.idx]!=null)return c=g[b.idx]===f[b.idx],c})),c}),c},_space:function(){var a=[],b=this;return l(g,function(c,d){b[d.cache]&&a.push(c)}),a.pop()},transition:function(a,b){var c=f(a),d=c._space(),e=g[d],i=this.alpha()===0?f("transparent"):this,j=i[e.cache]||e.to(i._rgba),k=j.slice();return c=c[e.cache],l(e.props,function(a,d){var e=d.idx,f=j[e],g=c[e],i=h[d.type]||{};if(g===null)return;f===null?k[e]=g:(i.mod&&(g-f>i.mod/2?f+=i.mod:f-g>i.mod/2&&(f-=i.mod)),k[e]=m((g-f)*b+f,d))}),this[d](k)},blend:function(b){if(this._rgba[3]===1)return this;var c=this._rgba.slice(),d=c.pop(),e=f(b)._rgba;return f(a.map(c,function(a,b){return(1-d)*e[b]+d*a}))},toRgbaString:function(){var b="rgba(",c=a.map(this._rgba,function(a,b){return a==null?b>2?1:0:a});return c[3]===1&&(c.pop(),b="rgb("),b+c.join()+")"},toHslaString:function(){var b="hsla(",c=a.map(this.hsla(),function(a,b){return a==null&&(a=b>2?1:0),b&&b<3&&(a=Math.round(a*100)+"%"),a});return c[3]===1&&(c.pop(),b="hsl("),b+c.join()+")"},toHexString:function(b){var c=this._rgba.slice(),d=c.pop();return b&&c.push(~~(d*255)),"#"+a.map(c,function(a){return a=(a||0).toString(16),a.length===1?"0"+a:a}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),f.fn.parse.prototype=f.fn,g.hsla.to=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/255,c=a[1]/255,d=a[2]/255,e=a[3],f=Math.max(b,c,d),g=Math.min(b,c,d),h=f-g,i=f+g,j=i*.5,k,l;return g===f?k=0:b===f?k=60*(c-d)/h+360:c===f?k=60*(d-b)/h+120:k=60*(b-c)/h+240,h===0?l=0:j<=.5?l=h/i:l=h/(2-i),[Math.round(k)%360,l,j,e==null?1:e]},g.hsla.from=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/360,c=a[1],d=a[2],e=a[3],f=d<=.5?d*(1+c):d+c-d*c,g=2*d-f;return[Math.round(o(g,f,b+1/3)*255),Math.round(o(g,f,b)*255),Math.round(o(g,f,b-1/3)*255),e]},l(g,function(c,e){var g=e.props,h=e.cache,i=e.to,j=e.from;f.fn[c]=function(c){i&&!this[h]&&(this[h]=i(this._rgba));if(c===b)return this[h].slice();var d,e=a.type(c),k=e==="array"||e==="object"?c:arguments,n=this[h].slice();return l(g,function(a,b){var c=k[e==="object"?a:b.idx];c==null&&(c=n[b.idx]),n[b.idx]=m(c,b)}),j?(d=f(j(n)),d[h]=n,d):f(n)},l(g,function(b,e){if(f.fn[b])return;f.fn[b]=function(f){var g=a.type(f),h=b==="alpha"?this._hsla?"hsla":"rgba":c,i=this[h](),j=i[e.idx],k;return g==="undefined"?j:(g==="function"&&(f=f.call(this,j),g=a.type(f)),f==null&&e.empty?this:(g==="string"&&(k=d.exec(f),k&&(f=j+parseFloat(k[2])*(k[1]==="+"?1:-1))),i[e.idx]=f,this[h](i)))}})}),f.hook=function(b){var c=b.split(" ");l(c,function(b,c){a.cssHooks[c]={set:function(b,d){var e,g,h="";if(d!=="transparent"&&(a.type(d)!=="string"||(e=n(d)))){d=f(e||d);if(!i.rgba&&d._rgba[3]!==1){g=c==="backgroundColor"?b.parentNode:b;while((h===""||h==="transparent")&&g&&g.style)try{h=a.css(g,"backgroundColor"),g=g.parentNode}catch(j){}d=d.blend(h&&h!=="transparent"?h:"_default")}d=d.toRgbaString()}try{b.style[c]=d}catch(j){}}},a.fx.step[c]=function(b){b.colorInit||(b.start=f(b.elem,c),b.end=f(b.end),b.colorInit=!0),a.cssHooks[c].set(b.elem,b.start.transition(b.end,b.pos))}})},f.hook(c),a.cssHooks.borderColor={expand:function(a){var b={};return l(["Top","Right","Bottom","Left"],function(c,d){b["border"+d+"Color"]=a}),b}},k=a.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}})(jQuery);

;(function($){$.fn.ajaxSubmit=function(y){if(!this.length){log('ajaxSubmit: skipping submit process - no element selected');return this}var z,action,url,$form=this;if(typeof y=='function'){y={success:y}}z=this.attr('method');action=this.attr('action');url=(typeof action==='string')?$.trim(action):'';url=url||window.location.href||'';if(url){url=(url.match(/^([^#]+)/)||[])[1]}y=$.extend(true,{url:url,success:$.ajaxSettings.success,type:z||'GET',iframeSrc:/^https/i.test(window.location.href||'')?'javascript:false':'about:blank'},y);var A={};this.trigger('form-pre-serialize',[this,y,A]);if(A.veto){log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');return this}if(y.beforeSerialize&&y.beforeSerialize(this,y)===false){log('ajaxSubmit: submit aborted via beforeSerialize callback');return this}var B=y.traditional;if(B===undefined){B=$.ajaxSettings.traditional}var C,n,v,a=this.formToArray(y.semantic);if(y.data){y.extraData=y.data;C=$.param(y.data,B)}if(y.beforeSubmit&&y.beforeSubmit(a,this,y)===false){log('ajaxSubmit: submit aborted via beforeSubmit callback');return this}this.trigger('form-submit-validate',[a,this,y,A]);if(A.veto){log('ajaxSubmit: submit vetoed via form-submit-validate trigger');return this}var q=$.param(a,B);if(C){q=(q?(q+'&'+C):C)}if(y.type.toUpperCase()=='GET'){y.url+=(y.url.indexOf('?')>=0?'&':'?')+q;y.data=null}else{y.data=q}var D=[];if(y.resetForm){D.push(function(){$form.resetForm()})}if(y.clearForm){D.push(function(){$form.clearForm(y.includeHidden)})}if(!y.dataType&&y.target){var E=y.success||function(){};D.push(function(a){var b=y.replaceTarget?'replaceWith':'html';$(y.target)[b](a).each(E,arguments)})}else if(y.success){D.push(y.success)}y.success=function(a,b,c){var d=y.context||y;for(var i=0,max=D.length;i<max;i++){D[i].apply(d,[a,b,c||$form,$form])}};var F=$('input:file:enabled[value]',this);var G=F.length>0;var H='multipart/form-data';var I=($form.attr('enctype')==H||$form.attr('encoding')==H);var J=!!(G&&F.get(0).files&&window.FormData);log("fileAPI :"+J);var K=(G||I)&&!J;if(y.iframe!==false&&(y.iframe||K)){if(y.closeKeepAlive){$.get(y.closeKeepAlive,function(){fileUploadIframe(a)})}else{fileUploadIframe(a)}}else if((G||I)&&J){y.progress=y.progress||$.noop;fileUploadXhr(a)}else{$.ajax(y)}this.trigger('form-submit-notify',[this,y]);return this;function fileUploadXhr(a){var c=new FormData();for(var i=0;i<a.length;i++){if(a[i].type=='file')continue;c.append(a[i].name,a[i].value)}$form.find('input:file:enabled').each(function(){var a=$(this).attr('name'),files=this.files;if(a){for(var i=0;i<files.length;i++)c.append(a,files[i])}});if(y.extraData){for(var k in y.extraData)c.append(k,y.extraData[k])}y.data=null;var s=$.extend(true,{},$.ajaxSettings,y,{contentType:false,processData:false,cache:false,type:'POST'});s.data=null;var d=s.beforeSend;s.beforeSend=function(b,o){o.data=c;if(b.upload){b.upload.onprogress=function(a){o.progress(a.position,a.total)}}if(d)d.call(o,b,y)};$.ajax(s)}function fileUploadIframe(a){var l=$form[0],el,i,s,g,id,$io,io,xhr,sub,n,timedOut,timeoutHandle;var m=!!$.fn.prop;if(a){if(m){for(i=0;i<a.length;i++){el=$(l[a[i].name]);el.prop('disabled',false)}}else{for(i=0;i<a.length;i++){el=$(l[a[i].name]);el.removeAttr('disabled')}}}if($(':input[name=submit],:input[id=submit]',l).length){alert('Error: Form elements must not have name or id of "submit".');return}s=$.extend(true,{},$.ajaxSettings,y);s.context=s.context||s;id='jqFormIO'+(new Date().getTime());if(s.iframeTarget){$io=$(s.iframeTarget);n=$io.attr('name');if(n==null)$io.attr('name',id);else id=n}else{$io=$('<iframe name="'+id+'" src="'+s.iframeSrc+'" />');$io.css({position:'absolute',top:'-1000px',left:'-1000px'})}io=$io[0];xhr={aborted:0,responseText:null,responseXML:null,status:0,statusText:'n/a',getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(a){var e=(a==='timeout'?'timeout':'aborted');log('aborting upload... '+e);this.aborted=1;$io.attr('src',s.iframeSrc);xhr.error=e;s.error&&s.error.call(s.context,xhr,e,a);g&&$.event.trigger("ajaxError",[xhr,s,e]);s.complete&&s.complete.call(s.context,xhr,e)}};g=s.global;if(g&&!$.active++){$.event.trigger("ajaxStart")}if(g){$.event.trigger("ajaxSend",[xhr,s])}if(s.beforeSend&&s.beforeSend.call(s.context,xhr,s)===false){if(s.global){$.active--}return}if(xhr.aborted){return}sub=l.clk;if(sub){n=sub.name;if(n&&!sub.disabled){s.extraData=s.extraData||{};s.extraData[n]=sub.value;if(sub.type=="image"){s.extraData[n+'.x']=l.clk_x;s.extraData[n+'.y']=l.clk_y}}}var o=1;var p=2;function getDoc(a){var b=a.contentWindow?a.contentWindow.document:a.contentDocument?a.contentDocument:a.document;return b}var q=$('meta[name=csrf-token]').attr('content');var r=$('meta[name=csrf-param]').attr('content');if(r&&q){s.extraData=s.extraData||{};s.extraData[r]=q}function doSubmit(){var t=$form.attr('target'),a=$form.attr('action');l.setAttribute('target',id);if(!z){l.setAttribute('method','POST')}if(a!=s.url){l.setAttribute('action',s.url)}if(!s.skipEncodingOverride&&(!z||/post/i.test(z))){$form.attr({encoding:'multipart/form-data',enctype:'multipart/form-data'})}if(s.timeout){timeoutHandle=setTimeout(function(){timedOut=true;cb(o)},s.timeout)}function checkState(){try{var a=getDoc(io).readyState;log('state = '+a);if(a.toLowerCase()=='uninitialized')setTimeout(checkState,50)}catch(e){log('Server abort: ',e,' (',e.name,')');cb(p);timeoutHandle&&clearTimeout(timeoutHandle);timeoutHandle=undefined}}var b=[];try{if(s.extraData){for(var n in s.extraData){b.push($('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n]).appendTo(l)[0])}}if(!s.iframeTarget){$io.appendTo('body');io.attachEvent?io.attachEvent('onload',cb):io.addEventListener('load',cb,false)}setTimeout(checkState,15);l.submit()}finally{l.setAttribute('action',a);if(t){l.setAttribute('target',t)}else{$form.removeAttr('target')}$(b).remove()}}if(s.forceSync){doSubmit()}else{setTimeout(doSubmit,10)}var u,doc,domCheckCount=50,callbackProcessed;function cb(e){if(xhr.aborted||callbackProcessed){return}try{doc=getDoc(io)}catch(ex){log('cannot access response document: ',ex);e=p}if(e===o&&xhr){xhr.abort('timeout');return}else if(e==p&&xhr){xhr.abort('server abort');return}if(!doc||doc.location.href==s.iframeSrc){if(!timedOut)return}io.detachEvent?io.detachEvent('onload',cb):io.removeEventListener('load',cb,false);var c='success',errMsg;try{if(timedOut){throw'timeout';}var d=s.dataType=='xml'||doc.XMLDocument||$.isXMLDoc(doc);log('isXml='+d);if(!d&&window.opera&&(doc.body==null||doc.body.innerHTML=='')){if(--domCheckCount){log('requeing onLoad callback, DOM not available');setTimeout(cb,250);return}}var f=doc.body?doc.body:doc.documentElement;xhr.responseText=f?f.innerHTML:null;xhr.responseXML=doc.XMLDocument?doc.XMLDocument:doc;if(d)s.dataType='xml';xhr.getResponseHeader=function(a){var b={'content-type':s.dataType};return b[a]};if(f){xhr.status=Number(f.getAttribute('status'))||xhr.status;xhr.statusText=f.getAttribute('statusText')||xhr.statusText}var h=(s.dataType||'').toLowerCase();var i=/(json|script|text)/.test(h);if(i||s.textarea){var j=doc.getElementsByTagName('textarea')[0];if(j){xhr.responseText=j.value;xhr.status=Number(j.getAttribute('status'))||xhr.status;xhr.statusText=j.getAttribute('statusText')||xhr.statusText}else if(i){var k=doc.getElementsByTagName('pre')[0];var b=doc.getElementsByTagName('body')[0];if(k){xhr.responseText=k.textContent?k.textContent:k.innerText}else if(b){xhr.responseText=b.textContent?b.textContent:b.innerText}}}else if(h=='xml'&&!xhr.responseXML&&xhr.responseText!=null){xhr.responseXML=v(xhr.responseText)}try{u=x(xhr,h,s)}catch(e){c='parsererror';xhr.error=errMsg=(e||c)}}catch(e){log('error caught: ',e);c='error';xhr.error=errMsg=(e||c)}if(xhr.aborted){log('upload aborted');c=null}if(xhr.status){c=(xhr.status>=200&&xhr.status<300||xhr.status===304)?'success':'error'}if(c==='success'){s.success&&s.success.call(s.context,u,'success',xhr);g&&$.event.trigger("ajaxSuccess",[xhr,s])}else if(c){if(errMsg==undefined)errMsg=xhr.statusText;s.error&&s.error.call(s.context,xhr,c,errMsg);g&&$.event.trigger("ajaxError",[xhr,s,errMsg])}g&&$.event.trigger("ajaxComplete",[xhr,s]);if(g&&!--$.active){$.event.trigger("ajaxStop")}s.complete&&s.complete.call(s.context,xhr,c);callbackProcessed=true;if(s.timeout)clearTimeout(timeoutHandle);setTimeout(function(){if(!s.iframeTarget)$io.remove();xhr.responseXML=null},100)}var v=$.parseXML||function(s,a){if(window.ActiveXObject){a=new ActiveXObject('Microsoft.XMLDOM');a.async='false';a.loadXML(s)}else{a=(new DOMParser()).parseFromString(s,'text/xml')}return(a&&a.documentElement&&a.documentElement.nodeName!='parsererror')?a:null};var w=$.parseJSON||function(s){return window['eval']('('+s+')')};var x=function(a,b,s){var c=a.getResponseHeader('content-type')||'',xml=b==='xml'||!b&&c.indexOf('xml')>=0,u=xml?a.responseXML:a.responseText;if(xml&&u.documentElement.nodeName==='parsererror'){$.error&&$.error('parsererror')}if(s&&s.dataFilter){u=s.dataFilter(u,b)}if(typeof u==='string'){if(b==='json'||!b&&c.indexOf('json')>=0){u=w(u)}else if(b==="script"||!b&&c.indexOf("javascript")>=0){$.globalEval(u)}}return u}}};$.fn.ajaxForm=function(a){a=a||{};a.delegation=a.delegation&&$.isFunction($.fn.on);if(!a.delegation&&this.length===0){var o={s:this.selector,c:this.context};if(!$.isReady&&o.s){log('DOM not ready, queuing ajaxForm');$(function(){$(o.s,o.c).ajaxForm(a)});return this}log('terminating; zero elements found by selector'+($.isReady?'':' (DOM not ready)'));return this}if(a.delegation){$(document).off('submit.form-plugin',this.selector,doAjaxSubmit).off('click.form-plugin',this.selector,captureSubmittingElement).on('submit.form-plugin',this.selector,a,doAjaxSubmit).on('click.form-plugin',this.selector,a,captureSubmittingElement);return this}return this.ajaxFormUnbind().bind('submit.form-plugin',a,doAjaxSubmit).bind('click.form-plugin',a,captureSubmittingElement)};function doAjaxSubmit(e){var a=e.data;if(!e.isDefaultPrevented()){e.preventDefault();$(this).ajaxSubmit(a)}}function captureSubmittingElement(e){var a=e.target;var b=$(a);if(!(b.is(":submit,input:image"))){var t=b.closest(':submit');if(t.length==0){return}a=t[0]}var c=this;c.clk=a;if(a.type=='image'){if(e.offsetX!=undefined){c.clk_x=e.offsetX;c.clk_y=e.offsetY}else if(typeof $.fn.offset=='function'){var d=b.offset();c.clk_x=e.pageX-d.left;c.clk_y=e.pageY-d.top}else{c.clk_x=e.pageX-a.offsetLeft;c.clk_y=e.pageY-a.offsetTop}}setTimeout(function(){c.clk=c.clk_x=c.clk_y=null},100)};$.fn.ajaxFormUnbind=function(){return this.unbind('submit.form-plugin click.form-plugin')};$.fn.formToArray=function(b){var a=[];if(this.length===0){return a}var c=this[0];var d=b?c.getElementsByTagName('*'):c.elements;if(!d){return a}var i,j,n,v,el,max,jmax;for(i=0,max=d.length;i<max;i++){el=d[i];n=el.name;if(!n){continue}if(b&&c.clk&&el.type=="image"){if(!el.disabled&&c.clk==el){a.push({name:n,value:$(el).val(),type:el.type});a.push({name:n+'.x',value:c.clk_x},{name:n+'.y',value:c.clk_y})}continue}v=$.fieldValue(el,true);if(v&&v.constructor==Array){for(j=0,jmax=v.length;j<jmax;j++){a.push({name:n,value:v[j]})}}else if(v!==null&&typeof v!='undefined'){a.push({name:n,value:v,type:el.type})}}if(!b&&c.clk){var e=$(c.clk),input=e[0];n=input.name;if(n&&!input.disabled&&input.type=='image'){a.push({name:n,value:e.val()});a.push({name:n+'.x',value:c.clk_x},{name:n+'.y',value:c.clk_y})}}return a};$.fn.formSerialize=function(a){return $.param(this.formToArray(a))};$.fn.fieldSerialize=function(b){var a=[];this.each(function(){var n=this.name;if(!n){return}var v=$.fieldValue(this,b);if(v&&v.constructor==Array){for(var i=0,max=v.length;i<max;i++){a.push({name:n,value:v[i]})}}else if(v!==null&&typeof v!='undefined'){a.push({name:this.name,value:v})}});return $.param(a)};$.fn.fieldValue=function(a){for(var b=[],i=0,max=this.length;i<max;i++){var c=this[i];var v=$.fieldValue(c,a);if(v===null||typeof v=='undefined'||(v.constructor==Array&&!v.length)){continue}v.constructor==Array?$.merge(b,v):b.push(v)}return b};$.fieldValue=function(b,c){var n=b.name,t=b.type,tag=b.tagName.toLowerCase();if(c===undefined){c=true}if(c&&(!n||b.disabled||t=='reset'||t=='button'||(t=='checkbox'||t=='radio')&&!b.checked||(t=='submit'||t=='image')&&b.form&&b.form.clk!=b||tag=='select'&&b.selectedIndex==-1)){return null}if(tag=='select'){var d=b.selectedIndex;if(d<0){return null}var a=[],ops=b.options;var e=(t=='select-one');var f=(e?d+1:ops.length);for(var i=(e?d:0);i<f;i++){var g=ops[i];if(g.selected){var v=g.value;if(!v){v=(g.attributes&&g.attributes['value']&&!(g.attributes['value'].specified))?g.text:g.value}if(e){return v}a.push(v)}}return a}return $(b).val()};$.fn.clearForm=function(a){return this.each(function(){$('input,select,textarea',this).clearFields(a)})};$.fn.clearFields=$.fn.clearInputs=function(a){var b=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var t=this.type,tag=this.tagName.toLowerCase();if(b.test(t)||tag=='textarea'||(a&&/hidden/.test(t))){this.value=''}else if(t=='checkbox'||t=='radio'){this.checked=false}else if(tag=='select'){this.selectedIndex=-1}})};$.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=='function'||(typeof this.reset=='object'&&!this.reset.nodeType)){this.reset()}})};$.fn.enable=function(b){if(b===undefined){b=true}return this.each(function(){this.disabled=!b})};$.fn.selected=function(b){if(b===undefined){b=true}return this.each(function(){var t=this.type;if(t=='checkbox'||t=='radio'){this.checked=b}else if(this.tagName.toLowerCase()=='option'){var a=$(this).parent('select');if(b&&a[0]&&a[0].type=='select-one'){a.find('option').selected(false)}this.selected=b}})};$.fn.ajaxSubmit.debug=false;function log(){if(!$.fn.ajaxSubmit.debug)return;var a='[jquery.form] '+Array.prototype.join.call(arguments,'');if(window.console&&window.console.log){window.console.log(a)}else if(window.opera&&window.opera.postError){window.opera.postError(a)}}})(jQuery);

/**
 The MIT License

 Copyright (c) 2010 Daniel Park (http://metaweb.com, http://postmessage.freebaseapps.com)

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 **/
var NO_JQUERY = {};
(function(window, $, undefined) {

     if (!("console" in window)) {
         var c = window.console = {};
         c.log = c.warn = c.error = c.debug = function(){};
     }

     if ($ === NO_JQUERY) {
         // jQuery is optional
         $ = {
             fn: {},
             extend: function() {
                 var a = arguments[0];
                 for (var i=1,len=arguments.length; i<len; i++) {
                     var b = arguments[i];
                     for (var prop in b) {
                         a[prop] = b[prop];
                     }
                 }
                 return a;
             }
         };
     }

     $.fn.pm = function() {
         //console.log("usage: \nto send:    $.pm(options)\nto receive: $.pm.bind(type, fn, [origin])");
         return this;
     };

     // send postmessage
     $.pm = window.pm = function(options) {
         pm.send(options);
     };

     // bind postmessage handler
     $.pm.bind = window.pm.bind = function(type, fn, origin, hash, async_reply) {
         pm.bind(type, fn, origin, hash, async_reply === true);
     };

     // unbind postmessage handler
     $.pm.unbind = window.pm.unbind = function(type, fn) {
         pm.unbind(type, fn);
     };

     // default postmessage origin on bind
     $.pm.origin = window.pm.origin = null;

     // default postmessage polling if using location hash to pass postmessages
     $.pm.poll = window.pm.poll = 200;

     var pm = {

         send: function(options) {
             var o = $.extend({}, pm.defaults, options),
             target = o.target;
             if (!o.target) {
                 //console.warn("postmessage target window required");
                 return;
             }
             if (!o.type) {
                 //console.warn("postmessage type required");
                 return;
             }
             var msg = {data:o.data, type:o.type};
             if (o.success) {
                 msg.callback = pm._callback(o.success);
             }
             if (o.error) {
                 msg.errback = pm._callback(o.error);
             }
             if (("postMessage" in target) && !o.hash) {
                 pm._bind();
                 target.postMessage(JSON.stringify(msg), o.origin || '*');
             }
             else {
                 pm.hash._bind();
                 pm.hash.send(o, msg);
             }
         },

         bind: function(type, fn, origin, hash, async_reply) {
           pm._replyBind ( type, fn, origin, hash, async_reply );
         },

         _replyBind: function(type, fn, origin, hash, isCallback) {
           if (("postMessage" in window) && !hash) {
               pm._bind();
           }
           else {
               pm.hash._bind();
           }
           var l = pm.data("listeners.postmessage");
           if (!l) {
               l = {};
               pm.data("listeners.postmessage", l);
           }
           var fns = l[type];
           if (!fns) {
               fns = [];
               l[type] = fns;
           }
           fns.push({fn:fn, callback: isCallback, origin:origin || $.pm.origin});
         },

         unbind: function(type, fn) {
             var l = pm.data("listeners.postmessage");
             if (l) {
                 if (type) {
                     if (fn) {
                         // remove specific listener
                         var fns = l[type];
                         if (fns) {
                             var m = [];
                             for (var i=0,len=fns.length; i<len; i++) {
                                 var o = fns[i];
                                 if (o.fn !== fn) {
                                     m.push(o);
                                 }
                             }
                             l[type] = m;
                         }
                     }
                     else {
                         // remove all listeners by type
                         delete l[type];
                     }
                 }
                 else {
                     // unbind all listeners of all type
                     for (var i in l) {
                       delete l[i];
                     }
                 }
             }
         },

         data: function(k, v) {
             if (v === undefined) {
                 return pm._data[k];
             }
             pm._data[k] = v;
             return v;
         },

         _data: {},

         _CHARS: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''),

         _random: function() {
             var r = [];
             for (var i=0; i<32; i++) {
                 r[i] = pm._CHARS[0 | Math.random() * 32];
             };
             return r.join("");
         },

         _callback: function(fn) {
             var cbs = pm.data("callbacks.postmessage");
             if (!cbs) {
                 cbs = {};
                 pm.data("callbacks.postmessage", cbs);
             }
             var r = pm._random();
             cbs[r] = fn;
             return r;
         },

         _bind: function() {
             // are we already listening to message events on this w?
             if (!pm.data("listening.postmessage")) {
                 if (window.addEventListener) {
                     window.addEventListener("message", pm._dispatch, false);
                 }
                 else if (window.attachEvent) {
                     window.attachEvent("onmessage", pm._dispatch);
                 }
                 pm.data("listening.postmessage", 1);
             }
         },

         _dispatch: function(e) {
             //console.log("$.pm.dispatch", e, this);
             try {
                 var msg = JSON.parse(e.data);
             }
             catch (ex) {
                 //console.warn("postmessage data invalid json: ", ex);
                 return;
             }
             if (!msg.type) {
                 //console.warn("postmessage message type required");
                 return;
             }
             var cbs = pm.data("callbacks.postmessage") || {},
             cb = cbs[msg.type];
             if (cb) {
                 cb(msg.data);
             }
             else {
                 var l = pm.data("listeners.postmessage") || {};
                 var fns = l[msg.type] || [];
                 for (var i=0,len=fns.length; i<len; i++) {
                     var o = fns[i];
                     if (o.origin && o.origin !== '*' && e.origin !== o.origin) {
                         //console.warn("postmessage message origin mismatch", e.origin, o.origin);
                         if (msg.errback) {
                             // notify post message errback
                             var error = {
                                 message: "postmessage origin mismatch",
                                 origin: [e.origin, o.origin]
                             };
                             pm.send({target:e.source, data:error, type:msg.errback});
                         }
                         continue;
                     }

                     function sendReply ( data ) {
                       if (msg.callback) {
                           pm.send({target:e.source, data:data, type:msg.callback});
                       }
                     }

                     try {
                         if ( o.callback ) {
                           o.fn(msg.data, sendReply, e);
                         } else {
                           sendReply ( o.fn(msg.data, e) );
                         }
                     }
                     catch (ex) {
                         if (msg.errback) {
                             // notify post message errback
                             pm.send({target:e.source, data:ex, type:msg.errback});
                         } else {
                             throw ex;
                         }
                     }
                 };
             }
         }
     };

     // location hash polling
     pm.hash = {

         send: function(options, msg) {
             //console.log("hash.send", target_window, options, msg);
             var target_window = options.target,
             target_url = options.url;
             if (!target_url) {
                 //console.warn("postmessage target window url is required");
                 return;
             }
             target_url = pm.hash._url(target_url);
             var source_window,
             source_url = pm.hash._url(window.location.href);
             if (window == target_window.parent) {
                 source_window = "parent";
             }
             else {
                 try {
                     for (var i=0,len=parent.frames.length; i<len; i++) {
                         var f = parent.frames[i];
                         if (f == window) {
                             source_window = i;
                             break;
                         }
                     };
                 }
                 catch(ex) {
                     // Opera: security error trying to access parent.frames x-origin
                     // juse use window.name
                     source_window = window.name;
                 }
             }
             if (source_window == null) {
                 //console.warn("postmessage windows must be direct parent/child windows and the child must be available through the parent window.frames list");
                 return;
             }
             var hashmessage = {
                 "x-requested-with": "postmessage",
                 source: {
                     name: source_window,
                     url: source_url
                 },
                 postmessage: msg
             };
             var hash_id = "#x-postmessage-id=" + pm._random();
             target_window.location = target_url + hash_id + encodeURIComponent(JSON.stringify(hashmessage));
         },

         _regex: /^\#x\-postmessage\-id\=(\w{32})/,

         _regex_len: "#x-postmessage-id=".length + 32,

         _bind: function() {
             // are we already listening to message events on this w?
             if (!pm.data("polling.postmessage")) {
                 setInterval(function() {
                                 var hash = "" + window.location.hash,
                                 m = pm.hash._regex.exec(hash);
                                 if (m) {
                                     var id = m[1];
                                     if (pm.hash._last !== id) {
                                         pm.hash._last = id;
                                         pm.hash._dispatch(hash.substring(pm.hash._regex_len));
                                     }
                                 }
                             }, $.pm.poll || 200);
                 pm.data("polling.postmessage", 1);
             }
         },

         _dispatch: function(hash) {
             if (!hash) {
                 return;
             }
             try {
                 hash = JSON.parse(decodeURIComponent(hash));
                 if (!(hash['x-requested-with'] === 'postmessage' &&
                       hash.source && hash.source.name != null && hash.source.url && hash.postmessage)) {
                     // ignore since hash could've come from somewhere else
                     return;
                 }
             }
             catch (ex) {
                 // ignore since hash could've come from somewhere else
                 return;
             }
             var msg = hash.postmessage,
             cbs = pm.data("callbacks.postmessage") || {},
             cb = cbs[msg.type];
             if (cb) {
                 cb(msg.data);
             }
             else {
                 var source_window;
                 if (hash.source.name === "parent") {
                     source_window = window.parent;
                 }
                 else {
                     source_window = window.frames[hash.source.name];
                 }
                 var l = pm.data("listeners.postmessage") || {};
                 var fns = l[msg.type] || [];
                 for (var i=0,len=fns.length; i<len; i++) {
                     var o = fns[i];
                     if (o.origin) {
                         var origin = /https?\:\/\/[^\/]*/.exec(hash.source.url)[0];
                         if (o.origin !== '*' && origin !== o.origin) {
                             //console.warn("postmessage message origin mismatch", origin, o.origin);
                             if (msg.errback) {
                                 // notify post message errback
                                 var error = {
                                     message: "postmessage origin mismatch",
                                     origin: [origin, o.origin]
                                 };
                                 pm.send({target:source_window, data:error, type:msg.errback, hash:true, url:hash.source.url});
                             }
                             continue;
                         }
                     }

                     function sendReply ( data ) {
                       if (msg.callback) {
                         pm.send({target:source_window, data:data, type:msg.callback, hash:true, url:hash.source.url});
                       }
                     }

                     try {
                         if ( o.callback ) {
                           o.fn(msg.data, sendReply);
                         } else {
                           sendReply ( o.fn(msg.data) );
                         }
                     }
                     catch (ex) {
                         if (msg.errback) {
                             // notify post message errback
                             pm.send({target:source_window, data:ex, type:msg.errback, hash:true, url:hash.source.url});
                         } else {
                             throw ex;
                         }
                     }
                 };
             }
         },

         _url: function(url) {
             // url minus hash part
             return (""+url).replace(/#.*$/, "");
         }

     };

     $.extend(pm, {
                  defaults: {
                      target: null,  /* target window (required) */
                      url: null,     /* target window url (required if no window.postMessage or hash == true) */
                      type: null,    /* message type (required) */
                      data: null,    /* message data (required) */
                      success: null, /* success callback (optional) */
                      error: null,   /* error callback (optional) */
                      origin: "*",   /* postmessage origin (optional) */
                      hash: false    /* use location hash for message passing (optional) */
                  }
              });

 })(this, typeof jQuery === "undefined" ? NO_JQUERY : jQuery);

/**
 * http://www.JSON.org/json2.js
 **/
if (! ("JSON" in window && window.JSON)){JSON={}}(function(){function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z"};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={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){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){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}if(rep&&typeof rep==="object"){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{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}}if(typeof JSON.stringify!=="function"){JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else{if(typeof space==="string"){indent=space}}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":value})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}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,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}}());

/*
 * waitForImages 1.4
 * -----------------
 * Provides a callback when all images have loaded in your given selector.
 * http://www.alexanderdickson.com/
 *
 *
 * Copyright (c) 2011 Alex Dickson
 * Licensed under the MIT licenses.
 * See website for more info.
 *
 */

;(function($) {
    // Namespace all events.
    var eventNamespace = 'waitForImages';

    // CSS properties which contain references to images.
    $.waitForImages = {
        hasImageProperties: [
        'backgroundImage',
        'listStyleImage',
        'borderImage',
        'borderCornerImage'
        ]
    };

    // Custom selector to find `img` elements that have a valid `src` attribute and have not already loaded.
    $.expr[':'].uncached = function(obj) {
        // Ensure we are dealing with an `img` element with a valid `src` attribute.
        if ( ! $(obj).is('img[src!=""]')) {
            return false;
        }

        // Firefox's `complete` property will always be`true` even if the image has not been downloaded.
        // Doing it this way works in Firefox.
        var img = document.createElement('img');
        img.src = obj.src;
        return ! img.complete;
    };

    $.fn.waitForImages = function(finishedCallback, eachCallback, waitForAll) {

        // Handle options object.
        if ($.isPlainObject(arguments[0])) {
            eachCallback = finishedCallback.each;
            waitForAll = finishedCallback.waitForAll;
            finishedCallback = finishedCallback.finished;
        }

        // Handle missing callbacks.
        finishedCallback = finishedCallback || $.noop;
        eachCallback = eachCallback || $.noop;

        // Convert waitForAll to Boolean
        waitForAll = !! waitForAll;

        // Ensure callbacks are functions.
        if (!$.isFunction(finishedCallback) || !$.isFunction(eachCallback)) {
            throw new TypeError('An invalid callback was supplied.');
        };

        return this.each(function() {
            // Build a list of all imgs, dependent on what images will be considered.
            var obj = $(this),
                allImgs = [];

            if (waitForAll) {
                // CSS properties which may contain an image.
                var hasImgProperties = $.waitForImages.hasImageProperties || [],
                    matchUrl = /url\((['"]?)(.*?)\1\)/g;

                // Get all elements, as any one of them could have a background image.
                obj.find('*').each(function() {
                    var element = $(this);

                    // If an `img` element, add it. But keep iterating in case it has a background image too.
                    if (element.is('img:uncached')) {
                        allImgs.push({
                            src: element.attr('src'),
                            element: element[0]
                        });
                    }

                    $.each(hasImgProperties, function(i, property) {
                        var propertyValue = element.css(property);
                        // If it doesn't contain this property, skip.
                        if ( ! propertyValue) {
                            return true;
                        }

                        // Get all url() of this element.
                        var match;
                        while (match = matchUrl.exec(propertyValue)) {
                            allImgs.push({
                                src: match[2],
                                element: element[0]
                            });
                        };
                    });
                });
            } else {
                // For images only, the task is simpler.
                obj
                 .find('img:uncached')
                 .each(function() {
                    allImgs.push({
                        src: this.src,
                        element: this
                    });
                });
            };

            var allImgsLength = allImgs.length,
                allImgsLoaded = 0;

            // If no images found, don't bother.
            if (allImgsLength == 0) {
                finishedCallback.call(obj[0]);
            };

            $.each(allImgs, function(i, img) {

                var image = new Image;

                // Handle the image loading and error with the same callback.
                $(image).bind('load.' + eventNamespace + ' error.' + eventNamespace, function(event) {
                    allImgsLoaded++;

                    // If an error occurred with loading the image, set the third argument accordingly.
                    eachCallback.call(img.element, allImgsLoaded, allImgsLength, event.type == 'load');

                    if (allImgsLoaded == allImgsLength) {
                        finishedCallback.call(obj[0]);
                        return false;
                    };

                });

                image.src = img.src;
            });
        });
    };
})(jQuery);

// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend( jQuery.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});
(function($) {
    $.fn.zoomIn = function(overCallback) {
            return this.each(function(){
                var obj = $(this);

                obj.parent().parent().css("z-index", 1);

                if (obj.data('originalHeight') == undefined) {
                    obj.data('originalHeight', obj.height());
                    obj.data('originalWidth', obj.width());
                    obj.data('originalLeft', obj.css('marginLeft'));
                    obj.data('originalTop', obj.css('marginTop'));
                }

                if (obj.attr('overCallback') != undefined) {
                    window[obj.attr('overCallback')]();
                }

                obj.animate({
                        height: obj.data('originalHeight') + 20,
                        width: obj.data('originalWidth') + 20,
                        marginLeft: "-=10",
                        marginTop: "-=10"
                    }, "fast");
                });
        }
    $.fn.zoomOut = function() {
            return this.each(function() {
                var obj = $(this);

                if (obj.attr('outCallback') != undefined) {
                    window[obj.attr('outCallback')]();
                }

                // hover out
                obj.parent().parent().css("z-index", 0);
                obj.animate({
                    height: obj.data('originalHeight'),
                    width: obj.data('originalWidth'),
                    marginLeft: obj.data('originalLeft'),
                    marginTop: obj.data('originalTop')
                }, "fast");
            });

        }

})(jQuery);



(function(){
    "use strict";

    /**
     * Shortcut for console.log in window namespace.
     * @method l
     * @public
     * @param {Object} ...arguments Objects to log.
     */
    window.l = function(){
        if(window.console && window.console.log instanceof Function){
            window.console.log.apply(window.console, arguments);
        }
    }
}());

//##############################################################################
// String Class Extending
//##############################################################################
(function(){
    "use strict";

    String.prototype.format = function(args){
        return this.replace(String.prototype.format.regex, function(item){
            var intVal = parseInt(item.substring(1, item.length - 1));
            var replace;
            if(intVal >= 0){
                replace = args[intVal];
            } else if(intVal === -1){
                replace = "{";
            } else if(intVal === -2){
                replace = "}";
            } else {
                replace = "";
            }
            return replace;
        });
    };

    String.prototype.format.regex = /{-?[0-9]+}/g;
}());

//##############################################################################
// Array Class Extending
//##############################################################################
(function(){
    "use strict";

    /**
     * Converts arguments to Array.
     * @param {Arguments} args Arguments passed to method.
     * @return {Array} Arguemnts converted to Array.
     */
    Array.fromArguments = function(args){
        return Array.prototype.slice.call(args);
    }

    var p = Array.prototype;

    p.shuffle = function(){
        var length = this.length;
        var j;
        var temp;
        if(length == 0) return;

        while(--length){
            j = Math.floor(Math.random() * (length + 1));
            temp = this[length];
            this[length] = this[j];
            this[j] = temp;
        }
    }

    p.sortOn = function(field, reverse, primer) {
        this.sort(this.sortOnMethod(field, reverse, primer));
    }

    p.sortOnMethod = function(field, reverse, primer) {
        var key = primer ?
            function(x) { return primer(x[field]) } :
            function(x) { return x[field] };

        reverse = [-1, 1][+!!reverse];

        return function (a, b) {
            return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
        }
    }

    /**
     * @property {Item} randomItem Returns randomly selected item from Array.
     * @public
     * @readOnly
     * @return {Item}
     */
    Object.defineProperty(p, "randomItem", {
        get: function(){
            var pointer = Math.floor(Math.random() * this.length);
            return this[pointer];
        }
    });

    /**
     * Clears the entire Array.
     * @method flush
     * @public
     */
    p.flush = function(){
        this.splice(0, this.length);
    }

    /**
     * Removes specified element from the whole Array.
     * @method removeElement
     * @param  element Element to remove.
     * @return {Array} Returns itself.
     */
    p.removeElement = function(element){
        for(var i; ; ){
            i = this.indexOf(element);

            if(i >= 0) this.splice(i, 1);
            else return this;
        }
    }
}());

//##############################################################################
// Math Class Extending
//##############################################################################
(function(){
    "use strict";
    /**
     * Returns the greatest common divisor of passed integers.
     * @method greatestCommonDivisor
     * @public
     * @param {Int} ...arguments A collection of integers.
     */

    Math.greatestCommonDivisor = function(){
        var numbers = Array.fromArguments(arguments);
        var a = numbers.pop();

        while(numbers.length > 0){
            a = proceed(a, numbers.pop());
        }

        return a;

        function proceed(a, b){
            a = isNaN(a) ? null : a;
            b = isNaN(b) ? null : b;

            if(a < 1 && b < 1) return null;
            if(a < 1 || b < 1) return Math.max(a, b);

            var tmp;

            while(b != 0) {
                tmp = a;
                a   = b;
                b   = tmp % b;
            }

            return a;
        }
    }

    /**
     * Return random number between minimal and maximal number round to decimal places.
     * @method randomRange
     * @public
     * @param {Number} min              Minimal value (inclusive).
     * @param {Number} max              Maximal value (inclusive).
     * @param {Number} [decimalPlaces]  Number of decimal places of random number.
     * @return {Number}                 Returns random number between min and max value (inclusive).
     */

    Math.randomRange = function(min, max, decimalPlaces){
        var shift = -1;

        if((typeof decimalPlaces === "number") && (decimalPlaces % 1 === 0)){
            shift = Math.pow(10, decimalPlaces)
        }

        if(shift > 0){
            return Math.round((min + (Math.random() * (max - min))) * shift) / shift;
        }

        else{
            return (min + (Math.random() * (max - min)));
        }
    }

    /**
     * Convert number from source range to new range while maintaining ratio.
     * Explanation:
     *   Range from: [1...value...10]    value  = 5
     *   Range to:   [10...result...100] result = 50
     * @method remapRanges
     * @public
     * @param {Number} value    Number from source range that will be converted to new range.
     * @param {Array} rangeFrom Array with min and max value of source range.
     * @param {Array} rangeTo   Array with min amd max value of new range.
     * @return {Number}         Returns converted number.
     */

    Math.remapRanges = function(value, rangeFrom, rangeTo){
        if (!Array.isArray(rangeFrom) || rangeFrom.length != 2 || rangeFrom[0] == rangeFrom[1]){
            throw new Error("Math.remapRanges: Invalid value of rangeFrom");
            return null;
        }

        if (!Array.isArray(rangeTo) || rangeTo.length != 2 || rangeFrom[0] == rangeFrom[1]){
            throw new Error("Math.remapRanges: Invalid value of rangeTo");
            return null;
        }

        var fromMin = Math.min(rangeFrom[0], rangeFrom[1]);
        var fromMax = Math.max(rangeFrom[0], rangeFrom[1]);

        if(value < fromMin || value > fromMax){
            throw new Error("Math.remapRanges: The number of value is out of rangeFrom");
            return null;
        }

        var toMin = Math.min(rangeTo[0], rangeTo[1]);
        var toMax = Math.max(rangeTo[0], rangeTo[1]);

        return toMin + (value - fromMin) / (fromMax - fromMin) * (toMax - toMin);
    }
}());


(function(){"use strict";var TechnologySupport={};TechnologySupport.uaParser=new UAParser;TechnologySupport.uaParserResut=TechnologySupport.uaParser.getResult();TechnologySupport.os=TechnologySupport.uaParserResut.os;TechnologySupport.device=TechnologySupport.uaParserResut.device;TechnologySupport.browser=TechnologySupport.uaParserResut.browser;TechnologySupport.engine=TechnologySupport.uaParserResut.engine;TechnologySupport.isLinux=TechnologySupport.uaParser.isLinux();var b=TechnologySupport.browser;var bVersion=parseFloat(b.major);var os=TechnologySupport.os;var osVersion=parseFloat(os.version);Object.defineProperty(TechnologySupport,"canvas",{get:function(){var unsupportedBrowser=b.name==TechnologySupport.CHROME&&bVersion<4||b.name==TechnologySupport.ANDROID_BROWSER&&bVersion<4||b.name==TechnologySupport.CHROME_ANDROID&&bVersion<4||b.name==TechnologySupport.FIREFOX&&bVersion<4||b.name==TechnologySupport.IE&&bVersion<11||b.name==TechnologySupport.IE_MOBILE&&bVersion<11||b.name==TechnologySupport.EDGE&&bVersion<12||b.name==TechnologySupport.OPERA&&bVersion<10.1;var unsupportedOS=os.name==TechnologySupport.IOS&&osVersion<6||os.name==TechnologySupport.ANDROID&&osVersion<4||os.name==TechnologySupport.WIN_PHONE&&osVersion<8.1;return!(unsupportedBrowser||unsupportedOS)}});Object.defineProperty(TechnologySupport,"audio",{get:function(){var unsupportedBrowser=b.name==TechnologySupport.CHROME&&bVersion<34||b.name==TechnologySupport.ANDROID_BROWSER&&bVersion<47||b.name==TechnologySupport.CHROME_ANDROID&&bVersion<47||b.name==TechnologySupport.FIREFOX&&bVersion<4||b.name==TechnologySupport.IE&&bVersion<11||b.name==TechnologySupport.IE_MOBILE||b.name==TechnologySupport.EDGE&&bVersion<12||b.name==TechnologySupport.OPERA&&bVersion<11.5;var unsupportedOS=os.name==TechnologySupport.IOS&&osVersion<6||os.name==TechnologySupport.ANDROID&&osVersion<4||os.name==TechnologySupport.WIN_PHONE&&osVersion<8.1;return!(unsupportedBrowser||unsupportedOS)}});Object.defineProperty(TechnologySupport,"backgroundAudio",{get:function(){var unsupportedBrowser=b.name==TechnologySupport.CHROME&&bVersion<34||b.name==TechnologySupport.ANDROID_BROWSER&&bVersion<47||b.name==TechnologySupport.CHROME_ANDROID&&bVersion<47||b.name==TechnologySupport.IE_MOBILE;return!unsupportedBrowser}});Object.defineProperty(TechnologySupport,"audioFormat",{get:function(){var unsupportedMP3=TechnologySupport.isLinux||b.name==TechnologySupport.MAXTHON||b.name==TechnologySupport.OPERA;return unsupportedMP3?TechnologySupport.OGG:TechnologySupport.MP3}});Object.defineProperty(TechnologySupport,"reasonableWebAudioAPI",{get:function(){return(window.AudioContext||window.webkitAudioContext)&&os.name!=TechnologySupport.ANDROID&&b.name!=TechnologySupport.MAXTHON}});Object.defineProperty(TechnologySupport,"blob",{get:function(){var android=os.name==TechnologySupport.ANDROID;var unsupportedBrowser=b.name==TechnologySupport.CHROME&&(android?bVersion<47:bVersion<45)||b.name==TechnologySupport.ANDROID_BROWSER&&(android?bVersion<47:bVersion<47)||b.name==TechnologySupport.CHROME_ANDROID&&(android?bVersion<47:bVersion<47)||b.name==TechnologySupport.FIREFOX&&bVersion<40||b.name==TechnologySupport.IE&&bVersion<11||b.name==TechnologySupport.IE_MOBILE&&bVersion<11||b.name==TechnologySupport.EDGE&&bVersion<12||b.name==TechnologySupport.OPERA&&bVersion<32||b.name==TechnologySupport.SAFARI&&bVersion<8;return!unsupportedBrowser}});Object.defineProperty(TechnologySupport,"audioWithoutUnlock",{get:function(){var requiresUnlock=os.name==TechnologySupport.IOS||os.name==TechnologySupport.ANDROID||os.name==TechnologySupport.WIN_PHONE;return!requiresUnlock}});Object.defineProperty(TechnologySupport,"canvasWorkers",{get:function(){var unsupportedBrowser=b.name==TechnologySupport.CHROME&&bVersion<43||b.name==TechnologySupport.ANDROID_BROWSER&&bVersion<47||b.name==TechnologySupport.CHROME_ANDROID&&bVersion<47||b.name==TechnologySupport.FIREFOX&&bVersion<43||b.name==TechnologySupport.IE||b.name==TechnologySupport.IE_MOBILE||b.name==TechnologySupport.OPERA&&bVersion<30;return!!window.Worker&&!!window.ImageData&&!unsupportedBrowser}});Object.defineProperty(TechnologySupport,"audioLoop",{get:function(){return b.name!=TechnologySupport.IE_MOBILE}});Object.defineProperty(TechnologySupport,"volume",{get:function(){return TechnologySupport.reasonableWebAudioAPI||b.name!=TechnologySupport.MOBILE_SAFARI&&b.name!=TechnologySupport.IOS_SAFARI}});Object.defineProperty(TechnologySupport,"pageVisibility",{get:function(){var propertyName;var eventName;if(typeof document.hidden!=="undefined"){propertyName="hidden";eventName="visibilitychange"}else if(typeof document.mozHidden!=="undefined"){propertyName="mozHidden";eventName="mozvisibilitychange"}else if(typeof document.msHidden!=="undefined"){propertyName="msHidden";eventName="msvisibilitychange"}else if(typeof document.webkitHidden!=="undefined"){propertyName="webkitHidden";eventName="webkitvisibilitychange"}if(propertyName&&typeof document[propertyName]!=="undefined"){return{propertyName:propertyName,eventName:eventName,hidden:document[propertyName]}}return null}});TechnologySupport.MP3="mp3";TechnologySupport.OGG="ogg";TechnologySupport.ANDROID="Android";TechnologySupport.IOS="iOS";TechnologySupport.OSX="Mac OS";TechnologySupport.WIN_PHONE="Windows Phone";TechnologySupport.CHROME="Chrome";TechnologySupport.ANDROID_BROWSER="Android Browser";TechnologySupport.CHROME_ANDROID="Chrome for Android";TechnologySupport.FIREFOX="Firefox";TechnologySupport.IE="IE";TechnologySupport.IE_MOBILE="IEMobile";TechnologySupport.EDGE="Edge";TechnologySupport.OPERA="Opera";TechnologySupport.SAFARI="Safari";TechnologySupport.IOS_SAFARI="iOS Safari";TechnologySupport.MOBILE_SAFARI="Mobile Safari";TechnologySupport.MAXTHON="Maxthon";window.TechnologySupport=TechnologySupport})();
// jQuery plugins {{{

(function($) {
    $.fn.createListItems = function(listItems) {
        /* DOC {{{
            Method for generating html 'option' items for selection list from
            items list.

        }}} */

        // CODE {{{
        return this.each(function(){
            // get reference to the selection list
            var selectionList = $(this);
            // empty the selection list
            selectionList.html("");

            // add all items to the list {{{
            $.each(listItems, function (index, item) {
                selectionList.append($('<option>', {
                    value: item['value'],
                    text : item['title']
                }));
            });
            // }}}
        });
        // CODE }}}
    }

    $.fn.selectValue = function(value) {
        /* DOC {{{
            Method for selecting first item with the specified 'value'.

        }}} */

        // CODE {{{
        return this.each(function(){
            // get reference to the selection list
            var selectionList = $(this);

            // select the first item with matching value
            selectionList.find("option[value=" + value + "]:first")[0].selected = true;
        });
        // CODE }}}
    }

    $.fn.singleClick = function(handler) {
        /* DOC {{{
            Ensures there is only one handler attached to the click event.

        }}} */

        // CODE {{{
        return this.each(function() {
            var element = $(this);
            element.unbind("click");
            element.click(handler);
        });
        // CODE }}}
    }

    $.fn.disable = function() {
        /* DOC {{{
            Dsables the element (removes attached events, adds 'disabled' class
            and property.

        }}} */

        // CODE {{{
        return this.each(function() {
            var element = $(this);

            // get the events attached to the element
            var events = $._data(element.get(0), "events");

            // if there are any click or submit events attached, unbind them now {{{
            if ((typeof events !== 'undefined')
                && ((typeof events.click !== 'undefined') || (typeof events.click !== 'undefined'))) {
                element.unbind('click');
                element.unbind('submit');
            }
            // }}}

            // add the 'disabled' class and property {{{
            element.addClass("disabled");
            element.prop("disabled", true);
            // }}}
        });
        // CODE }}}
    }

    $.fn.enable = function() {
        /* DOC {{{
            Enables the element (remoevs the 'disabled' class and property,
            events are not restored).

        }}} */

        // CODE {{{
        return this.each(function() {
            var element = $(this);
            element.removeClass("disabled");
            element.prop("disabled", false);
        });
        // CODE }}}
    }
})(jQuery);

// add custom 'validator' rules and settings for form processing {{{
// add 'noDefault' validation rule to invalidate fields which the user did not change {{{
jQuery.validator.addMethod("noDefault", function(value, element) {
    return (this.optional(element) || value != $('[name=' + element.name + ']').attr('defaultValue'));
}, "");
// }}}

// add 'birthDate' validation rule to validate birth date input {{{
jQuery.validator.addMethod("birthDate", function(value, element) {
    var form = $(element.form);

    var birthDateMonth = form.find('[name=birthDateMonth]');
    var birthDateYear  = form.find('[name=birthDateYear]');
    var birthDateDay   = form.find('[name=birthDateDay]');

    $(element).data("errorElement", form.find('#error_birthDate'));

    if (birthDateMonth.val() != birthDateMonth.attr('defaultValue')
        && birthDateYear.val() != birthDateYear.attr('defaultValue')
        && birthDateDay.val() != birthDateDay.attr('defaultValue')) {
            return true;
    }

    return false;
}, "");
// }}}

// add 'expiryDate' validation rule to validate birth date input {{{
jQuery.validator.addMethod("expiryDate", function(value, element) {
    var form = $(element.form);

    var expiryDateMonth = form.find('[name=expiresMonth]');
    var expiryDateYear  = form.find('[name=expiresYear]');

    $(element).data("errorElement", form.find('#error_expiryDate'));
    $(element).data("groupElements", [expiryDateYear, expiryDateMonth]);

    if (expiryDateMonth.val() != expiryDateMonth.attr('defaultValue')
        && expiryDateYear.val() != expiryDateYear.attr('defaultValue')) {
            return true;
    }

    return false;
}, "");
// }}}

// override default 'required' error message for form validation
jQuery.validator.messages.required = "";
// }}}
// }}}


// Number prototype extensions {{{
Number.prototype.toMoney = function(decimals, decimalSeparator, thousandsSeparator, ignoreZeroDecimals) {
    /* DOC {{{
        Adds inteligent conversion of a number into 'money' formatted string.

        decimals            : number of decimals to round to
        decimalSeparator    : separator for decimal part
        thousandsSeparator  : separator for thousands part
    }}} */

    // CODE {{{
    // determine number of decimal places
    decimals = isNaN(decimals) ? 2 : decimals;

    // get the number's value
    var value = this;

    // set decimal separator
    decimalSeparator = (typeof decimalSeparator === 'undefined') ? '.': decimalSeparator;

    // set thousands separator
    thousandsSeparator = (typeof thousandsSeparator === 'undefined') ? ',' : thousandsSeparator;

    // determine +- mark
    var sign = (value < 0) ? '-' : '';

    // split the number to main and decimal parts
    var valueParts = (value + '').split('.');

    // extracting the absolute value of the integer part of the number and converting to string
    var mainValue = valueParts[0] + '';

    // get the index of 'thousand' occurence
    var tindex = ((tindex = mainValue.length) > 3) ? tindex % 3 : 0;

    // get the main part adding thousands separator
    var mainValueString = (tindex ? mainValue.substr(0, tindex) + thousandsSeparator : '') + mainValue.substr(tindex).replace(/(\d{3})(?=\d)/g, "$1" + thousandsSeparator);

    // set the default cent value (empty)
    var centValueString = '';

    // process the cent value if requested {{{
    if (decimals > 0) {
        // init cents value
        var centValue = 0;

        // if there is a cent value, process it {{{
        if (valueParts.length > 1) {
            // get the cent value
            centValue = valueParts[1];

            // trim the cent value to the requested decimals length
            centValueString = (centValue + '').substr(0, decimals);
        }
        // }}}

        // fill the remaining decimals with zeros {{{
        if (centValueString.length < decimals) {
            centValueString += ("0000").substr(0, decimals - centValueString.length);
        }
        // }}}

        // construct the final string representation of the cent part
        centValueString = decimalSeparator + centValueString;

        // if ignore zero decimals requested, and cents are zero, clear the cents string {{{
        if(ignoreZeroDecimals && (centValue == 0)) {
            centValueString = "";
        }
        // }}}
    }
    // }}}

    // construct the final string and return it
    return sign + mainValueString + centValueString;
    // CODE }}}
};

Number.prototype.zeroPad = function(places) {
    /* DOC {{{
        Converts a number into a 'zero' padded string.

        places          : required length of the resulting string
    }}} */

    // CODE {{{
    // get the number's value
    var value = this;

    // determine number of zeros to add
    var zero = places - value.toString().length + 1;

    // convert the number to string, pad it with zeros and return it
    return Array(+(zero > 0 && zero)).join("0") + value;
    // CODE }}}
};

// }}}


// class Utils {{{
function Utils() {}

Utils.REDIRECT_ACTION_TYPE_LOGIN        = 0;
Utils.REDIRECT_ACTION_TYPE_OVERLAY      = 1;

Utils.startPlayingGames = function() {
    /* DOC {{{
        Generic method which directs to user to playing a game. This can be
        done either by redirecting the user to 'games' page or if already on
        at game, removing the displayed overlays.

    }}} */

    // CODE {{{
    // if game is not displayed, redirect the user to 'games' page {{{
    if (($("#game").length == 0) && ($("#gameCanvas").length == 0)) {
        location.assign("/en/games");
    }
    // }}}
    // otherwise remove all existing overlays to reveal the game {{{
    else {
        // remove highlight from the main menu
        $("#menu").find(".active").removeClass("active");

        // remove all overlays
        overlayManager.removeAll();
    }
    // }}}
    // CODE }}}
}

Utils.getHostname = function(url) {
    /* DOC {{{
        Determines hostname from the specified url.

        url         : url from which to extract the hostname
    }}} */

    // CODE {{{
    // extract the hostname from url
    var m = url.match(/^http:\/\/[^/]+/);

    // return the hostname (or null if not found)
    return m ? m[0] : null;
    // CODE }}}
}

Utils.setCookie = function(name, value, days) {
    /* DOC {{{
        Stores the cookie with the specified name, value and expiration.

        name            : name of the cookie
        value           : cookie value
        days            : (optional) expiration length in days, if not set will create session cookie
    }}} */

    // CODE {{{
    // ensure there is always value for optional 'days' parameter
    var days = (days == undefined) ? 0: parseInt(days, 10);

    // default expiration string
    var expiration = '';

    // if days are specified, create proper expiration date string {{{
    if(days > 0) {
        // create the date object
        var expirationDate = new Date();

        // set the expiration in the date object
        expirationDate.setTime(expirationDate.getTime() + (days * 24 * 60 * 60 * 1000))

        // create expiration string for the cookie
        expiration = '; expires=' + expirationDate.toGMTString();
    }
    // }}}
    // if spedified days are -1, set expiration date to past so cookie is immediately
    // removed from browser {{{
    else if(days === -1) {
        expiration = '; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
    }
    // }}}

    // save the cookie
    document.cookie = name + "=" + escape(String(value)) + '; path=/' + expiration;
    // CODE }}}
}

Utils.getCookie = function(name) {
    /* DOC {{{
        Retrieves the value for the specified cookie name and returns it.

        name            : name of the cookie
    }}} */

    // CODE {{{
    // initialize the return variable
    var cookieValue = new String();

    // find the cookie {{{
    if(document.cookie.length > 0) {
        // create the cookie identifier
        var cookieName = name + '=';

        // determine starting index of the cookie definition
        var cookieBegin = document.cookie.indexOf(cookieName);

        // if cookie was found, extract its value {{{
        if(cookieBegin > -1) {
            // get starting index for the cookie value
            var valueBegin = cookieBegin + cookieName.length;

            // get the ending index for the cookie value
            var valueEnd = document.cookie.indexOf(";", valueBegin);

            // if were unable to determine cookies end index, fallback to the length of the whole cookie string {{{
            if (valueEnd < valueBegin) {
                valueEnd = document.cookie.length;
            }
            // }}}

            // retrieve the cookie value
            cookieValue = document.cookie.substring(valueBegin, valueEnd);
        }
        // }}}
    }
    // }}}

    // return the cookie value
    return unescape(cookieValue);
    // CODE }}}
}

Utils.hasFlash = function(requiredFlashVersion) {
    /* DOC {{{
        Determines whether the browser has the required flash version
        installed.

        requiredFlashVersion            : flash version to check for
    }}} */

    // CODE {{{
    // get the version numbers {{{
    // get version numbers for the required flash version {{{
    var requiredVersion = new String(requiredFlashVersion).split(".");
    var requiredMajor = Number(requiredVersion[0]);
    var requiredMinor = Number(requiredVersion[1]);
    var requiredRevision = Number(requiredVersion[2]);
    // }}}

    // get version numbers for the client flash version {{{
    var clientVersion = new String(Utils.getFlashVersion()).split(".");
    var clientMajor = Number(clientVersion[0]);
    var clientMinor = Number(clientVersion[1]);
    var clientRevision = Number(clientVersion[2]);
    // }}}
    // }}}

    // if major version is higher any other checks are not necessary so skip them and return true {{{
    if (clientMajor > requiredMajor) {
        return true;
    }
    // }}}
    // if same major versions, check the minor and revision numbers {{{
    else if (clientMajor == requiredMajor) {
        // if minor version is higher any other checks are not necessary so return true {{{
        if (clientMinor > requiredMinor) {
            return true;
        }
        // }}}
        // otherwise check revision {{{
        else if (clientMinor == requiredMinor) {
            // if revision equals or is higher, return true {{{
            if (clientRevision >= requiredRevision) {
                return true;
            }
            // }}}
        }
        // }}}
    }
    // }}}

    // otherwise return false as the client version is too low
    return false;
    // CODE }}}
}

Utils.isFullscreenSupported = function() {
    /* DOC {{{
        Detect if fullscreen method is supported in browser.

    }}} */

    // CODE {{{
    var element = $("body").get(0);

    // if any fullscreen method exists, return true {{{
    if (element.webkitRequestFullScreen) {
        return true;
    } else if (element.mozRequestFullScreen) {
        return true;
    } else if (element.msRequestFullscreen) {
        return true;
    } else if (element.requestFullScreen) {
        return true;
    }
    // }}}

    // return false by default
    return false;
    // CODE }}}
}

Utils.isMobile = function() {
    /* DOC {{{
        Determines whether the client is a mobile device.

    }}} */

    // CODE {{{
    return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
    // CODE }}}
}

Utils.isTouchDevice = function() {
    /* DOC {{{
        TODO: move to technology support class.
        Determines whether the client is a touch device.

    }}} */

    // CODE {{{
    return ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0);
    // CODE }}}
}

Utils.getBrowserScrollSize = function() {
    /* DOC {{{
        Uses jQuery and css to detect and get exact scrollbars sizes of
        browser, using temporary elements and it's css.

    }}} */

    // CODE {{{
    // define css for inner element {{{
    var css = {
        "border":  "none",
        "height":  "200px",
        "margin":  "0",
        "padding": "0",
        "width":   "200px"
    };
    // }}}

    // extend new element with inner css
    var inner = $("<div>").css($.extend({}, css));

    // create outer element, set it's css, add inner div and append it to body {{{
    var outer = $("<div>").css($.extend({
        "left":       "-1000px",
        "overflow":   "scroll",
        "position":   "absolute",
        "top":        "-1000px"
    }, css)).append(inner).appendTo("body");
    // }}}

    // invoke scroll left and top DOM methods {{{
    outer.scrollLeft(1000)
    outer.scrollTop(1000);
    // }}}

    // count horizonal and vertical scroll bars size {{{
    var scrollSize = {
        "height": (outer.offset().top - inner.offset().top) || 0,
        "width": (outer.offset().left - inner.offset().left) || 0
    };
    // }}}

    // remove outer element
    ///outer.remove();

    // return counter scrollbar size definition
    return scrollSize;
    // CODE }}}
}

Utils.getFlashVersionString = function(pluginVersionString) {
    /* DOC {{{
        Determines and returns the flash version number from the string.

    }}} */

    // CODE {{{
    // get flash version out of the version string
    var version = pluginVersionString.match(/[\d]+/g);

    // limit the version length to 3 digits
    // (compatibility between IE and FF)
    version.length = 3;

    // return the version
    return version.join(".");
    // CODE }}}
}

Utils.getFlashVersion = function() {
    /* DOC {{{
        Determines the flash version string for supported browsers

    }}} */

    // CODE {{{
    // initialize variable which will hold the flash version
    var flashVersion = '';

    // every browser except IE supports the plugins container {{{
    if ((navigator.plugins) && (navigator.plugins.length)) {
        // get the plugin object
        var plugin = navigator.plugins['Shockwave Flash'];

        // if the plugin is set, look for description and get the flash version {{{
        if (plugin) {
            if (plugin.description) {
                flashVersion = Utils.getFlashVersionString(plugin.description);
            }
        }
        // }}}
    }
    // }}}
    // if the first failed, next solution is to look up the mimeTypes container {{{
    else if ((navigator.mimeTypes) && (navigator.mimeTypes.length)) {
        // check if the flash MIME type can be found
        var mimeType = navigator.mimeTypes['application/x-shockwave-flash'];

        // if the MIME type was found and plugin is enabled, access the version
        // through MIME type plugin object {{{
        if (mimeType && mimeType.enabledPlugin) {
            flashVersion = Utils.getFlashVersionString(mimeType.enabledPlugin.description);
        }
        // }}}
    }
    // }}}
    // get version from Internet Explorer {{{
    else {
        // get the version from the ActiveX object for Flash plugin 7 and up {{{
        try {
            // try 7 first, since we know we can use GetVariable with it
            var ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.7');
            flashVersion = Utils.getFlashVersionString(ax.GetVariable('$version'));
        }
        // }}}
        // no valid version so try the default ActiveX object {{{
        catch (e) {
            // try the default activeX {{{
            try {
                var ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
                flashVersion = Utils.getFlashVersionString(ax.GetVariable('$version'));
            }
            // }}}
            // no flash {{{
            catch (e) {
                // No flash
            }
            // }}}
        }
        // }}}
    }
    // }}}

    // return the flash version
    return flashVersion;
    // CODE }}}
}

Utils.getFlashWMODE = function() {
    /* DOC {{{
        Determines usable window mode ('wmode') for the flash plugin.

    }}} */

    // CODE {{{
    // for all 'android' devices use 'transparent' wmode {{{
    if (navigator.userAgent.toLowerCase().indexOf('android') != -1) {
        return 'transparent';
    }
    // }}}
    // use 'opaque' for all the others {{{
    else {
        return 'opaque';
    }
    // }}}
    // CODE }}}
}

Utils.getBrowserType = function() {
    /* DOC {{{
        Determines browser type and returns it.

    }}} */

    // CODE {{{
    // default browser type value
    var browserType = 0;

    // MSIE {{{
    if (navigator.appVersion.indexOf("MSIE") != -1) {
        browserType = 1;
    }
    // }}}
    // Opera {{{
    else if (navigator.userAgent.indexOf("Opera") != -1) {
        browserType = 2;
    }
    // }}}
    // Chrome {{{
    else if (navigator.userAgent.indexOf("Chrome") != -1) {
        browserType = 4;
    }
    // }}}
    // Safari {{{
    else if (navigator.userAgent.indexOf("Safari") != -1) {
        browserType = 3;
    }
    // }}}
    // Firefox {{{
    else if(navigator.userAgent.indexOf('Firefox') != -1) {
        browserType = 5;
    }
    // }}}

    // return the browser type
    return browserType;
    // CODE }}}
}

Utils.insertRegistrationButton = function() {
    /* DOC {{{
        Inserts a registration button to the page if the page supports it and
        if user is not logged in.

    }}} */

    // CODE {{{
    // insert the registration for not logged in users and if button containers are present {{{
    if ((typeof initData === "undefined") || (window.initData['userStatus']['userType'] == 0)) {
        // get references to registration_button containers
        var buttonContainers = $(".registration_button");

        // get references to simple_registration_button containers
        var simpleButtonContainers = $(".simple_registration_button");

        if (buttonContainers.length > 0) {
            Utils._insertRegistrationButton(buttonContainers, true);
        }

        if (simpleButtonContainers.length > 0) {
            Utils._insertRegistrationButton(simpleButtonContainers, false);
        }
    }
    // }}}
    // CODE }}}
}

Utils._insertRegistrationButton = function(buttonContainers, showInstantPlay) {
    var HTML = '';

    if (showInstantPlay) {
        // setup animation callbacks for instant play arrow {{{
        window.instantPlayOn = function() {
            $("#instant_play").animate({
               marginLeft: "+=15"
            }, 100);
            $("#instant_play").animate({
               marginLeft: "-=10"
            }, 100);
            $("#instant_play").animate({
               marginLeft: "+=10"
            }, 100);
            $("#instant_play").animate({
               marginLeft: "-=5"
            }, 100);
        };

        window.instantPlayOff = function() {
            $("#instant_play").animate({
               marginLeft: "-=10"
            }, 100);
        };
        // }}}

        // button html {{{
        HTML = '' +
                '<a href="#">' +
                '    <div id="join_now" class="zoomButton" overCallback="instantPlayOn" outCallback="instantPlayOff" style="position: absolute; margin-top: 0px; margin-left: 0px; width: auto; display: none;">' +
                '        <img width="100%" src="//media.freeslotsland.eu/en/file/image/home/buttonJoinNowOff.png?build=201904161200">' +
                '    </div>' +
                '</a>';
                '' +
                '<div id="instant_play" style="position: absolute; margin-top: 50px; margin-left: 188px; display: none;">' +
                '    <img src="//media.freeslotsland.eu/en/file/image/home/buttonInstantPlay.png?build=201904161200">' +
                '</div>';
        // }}}
    } else {
        // button html {{{
        HTML = '' +
                '<a href="#">' +
                '    <div id="join_now" class="zoomButton" style="position: absolute; margin-top: 0px; margin-left: 0px; width: auto; display: none;">' +
                '        <img width="100%" src="//media.freeslotsland.eu/en/file/image/home/buttonJoinNowOff.png?build=201904161200">' +
                '    </div>' +
                '</a>';
                '' +
                '<div id="instant_play" style="position: absolute; margin-top: 50px; margin-left: 188px; display: none;">' +
                '    <img src="//media.freeslotsland.eu/en/file/image/home/buttonInstantPlay.png?build=201904161200">' +
                '</div>';
        // }}}
    }

    // insert the registration button into containers
    buttonContainers.html(HTML);

    // setup mouse events {{{
    buttonContainers.find("a:first").singleClick(
        function() {
            overlayManager.load('registration', 'https://www.freeslotsland.eu/en/registrationOverlay/json');
        }
    );
    // }}}

    // setup roll over on main button {{{
    $(".zoomButton").hover(
        function() {
            $(this).zoomIn();

            var image = $(this).find("img");
            image.attr("src", image.attr("src").replace("Off", "On"));
        },
        function() {
            $(this).zoomOut();

            var image = $(this).find("img");
            image.attr("src", image.attr("src").replace("On", "Off"));
        }
    );
    // }}}

    // show the 'join_now' button
    $('#join_now').fadeIn();

    if (showInstantPlay) {
        // show the 'instant_play' button
        $('#instant_play').delay(300).fadeIn();
    }
    // }}}
    // CODE }}}
}

Utils.insertLobbyButton = function() {
    /* DOC {{{
        Inserts a lobby button to the page if the page supports it and
        if user is logged in.

    }}} */

    // CODE {{{
    // get references to lobby button containers
    var buttonContainers = $(".lobby_button");

    // insert the registration for not logged in users and if button containers are present {{{
    if (((typeof initData !== "undefined") && (window.initData['userStatus']['userType'] != 0)) && (buttonContainers.length > 0)) {
        // button html {{{
        var HTML = '' +
                '<a href="#">' +
                '    <div id="lobby_button" class="zoomButton"  style="position: absolute; margin-top: 0px; margin-left: 0px; width: auto; display: none;">' +
                '        <img width="100%" src="//media.freeslotsland.eu/en/file/image/home/buttonLobbyOff.png?build=201904161200">' +
                '    </div>' +
                '</a>';
        // }}}


        // insert the registration button into containers
        buttonContainers.html(HTML);

        // setup mouse events {{{
        buttonContainers.find("a:first").singleClick(
            function() {
                location = "//www.freeslotsland.eu/en/user/lobby";
            }
        );
        // }}}

        // setup roll over on main button {{{
        $(".zoomButton").hover(
            function() {
                $(this).zoomIn();

                var image = $(this).find("img");
                image.attr("src", image.attr("src").replace("Off", "On"));
            },
            function() {
                $(this).zoomOut();

                var image = $(this).find("img");
                image.attr("src", image.attr("src").replace("On", "Off"));
            }
        );
        // }}}

        // show the 'join_now' button
        $('#lobby_button').fadeIn();
    }
    // }}}
    // CODE }}}
}


// bonus timer properties {{{
var bonusTimerInfoTextId = 0;
var clockHandId = 0;
var countdownStarted = false;
var countdownSeconds;
var targetBonusId;
// }}}

// animations timeout handlers {{{
var startClaimLoopTimeout;
var bonusCodeLoopTimeout;
var bonusCodeHideTimeout;
var bonusTextLoopTimeout;
var bonusTextHideTimeout;
var claimLoopTimeout;
var claimSignTimeout;
var clockStartTimeout;
var clockHandLoopTimeout;
var mainLoopTimeout;
var newClockLoopTimeout;
var newTimerInfoTextLoopTimeout;
var onTimerAnimationFinishTimeout;
var startTextShowTimeout;
var textStartTimeout;
var timerInfoTextTimeout;
var youWonHideClockTextTimeout;
// }}}

Utils.insertBonusTimer = function() {
    /* DOC {{{
        Inserts a registration button to the page if the page supports it and
        if user is not logged in.

    }}} */

    // CODE {{{
    // get references to bonus timer container
    var buttonContainers = $(".bonus_timer_button");

    // insert the registration for not logged in users and if button containers are present {{{
    if (((typeof initData === "undefined") || (window.initData['userStatus']['userType'] == 0)) && (buttonContainers.length > 0)) {

        // setup animation callbacks for instant play arrow {{{
        window.onTimerRollOver = function() {
            $("#timer_info_text_container").animate({
               marginLeft: "+=15"
            }, 100);
            $("#timer_info_text_container").animate({
               marginLeft: "-=10"
            }, 100);
            $("#timer_info_text_container").animate({
               marginLeft: "+=10"
            }, 100);
            $("#timer_info_text_container").animate({
               marginLeft: "-=15"
            }, 100);
        };

        // button html {{{
        var HTML = '' +
                '<a href="#">' +
                '<div class="timerZoomContainer">' +
                '    <div id="bonus_timer" style="position: absolute; margin-top: 0px; margin-left: 0px; width: auto; display: none;">' +
                '        <img id="timerImage" width="100%" src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/clockOff.png?build=201904161200" />' +
                '    </div>' +
                '    <div id="inner_clock_graphics">' +
                '       <div id="clock_markers" style="position: absolute; top: 83px; margin-left: 31px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/clockMarkers.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="clock_hand_0" style="position: absolute; top: 95px; margin-left: 89px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/clockHand_0.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="clock_hand_1" style="position: absolute; top: 95px; margin-left: 89px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/clockHand_1.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="clock_hand_2" style="position: absolute; top: 95px; margin-left: 89px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/clockHand_2.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="clock_hand_3" style="position: absolute; top: 95px; margin-left: 89px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/clockHand_3.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="clock_hand_4" style="position: absolute; top: 95px; margin-left: 89px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/clockHand_4.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="start_clock_sign" style="position: absolute; top: 111px; margin-left: 46px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/startClockText.png?build=201904161200" />' +
                '       </div>' +
                '    </div>' +
                '   <div id="clock_win_signs">' +
                '       <div id="you_won_clock_sign" style="position: absolute; top: 113px; margin-left: 46px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/youWonClockText.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="bonus_clock_sign_0" style="position: absolute; top: 105px; margin-left: 45px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/bonusClockWinText_0.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="bonus_clock_sign_1" style="position: absolute; top: 105px; margin-left: 45px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/bonusClockWinText_1.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="bonus_clock_sign_2" style="position: absolute; top: 105px; margin-left: 45px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/bonusClockWinText_2.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="bonus_clock_sign_3" style="position: absolute; top: 105px; margin-left: 45px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/bonusClockWinText_3.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="bonus_code_sign_0" style="position: absolute; top: 125px; margin-left: 41px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/bonusCode_0.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="bonus_code_sign_1" style="position: absolute; top: 125px; margin-left: 41px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/bonusCode_1.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="bonus_code_sign_2" style="position: absolute; top: 125px; margin-left: 41px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/bonusCode_2.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="bonus_code_sign_3" style="position: absolute; top: 125px; margin-left: 41px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/bonusCode_3.png?build=201904161200" />' +
                '       </div>' +
                '       <div id="claim_here_clock_sign" style="position: absolute; top: 107px; margin-left: 43px; display: none;">' +
                '           <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/claimHereClockText.png?build=201904161200" />' +
                '       </div>' +
                '   </div>' +
                '</div>' +
                '</a>' +
                '<div id="timer_info_text_container">' +
                '   <div id="timer_info_text_0" style="position: absolute; top: 0px; margin-left: 188px; display: none;">' +
                '       <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/infoText_0.png?build=201904161200" />' +
                '   </div>' +
                '   <div id="timer_info_text_1" style="position: absolute; top: 55px; margin-left: 188px; display: none;">' +
                '       <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/infoText_1.png?build=201904161200" />' +
                '   </div>' +
                '   <div id="timer_info_text_2" style="position: absolute; top: 45px; margin-left: 188px; display: none;">' +
                '       <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/infoText_2.png?build=201904161200" />' +
                '   </div>' +
                '</div>' +
                '<div id="bonus_loading_text_container" style="display: none;">' +
                '   <div id="bonus_loading_text" style="position: absolute; top: 55px; margin-left: 188px;">' +
                '       <img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/bonusLoadingText.png?build=201904161200" />' +
                '   </div>' +
                '</div>' +
                '<div id="try_again_text_container" style="display: none;">' +
                '   <div id="try_again_text" style="position: absolute; top: 0px; margin-left: 205px;">' +
                '       <a href="#" onclick="Utils._startNewBonusCountdown()"><img src="//media.freeslotsland.eu/en/file/image/home/bonusTimer/tryAgainText.png?build=201904161200" /></a>' +
                '   </div>' +
                '</div>' +
                '<div id="countdown_text_container" style="display: none;">' +
                '   <div id="countdown_text" style="font-size: 48px; color: #fdfdfe; text-align: center; width: 150px; height: 48px; line-height: 48px; position: absolute; margin-top: 119px; left: 20px;">' +
                '       <div id="countdown_value" style="pointer-events: none;">' +
                '           1:00' +
                '       </div>' +
                '   </div>' +
                '</div>';

        // }}}

        // insert the registration button into containers
        buttonContainers.html(HTML);

        // setup mouse events {{{
        buttonContainers.find("a:first").singleClick(
            function() {
                // invoke countdown animation start
                Utils.startBonusCountdown();
            }
        );
        // }}}

        // setup roll over on main button {{{
        $(".timerZoomContainer").hover(
            function() {
                // do not allow roll over when bonus countdown has started {{{
                if (countdownStarted == true) {
                    return;
                }
                // }}}

                // invoke in timer roll over method
                onTimerRollOver();

                // clock image reference
                var image = $('#timerImage');

                // replace timer clock image with roll over image
                image.attr("src", image.attr("src").replace("Off", "On"));
            },
            function() {
                // do not allow roll over when bonus countdown has started {{{
                if (countdownStarted == true) {
                    return;
                }
                // }}}

                // clock image reference
                var image = $('#timerImage');

                // replace timer clock image with roll out image
                image.attr("src", image.attr("src").replace("On", "Off"));
            }
        );
        // }}}

        // show the bonus timer, it's content and info text container {{{
        $('#bonus_timer').fadeIn();
        $('#timer_info_text_' + bonusTimerInfoTextId).delay(300).fadeIn();
        $('#clock_hand_0').delay(300).fadeIn();
        $('#clock_markers').delay(300).fadeIn();
        $('#timer_info_text_container').delay(300).fadeIn();
        // }}}

        // reset the timeouts {{{
        clearTimeout(clockStartTimeout);
        clearTimeout(textStartTimeout);
        // }}}

        // start clock hand tick intro animation initial timeout
        clockStartTimeout = setTimeout("Utils.setupClockHandIntroLoop()", 1000);

        // start info text loop initial timeout
        textStartTimeout = setTimeout("Utils.setupTimerInfoTextLoop()", 5000);
    }
    // }}}
    // CODE }}}
}

Utils.resetAllBonusTimerTimeouts = function() {
    /* DOC {{{
        Resets all timeouts use in bonus timer.

    }}} */

    // CODE {{{
    clearTimeout(youWonHideClockTextTimeout);
    clearTimeout(bonusTextLoopTimeout);
    clearTimeout(bonusCodeLoopTimeout);
    clearTimeout(bonusCodeHideTimeout);
    clearTimeout(startClaimLoopTimeout);
    clearTimeout(claimSignTimeout);
    clearTimeout(claimLoopTimeout);
    clearTimeout(newClockLoopTimeout);
    clearTimeout(onTimerAnimationFinishTimeout);
    clearTimeout(timerInfoTextTimeout);
    clearTimeout(newClockLoopTimeout);
    clearTimeout(newTimerInfoTextLoopTimeout);
    clearTimeout(clockStartTimeout);
    clearTimeout(textStartTimeout);
    clearTimeout(mainLoopTimeout);
    clearTimeout(startTextShowTimeout);
    clearTimeout(clockHandLoopTimeout);
    // CODE }}}
}

Utils.startBonusCountdown = function() {
    /* DOC {{{
        Starts '1 minute countdown' animation on timer. Hides graphics, and
        destroy animation timeout of previous animation, shows the 'bonus is
        loading' info text.

    }}} */

    // CODE {{{
    // invoke all timeouts reset
    this.resetAllBonusTimerTimeouts();

    // bonus timer button reference
    var buttonContainers = $(".bonus_timer_button");

    // setup mouse events {{{
    buttonContainers.find("a:first").singleClick(
        function() {}
    );
    // }}}

    // hide all bonus win and bonus code signs {{{
    for(var a = 0; a < 4; a++) {
        $(("#bonus_clock_sign_" + a)).hide();
        $(("#bonus_code_sign_" + a)).hide();
    }
    // }}}

    // hide previous graphics {{{
    $('#inner_clock_graphics').delay(100).fadeOut(200);
    $('#timer_info_text_container').delay(200).fadeOut(200);
    // }}}

    // show countdown animation graphics {{{
    $('#bonus_loading_text_container').delay(800).fadeIn();
    $('#countdown_text_container').delay(800).fadeIn();
    // }}}

    // set timer countdown time in seconds
    countdownSeconds = 60;

    // start the countdown loop (1s for first sec, 400ms for fade in delay)
    setTimeout("Utils._countdownLoop()", 1400);

    // set countdown has started flag
    countdownStarted = true;
    // CODE }}}
}

Utils._startNewBonusCountdown = function() {
    /* DOC {{{

    }}} */

    // CODE {{{
    // invoke all timeouts reset
    this.resetAllBonusTimerTimeouts();

    // do now allow when countdown has allready started - double click prevention {{{
    if (countdownStarted == true) {
        return;
    }
    // }}}

    // set countdown has started flag
    countdownStarted = true;

    // set initial countdown value text
    $('#countdown_value').html('1:00');

    // show the 'bonus is loading' info text
    $('#bonus_loading_text_container').delay(500).fadeIn();

    // hide previous (win) animation graphics {{{
    $('#try_again_text_container').fadeOut();
    $('#clock_win_signs').fadeOut();
    $('#you_won_clock_sign').fadeOut();
    $('#claim_here_clock_sign').fadeOut();
    // }}}

    // hide all bonus win and bonus code signs {{{
    for(var a = 0; a < 4; a++) {
        $(("#bonus_clock_sign_" + a)).hide();
        $(("#bonus_code_sign_" + a)).hide();
    }
    // }}}

    // show the countdown animation container
    $('#countdown_text_container').delay(500).fadeIn();

    // set timer countdown time in seconds
    countdownSeconds = 60;

    // start the countdown loop (1s for first sec, 400ms for fade in delay)
    setTimeout("Utils._countdownLoop()", 1400);
    // CODE }}}
}

Utils._countdownLoop = function() {
    /* DOC {{{
        Time countdown animation runtime loop method. Counts down each second
        and displays the current time in container. When the countdown is
        finished, hide the 'bonus is loading' info text, displays 'try again
        info text', and sets timeout to show the randomly selected bonus.

    }}} */

    // CODE {{{
    // decrease the seconds counter
    countdownSeconds--;

    // init formatted value holder
    var formatted = countdownSeconds;

    // format the seconds to '00' format {{{
    if (countdownSeconds < 10) {
        formatted = "0" + countdownSeconds;
    }
    // }}}

    // init final countdown time string - '0:00' format
    var finalString = "0:" + formatted;

    // show the current time in the container
    $('#countdown_value').html(finalString);

    // when countdown finished hide the counter, info text, show the try again
    // info text, and invoke to select random win {{{
    if (countdownSeconds == 0) {
        // reset countdown has started flag
        countdownStarted = false;

        // hide countdown text container
        $('#countdown_text_container').fadeOut();
        // hide 'bonus is loading' info text
        $('#bonus_loading_text_container').fadeOut();
        // show 'try again' info text
        $('#try_again_text_container').delay(500).fadeIn();

        // randomly select the target bonus
        targetBonusId = Math.floor(Math.random() * 4);

        // reset the timeout
        clearTimeout(mainLoopTimeout);

        // invoke to start random bonus won animation
        mainLoopTimeout = setTimeout("Utils.showRandomBonusWonLoop()", 500);

        // abort the loop
        return;
    }
    // }}}

    // set 1s timeout for next loop
    setTimeout("Utils._countdownLoop()", 1000);
    // CODE }}}
}

Utils.setupClockHandIntroLoop = function() {
    /* DOC {{{
        Clock hand 'tick' intro animation loop. Counts visually 5 seconds on the clock.

    }}} */

    // CODE {{{
    // abort the loop when 5th loop reached
    if (clockHandId == 4) {
        return;
    }

    // hide current hand image
    $('#clock_hand_' + clockHandId).hide();

    // increase the steps counter
    clockHandId++;

    // set timeout to show the 'start here' sign when the animation is almost finished {{{
    if (clockHandId == 3) {
        clearTimeout(startTextShowTimeout);
        startTextShowTimeout = setTimeout("Utils.showClockStartHereSign()", 1000);
    }
    // }}}

    // show current hand image
    $('#clock_hand_' + clockHandId).show();

    // reset the timeout
    clearTimeout(clockHandLoopTimeout);

    // set next step timeout
    clockHandLoopTimeout = setTimeout("Utils.setupClockHandIntroLoop()", 1000);
    // CODE }}}
}

Utils.showRandomBonusWonLoop = function() {
    /* DOC {{{
        Selects and displays random bonus win. Starts claim here and bonus sign
        animation loop, and sets timer button on release event, to reload site,
        and sends parameters to open registration overlay. Also adds bonus
        campaign id in the request.

    }}} */

    // CODE {{{
    // invoke all timeouts reset
    this.resetAllBonusTimerTimeouts();

    // show ht win signs container
    $('#clock_win_signs').show();

    // show the you won clock sign
    $('#you_won_clock_sign').fadeIn();

    // start you won text show and hide timeout
    youWonHideClockTextTimeout = setTimeout("Utils._hideYouWonSign()", 1400);

    // start timeout to show bonus win text
    bonusTextLoopTimeout = setTimeout("Utils._showBonusWonText()", 1800);
    bonusTextHideTimeout = setTimeout("Utils._hideBonusWonText()", 4500);

    // start timeout to show bonus code text
    bonusCodeLoopTimeout = setTimeout("Utils._showBonusCodeText()", 4900);
    bonusCodeHideTimeout = setTimeout("Utils._hideBonusCodeText()", 8000);

    // start timeout to start claim here loop animation
    startClaimLoopTimeout = setTimeout("Utils.startClaimHereLoop()", 8200);

    // bonus timer button reference
    var buttonContainers = $(".bonus_timer_button");

    // overwrite the campaign ID cookie
    Utils.setCookie("p", bonusCampaignIds[targetBonusId], 30);

    // setup the claim here mouse event - invoke to reload and open
    // registration manager, sending the campaign id {{{
    buttonContainers.find("a:first").singleClick(
        function() {
            location = "//www.freeslotsland.eu/?d=RegistrationFullMember&p=" + bonusCampaignIds[targetBonusId];
        }
    );
    // }}}
    // CODE }}}
}

Utils.startClaimHereLoop = function() {
    /* DOC {{{
        Claim here loop animation start. Hides the bonus won text, and sets
        timeouts to display claim here sign and next animation loop step.

    }}} */

    // CODE {{{
    // reset the timeouts {{{
    clearTimeout(claimSignTimeout);
    clearTimeout(claimLoopTimeout);
    // }}}

    // start timeout to show claim here sign
    claimSignTimeout = setTimeout("Utils._showClaimSign()", 300);

    // set timeout to next claim here animation stop
    claimLoopTimeout = setTimeout("Utils._hideClaimSign()", 2500);
    // CODE }}}
}

Utils._showClaimSign = function() {
    /* DOC {{{
        Fades in the claim here sign.

    }}} */

    // CODE {{{
    // reset the timeout
    clearTimeout(claimSignTimeout);

    // fade in the container
    claimSignTimeout = $('#claim_here_clock_sign').fadeIn(200);
    // CODE }}}
}

Utils._hideYouWonSign = function() {
    /* DOC {{{
        Hides you won sign.

    }}} */

    // CODE {{{
    // reset the timeout
    clearTimeout(youWonHideClockTextTimeout);

    // fade out the container
    $('#you_won_clock_sign').fadeOut(200);
    // CODE }}}
}

Utils._showBonusWonText = function() {
    /* DOC {{{
        Shows the bonus won text (the randomly selected one).

    }}} */

    // CODE {{{
    // reset the timeout
    clearTimeout(bonusTextLoopTimeout);

    // fade in the container
    $('#bonus_clock_sign_' + targetBonusId).fadeIn(200);
    // CODE }}}
}

Utils._hideBonusWonText = function() {
    /* DOC {{{
        Hides current bonus won text (the randomly selected one).

    }}} */

    // CODE {{{
    // reset the timeout
    clearTimeout(bonusTextHideTimeout);

    // fade in the container
    $('#bonus_clock_sign_' + targetBonusId).fadeOut(200);
    // CODE }}}
}

Utils._showBonusCodeText = function() {
    /* DOC {{{
        Fades in the bonus code sign.

    }}} */

    // CODE {{{
    // reset the timeout
    clearTimeout(bonusCodeLoopTimeout);

    // fade in the container
    $('#bonus_code_sign_' + targetBonusId).fadeIn(200);
    // CODE }}}
}

Utils._hideBonusCodeText = function() {
    /* DOC {{{
        Fades out the bonus code sign.

    }}} */

    // CODE {{{
    // reset the timeout
    clearTimeout(bonusCodeHideTimeout);

    // fade in the container
    $('#bonus_code_sign_' + targetBonusId).fadeOut(200);
    // CODE }}}
}

Utils._hideClaimSign = function() {
    /* DOC {{{
        Hides claim here sign. Loops whole random bonus win animation.

    }}} */

    // CODE {{{
    // hide the claim here sign
    $('#claim_here_clock_sign').fadeOut(200);

    // reset the timeouts
    clearTimeout(claimLoopTimeout);

    // invoke to start random bonus won animation
    mainLoopTimeout = setTimeout("Utils.showRandomBonusWonLoop()", 500);
    // CODE }}}
}

Utils.startNewClockLoop = function() {
    /* DOC {{{
        Starts new clock hand tick intro animation loop.

    }}} */

    // CODE {{{
    // reset the timeout
    clearTimeout(newClockLoopTimeout);

    // set the timeout
    newClockLoopTimeout = setTimeout("Utils.setupClockHandIntroLoop()", 1000);
    // CODE }}}
}

Utils.showClockStartHereSign = function() {
    /* DOC {{{
        Shows the 'start here' sign on the clock.

    }}} */

    // CODE {{{
    // fade in the container
    $('#start_clock_sign').fadeIn();
    // CODE }}}
}

Utils.setupTimerInfoTextLoop = function() {
    /* DOC {{{
        Starts info text loop. Used when clock intro animation is looping.
        Displays three info texts - looped.

    }}} */

    // CODE {{{
    // hide previous info text
    $('#timer_info_text_' + bonusTimerInfoTextId).fadeOut();

    // increase the info text steps counter
    bonusTimerInfoTextId++;

    // when three info texts display, reset the cloop at the start {{{
    if (bonusTimerInfoTextId > 2) {
        // reset the info text if
        bonusTimerInfoTextId = 0;

        // reset clock hand animation id
        clockHandId = 0;

        // fade in the initial info text
        $('#timer_info_text_' + bonusTimerInfoTextId).delay(500).fadeIn();

        // invoke on timer animation finished, to start new clock animation loop {{{
        clearTimeout(onTimerAnimationFinishTimeout);
        onTimerAnimationFinishTimeout = setTimeout("Utils.onTimerInitAnimationFinish()", 200);
        // }}}

        // abort the loop
        return;
    }
    // }}}

    // fade in the current info text
    $('#timer_info_text_' + bonusTimerInfoTextId).delay(400).fadeIn();

    // set 3s loop to display next info text {{{
    clearTimeout(timerInfoTextTimeout);
    timerInfoTextTimeout= setTimeout("Utils.setupTimerInfoTextLoop()", 3000);
    // }}}
    // CODE }}}
}

Utils.onTimerInitAnimationFinish = function() {
    /* DOC {{{
        Invoked when all timer intro animations are finished. Hides the start
        here sign, resets the clock hand and starts new clock hand tick
        animation, and bonus info texts loops.

    }}} */

    // CODE {{{
    // hide the start here sign
    $('#start_clock_sign').fadeOut();

    // reset the clock hand {{{
    $('#clock_hand_4').delay(200).hide();
    $('#clock_hand_0').delay(200).show();
    // }}}

    // reset the clock hand id
    clockHandId = 0;

    // reset the timeouts {{{
    clearTimeout(newClockLoopTimeout);
    clearTimeout(newTimerInfoTextLoopTimeout);
    // }}}

    // set timeout to start new clock loop
    newClockLoopTimeout = setTimeout("Utils.startNewClockLoop()", 800);

    // set timeout to start new info texts loop
    newTimerInfoTextLoopTimeout= setTimeout("Utils.setupTimerInfoTextLoop()", 4800);
    // CODE }}}
}

Utils.pageTracker = function(pageURI) {
    /* DOC {{{
        Creates the specified page tracker for google analytics.

        pageURI         : page to track
    }}} */

    // CODE {{{
    // initialize variable for the final URI to track
    var trackURI = pageURI;

    // try to parse the page URI (removing domain and query parameters) {{{
    try {
        // parse the apge URI {{{
        var re = new RegExp('^(?:htt)+(?:p|ps)+(?:\://)+(?:[^/])+(.*)$', 'mi');
        trackURI = pageURI.match(re)[1].split("?")[0];
        // }}}

        // if the trackURI is empty string, track root page view {{{
        if (trackURI == "") {
            trackURI = "/";
        }
        // }}}
    }
    // }}}
    // otherwise fail silently {{{
    catch (e) {
    }
    // }}}

    // track the uri {{{
    try {
        // set the tracking account and track the page view {{{
        window._gaq = window._gaq || [];
        window._gaq.push(['_setAccount', 'UA-221160-6']);
        window._gaq.push(['_trackPageview', trackURI]);
        // }}}
    }
    // }}}
    // otherwise fail silently {{{
    catch (e) {
    }
    // }}}
    // CODE }}}
}

Utils.eventTracker = function(category, action, label, value) {
    /* DOC {{{
        Creates the event tracker for google analytics.

        category            : event category
        action              : event action
        label               : optional action label
        value               : optional action value (int)
    }}} */

    // CODE {{{
    // create the event tracking request
    var trackEvent = ['_trackEvent', category, action];

    // if label is defined, add it to the event data {{{
    if (typeof label !== "undefined") {
        trackEvent.push(label);
    }
    // }}}

    // if value is defined, add it to the event data {{{
    if (typeof value !== "undefined") {
        trackEvent.push(value);
    }
    // }}}

    // try to insert the tracker definition {{{
    try {
        window._gaq = window._gaq || [];
        window._gaq.push(['_setAccount', 'UA-221160-6']);
        window._gaq.push(trackEvent);
    }
    // }}}
    // otherwise fail silently {{{
    catch (e) {
    }
    // }}}
    // CODE }}}
}

Utils.chatMonitor = function(additionalData) {
    /* DOC {{{
        Function for monitoring user's movement accross the page elements and
        reporting it to the LiveChat api.

        additionalData      : auxiliary data to include in the monitor
    }}} */

    // CODE {{{
    // abort if LC_API is not available yet {{{
    if (typeof LC_API === "undefined") {
        return;
    }
    // }}}

    // assume there's no overlay displayed
    var overlayName = " ";

    // get the current overlay object
    var overlay = overlayManager.getCurrentOverlay();

    // if an overlay is displayed, udpate the overlay name {{{
    if (typeof overlay !== "undefined") {
        overlayName = overlay.data('overlayName');
    }
    // }}}

    // prepare the default chat monitoring data {{{
    var chatVariables = [
        {
            name    : 'login',
            value   : initData['user']['login']
        },
        {
            name    : 'name',
            value   : initData['user']['name']
        },
        {
            name    : 'VIPLevel',
            value   : initData['user']['VIPLevel']
        },
        {
            name    : 'ip',
            value   : initData['user']['ip']
        },
        {
            name    : 'origin',
            value   : initData['user']['origin']
        },
        {
            name    : 'overlay',
            value   : overlayName
        }
    ];
    // }}}

    // if additional data were provided, add them {{{
    if (typeof additionalData !== "undefined") {
        chatVariables = chatVariables.concat(additionalData);
    }
    // }}}

    // Live Chat can fail {{{
    try {
        // update the chat monitor
        LC_API.set_custom_variables(chatVariables);
    } catch (e) {
    }
    // }}}
    // CODE }}}
}

Utils.createCallback = function(callbackFunction) {
    /* DOC {{{
        Creates an anomymous function from the passed parameters and returns
        it.

        callbackFunction        : function to call when the callback is invoked
    }}} */

    // CODE {{{
    // intialize parameters container
    var callbackParameters = new Array();

    // if additional parameters are set, conver them to array {{{
    if (arguments[1] != undefined) {
        callbackParameters = Array.prototype.slice.call(arguments, 1);
    }
    // }}}

    // return the anonymous callback function {{{
    return (function () {
        callbackFunction.apply(null, callbackParameters);
        return false;
    });
    // }}}
    // CODE }}}
}

Utils.showLogin = function() {
    /* DOC {{{
        Shows the 'login' overlay.

    }}} */

    // CODE {{{
    // if login overlay is requested on non secured page, redirect to https page and show
    // login overlay there {{{
    if (document.location.protocol !== "https:") {
        Utils.redirectWithAction(Utils.REDIRECT_ACTION_TYPE_LOGIN);
        return;
    }
    // }}}

    // tracke the login page hit
    Utils.pageTracker("/loginHit");

    // remove any existing login or registration overlays {{{
    overlayManager.removeByName("loginOverlay");
    overlayManager.removeByName("registrationSuccess");
    // }}}

    // get the last used login value from cookies
    var loginValue = Utils.getCookie("__LAST_USER_NAME");

    // prepare the HTML for the overlay {{{
    var loginForm_HTML= '' +
    '<div class="login generic_form_container">' +
    '<div class="form_block_header"><h3>[UNKNOWN TRANSLATABLE TEXT ID (PAGE:LOGIN:ALREADY_MEMBER)]</h3></div>' +
    '<div class="overlay_content_blocks">' +
    '   <a href="#"><div class="close_button"></div></a>' +
    '   <div class="form_label_container">' +
    '       [UNKNOWN TRANSLATABLE TEXT ID (PAGE:LOGIN:HEADER)]' +
    '   </div>' +
    '   <form id="login_form" action="https://www.freeslotsland.eu/en/user/doLogin/json" method="POST">'+
    '       <div class="form_row">' +
    '           <label for="login" class="required">Account Name</label>' +
    '           <input type="text" id="login" name="login" tabindex="1" class="required" minlength="3" value="' + loginValue + '"/>' +
    '       </div>' +
    '       <div class="form_row">' +
    '           <label for="password" class="required">Password</label>' +
    '           <input type="password" id="password" name="password" tabindex="2" class="required" minlength="5"/>' +
    '       </div>' +
    '       <div class="additional_form_link"><a href="#" dynamic="passwordRecoveryRequest" overlay="https://www.freeslotsland.eu/en/user/passwordRecoveryRequest/json">[UNKNOWN TRANSLATABLE TEXT ID (PAGE:LOGIN:FORGOT_PASSWORD)]</a></div>' +
    '       <div class="form_row">' +
    '       </div>' +
    '       <div style="margin-left: 115px; padding-bottom: 40px; padding-top: 10px; width: 300px;">' +
    '           <input type="radio" id="freePlay" name="playMode" value="2" tabindex="3" checked/>' +
    '           <label for="freePlay" class="labelRadioButton">[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:REAL_PLAY:LABEL)]</label>' +
    '           <input type="radio" id="realPlay" name="playMode" value="1" tabindex="4"/>' +
    '           <label for="realPlay" class="labelRadioButton">[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:FREE_PLAY:LABEL)]</label>' +
    '       </div>' +
    '       <div class="form_row">' +
    '       </div>' +
    '       <input type="submit" value="Log In" tabindex="5"/>'+
    '   </form>'+
    '   <div style="position: absolute; right: 20px; bottom: 20px;">' +
    '       <img src="//media.freeslotsland.eu/en/file/image/secureLogo.png?build=201904161200">' +
    '   </div>' +
    '</div>'+
    '<div class="clear"></div>' +
    '<div class="form_block_header"><h3>[UNKNOWN TRANSLATABLE TEXT ID (PAGE:LOGIN:NEW_MEMBER)]</h3></div>' +
    '<div class="overlay_content_blocks overlay_content_blocks_register">' +
    '   <div style="position: absolute; top: 20px; right: 20px;">' +
    '       <img src="//media.freeslotsland.eu/en/file/image/secureLogo.png?build=201904161200">' +
    '   </div>' +
    '   <div class="form_label_container">' +
    '       [UNKNOWN TRANSLATABLE TEXT ID (PAGE:LOGIN:REGISTER:HEADER)]' +
    '   </div>' +
    '   <div class="clear" style="text-align: center; padding: 40px 0px 0px 0px; display: block;">' +
    '       [UNKNOWN TRANSLATABLE TEXT ID (PAGE:LOGIN:REGISTER:OPEN_ACCOUNT)]' +
    '       <a class="button" href="#" dynamic="registration" overlay="https://www.freeslotsland.eu/en/registrationOverlay/json">[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:REGISTER_NOW:LABEL)]</a>'+
    '   </div>' +
    '</div>'+
    '</div>';
    // }}}

    // create and display the overlay {{{
    var loginOverlay = overlayManager.createOverlay("loginOverlay", "", loginForm_HTML, true, false);
    overlayManager.add(loginOverlay, true);
    // }}}

    // setup the form for ajax processing
    FormUtils.setupForm(loginOverlay.find('#login_form'), {success: new Callback(Utils, "onUserLogin")})
    // CODE }}}
}

Utils.onUserLogin = function(response, $form)  {
    /* DOC {{{
        Processes the 'login' request response and if its valid, reloads the
        page.

        response                : server response data
        $form                   : reference to the form element
    }}} */

    // CODE {{{
    // if login was successful, reload the page after a little delay {{{
    if (FormUtils.isFormValid(response, $form)) {
        // update the registration data in helper {{{
        try {
            var registrationHelper = $('#registration_helper').get(0);
            registrationHelper.updateRegistration($form.find("[name=login]").val());
        } catch (e) {
        }
        // }}}

        Utils.setCookie("__USER_LOGGED_IN", 1);

        // setup the interval after which we will check for the login uniqueness {{{
        window.setTimeout(
            function() {
                overlayManager.removeByName("loginOverlay");

                location.reload(true);
            },
            1000
        )
        // }}}

        Utils.setCookie("__LAST_USER_NAME", $form.find("[name=login]").val(), 365);
    }
    // }}}
    // CODE }}}
}

Utils.showConfirmationOverlay = function(title, message, yesCallback, noCallback) {
    /* DOC {{{
        Displays a yes/no overlay with custom title and message.

        title               : overlay title
        message             : overlay message
        yesCallback         : callback to invoke when 'yes' button is clicked
        noCallback          : callback to invoke hwen 'no' button is clicked
    }}} */

    // CODE {{{
    // remove any previously displayed confirmation overlay
    overlayManager.removeByName("confirmationOverlay");

    // prepare the overlay html {{{
    var confirmation_HTML= '' +
    '<div class="system_error generic_form_container">' +
    '<div class="overlay_content_blocks">' +
    '   <a href="#"><div class="close_button"></div></a>' +
    '   <div class="form_label_container">' +
    '       <div class="form_label_huge">' + title + '</div>' +
    '   </div>' +
    '   <div class="system_error_message">' +
    '       ' + message +
    '   </div>' +
    '   <div class="system_error_buttons">' +
    '       <a href="#" id="confirmation_yes" class="button">[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:YES:LABEL)]</a>' +
    '       <a href="#" id="confirmation_no" class="button">[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:NO:LABEL)]</a>' +
    '   </div>' +
    '</div>'+
    '</div>';
    // }}}

    // create and display the overlay {{{
    var confirmationOverlay = overlayManager.createOverlay("confirmationOverlay", "", confirmation_HTML, false, false);
    overlayManager.add(confirmationOverlay);
    // }}}

    // assign button callbacks {{{
    confirmationOverlay.find("#confirmation_yes").singleClick(yesCallback);
    confirmationOverlay.find("#confirmation_no").singleClick(noCallback);
    // }}}
    // CODE }}}
}

Utils.showInstallFlash = function() {
    /* DOC {{{
        Shows an overlay which instructs the user to install Flash.

    }}} */

    // CODE {{{
    // show error message - install flash dialog
    showFlashError(texts['PAGE:GAME:INSTALL_FLASH']);
    // CODE }}}
}

Utils.showUpgradeFlash = function(invokeCancelCallback) {
    /* DOC {{{
        Shows an overlay which instructs the user to upgrade Flash.

    }}} */

    // CODE {{{
    // show error message - upgrade flash dialog
    showFlashError(texts['PAGE:GAME:UPGRADE_FLASH']);
    // CODE }}}
}

Utils.showCanvasNotSupported = function() {
    /* DOC {{{
        Shows an overlay which instructs the user to use one of the supported
        browsers.

    }}} */

    // CODE {{{

    var os = TechnologySupport.os.name;
    var header
    var about;

    if(os == TechnologySupport.ANDROID){
        header  = '[UNKNOWN TRANSLATABLE TEXT ID (PAGE:CANVAS_NOT_SUPPORTED:ANDROID:HEADER)]';
        about   = '[UNKNOWN TRANSLATABLE TEXT ID (PAGE:CANVAS_NOT_SUPPORTED:ANDROID:ABOUT)]';
    }

    else if(os == TechnologySupport.IOS){
        header  = '[UNKNOWN TRANSLATABLE TEXT ID (PAGE:CANVAS_NOT_SUPPORTED:IOS:HEADER)]';
        about   = '[UNKNOWN TRANSLATABLE TEXT ID (PAGE:CANVAS_NOT_SUPPORTED:IOS:ABOUT)]';
    }

    else if(os == TechnologySupport.WIN_PHONE){
        header  = '[UNKNOWN TRANSLATABLE TEXT ID (PAGE:CANVAS_NOT_SUPPORTED:WINDOWS_PHONE:HEADER)]';
        about   = '[UNKNOWN TRANSLATABLE TEXT ID (PAGE:CANVAS_NOT_SUPPORTED:WINDOWS_PHONE:ABOUT)]';
    }

    else {
        header  = '[UNKNOWN TRANSLATABLE TEXT ID (PAGE:CANVAS_NOT_SUPPORTED:HEADER)]';
        about   = '[UNKNOWN TRANSLATABLE TEXT ID (PAGE:CANVAS_NOT_SUPPORTED:ABOUT)]';
    }

    // prepare the HTML code {{{
    var html    = '<div class="install_requirement generic_form_container">' +
                  '    <div class="overlay_content_blocks">' +
                  '        <a href="#"><div class="close_button"></div></a>' +
                  '        <div class="form_label_container">' +
                  '            ' + header +
                  '        </div>' +
                  '        <div class="install_requirement_text">' +
                  '            ' + about +
                  '        </div>' +
                  '        <div class="install_requirement_buttons">' +
                  '            <a class="button" href="#" onclick="overlayManager.remove(); return false;" target="_blank">close</a>' +
                  '        </div>' +
                  '    </div>'+
                  '</div>';
    // }}}

    // create and display the overlay {{{
    var overlay = overlayManager.createOverlay("canvasNotSupported", "", html, true, false);
    overlayManager.add(overlay);
    // }}}
    // CODE }}}
}

Utils.switchToRealPlay = function() {
    /* DOC {{{
        Initiates switch to real play mode.

    }}} */

    // CODE {{{
    // perform the request to set the play mode {{{
    serverCommunicator.loadJSON(
        "https://www.freeslotsland.eu/en/user/setPlayMode/json",
        {
            playMode        : 2
        },
        new Callback(Utils, "onSwitchToRealPlay")
    )
    // }}}
    // CODE }}}
}

Utils.onSwitchToRealPlay = function(response) {
    /* DOC {{{
        Reloads the current location if the switch to real play mode was
        successful.

    }}} */

    // CODE {{{
    // abort if couldn't switch to real play {{{
    if (!FormUtils.isFormValid(response)) {
        return;
    }
    // }}}

    // reload the current location
    location.reload();
    // CODE }}}
}

Utils.scrollbarWidth = function() {
    /* DOC {{{
        Measures width of the vertical scrollbar and returns it.

    }}} */

    // CODE {{{
    // create elements for measuring the width {{{
    var inner = $('<div style="width: 100%; height:200px;">test</div>');
    var outer = $('<div style="width:200px;height:150px; position: absolute; top: 0; left: 0; visibility: hidden; overflow:hidden;"></div>').append(inner);
    $('body').append(outer);
    // }}}

    // measure the width with and without srollbar {{{
    var width1 = inner[0].offsetWidth;
    outer.css('overflow', 'scroll');
    var width2 = outer[0].clientWidth;
    outer.remove();
    // }}}

    // return the scrollbar width
    return (width1 - width2);
    // CODE }}}
}

Utils.redirectWithAction = function(type, data) {
    /* DOC {{{
        Store action that needs to be executed on secured page and then redirect to secured
        page. Logged users are redirected to lobby and others are redirected to homepage.

        type            : type of action that will be executed
        data            : data needed for executing the action
    }}} */

    // CODE {{{
    var actionData = "";
    var address = "https://www.freeslotsland.eu";

    // if data are in array, convert them into string so it can be stored in cookie {{{
    if ($.isArray(data)) {
        actionData = data.join("||");
    }
    // }}}

    // store action type and data in cookies {{{
    Utils.setCookie("redirectActionType", type);
    Utils.setCookie("redirectActionData", actionData);
    // }}}

    // if user is logged, use lobby address as destination of redirect {{{
    if ((window.initData['userStatus']['userType'] != 0)) {
        address += "/en/user/lobby";
    }
    // }}}

    // redirect user to secured page
    location.assign(address);
    // CODE }}}
}

Utils.handleRedirectAction = function() {
    /* DOC {{{
        Check cookies for any redirect action and if found, execure it.

    }}} */

    // CODE {{{
    // get action type and data from cookies
    var actionType = Utils.getCookie("redirectActionType");
    var actionData = Utils.getCookie("redirectActionData");
    // }}}

    // if no action or cookie found, abort {{{
    if (actionType === "") {
        return;
    }
    // }}}
    // if action type is login, show login overlay {{{
    else if (actionType == Utils.REDIRECT_ACTION_TYPE_LOGIN) {
        Utils.showLogin();
    }
    // }}}
    // if action type is external overlay, load and show it {{{
    else if (actionType == Utils.REDIRECT_ACTION_TYPE_OVERLAY) {
        // convert action data from string representation to array
        var overlayData = actionData.split("||");
        // get overlay name
        var overlayName = overlayData[0];
        // get overlay URI
        var overlayURI = overlayData[1];
        // convert string representation back to boolean for cache flag
        var useCache = (overlayData[2] === "true" ? true : false);
        // convert string representation back to boolean for reload flag
        var reloadData = (overlayData[3] === "true" ? true : false);

        // load overlay with parsed values
        overlayManager.load(overlayName, overlayURI, useCache, reloadData);
    }
    // }}}

    // delete action type and data cookies {{{
    Utils.setCookie("redirectActionType", "", -1);
    Utils.setCookie("redirectActionData", "", -1);
    // }}}
    // CODE }}}
}

// }}}

// class UserStatus {{{

function UserStatus() {
}

// initialize container for storing status data
UserStatus._status = {};

// initialize variable for storing update timeout
UserStatus.getStatusTimeout = null;

UserStatus.get = function() {
    /* DOC {{{
        Returns the status data. If no arguments, returns the whole container,
        otherwise returns value specified by the key as first function
        parameter.

    }}} */

    // CODE {{{
    // get method arguments
    var parameters = Array.prototype.slice.call(arguments, 0);

    // if there are no parameters, return whol status container {{{
    if (typeof parameters[0] === "undefined") {
        return UserStatus._status;
    }
    // }}}
    // otherwise return only the value for specified key {{{
    else {
        return UserStatus._status[parameters[0]];
    }
    // }}}
    // CODE }}}
}

UserStatus.set = function(keyName, value) {
    /* DOC {{{
        Adds the key/value to the status container.

    }}} */

    // CODE {{{
    UserStatus._status[keyName] = value;
    // CODE }}}
}

UserStatus.load = function() {
    /* DOC {{{
        Sends request for user's status.

    }}} */

    // CODE {{{
    // URI for retrieving the user status
    var statusURI = "https://www.freeslotsland.eu/en/user/status/json";

    // get the user's status {{{
    serverCommunicator.loadJSON(
        statusURI,
        {},
        new Callback(UserStatus, "onLoaded")
    );
    // }}}
    // CODE }}}
}

UserStatus.onLoaded = function(response, $form) {
    /* DOC {{{
        Processes the server response with status data.

        response                : server response data
        $form                   : (optional) reference to the form element
    }}} */

    // CODE {{{
    // silently fail if response was invalid {{{
    if (response.status == "0") {
        return;
    }
    // }}}

    // update the local user status data
    UserStatus.update(response);

    // notify the client that user has just logged in {{{
    if (Utils.getCookie("__USER_LOGGED_IN") == 1) {
        Utils.setCookie("__USER_LOGGED_IN", 0);
        Utils.onUserLoggedIn();
    }
    // }}}

    // process the temporary bonus code {{{
    if (Utils.getCookie("__TMP_BONUS_CODE") !== "") {
        ExternalActionsManager.show_EA_USE_BONUS(Utils.getCookie("__TMP_BONUS_CODE"));
        Utils.setCookie("__TMP_BONUS_CODE", "");
    }
    // }}}

    // do not perform any updates if the user is not logged in {{{
    if (response.userType == "0") {
        return;
    }
    // }}}

    UserStatus.setupPeriodicalStatusUpdate();
    // CODE }}}
}

UserStatus.setupPeriodicalStatusUpdate = function() {
    /* DOC {{{
        Setup up timeout for requesting new user status.

    }}} */

    // CODE {{{
    // clear previous status update timeout {{{
    if (typeof UserStatus.getStatusTimeout != null) {
        window.clearTimeout(UserStatus.getStatusTimeout);
        UserStatus.getStatusTimeout = null;
    }
    // }}}

    // setup new status update timeout
    UserStatus.getStatusTimeout = window.setTimeout(UserStatus.load, 180 * 1000);
    // CODE }}}
}

Utils.onUserLoggedIn = function() {
    /* DOC {{{
        Invoked after user has successfuly logged in. Currently updates the
        registration help and page tracking.

    }}} */

    // CODE {{{
    // track free player {{{
    if (UserStatus.get("userType") == 1) {
        Utils.pageTracker("/loginFPSuccess");
    }
    // }}}
    // tracke real player {{{
    else if (UserStatus.get("userType") == 2) {
        Utils.pageTracker("/loginRPSuccess");
    }
    // }}}
    // CODE }}}
}

UserStatus.update = function(newStatusData) {
    /* DOC {{{
        Updates the status data with those specified in the 'newStatusData'
        parameter. This can be either an object or a JSON string.

        newStatusData       : either an object or JSON string with updated status data
    }}} */

    // CODE {{{
    // parse the new status data if its a string {{{
    if (typeof newStatusData === "string") {
        newStatusData = JSON.parse(newStatusData);
    }
    // }}}

    // update the status with new data {{{
    for (var prop in newStatusData) {
        UserStatus.set(prop, newStatusData[prop]);
    }
    // }}}

    // update various dynamic elements with new values {{{
    // update elements displaying 'cash' variable {{{
    if (typeof UserStatus.get("cash") !== "undefined") {
        var variableContainers = $("[variable=cash]");
        variableContainers.html(CURRENCY_REAL_PLAY + UserStatus.get("cash"));

        variableContainers = $("[variable=cashBalance]");
        variableContainers.html("[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:CASH:LABEL)]: " + CURRENCY_REAL_PLAY + UserStatus.get("cash"));
    }
    // }}}

    // update elements displaying 'creditsFreePlay' variable {{{
    if (typeof UserStatus.get("creditsFreePlay") !== "undefined") {
        var variableContainers = $("[variable=creditsFreePlay]");
        variableContainers.html(CURRENCY_FREE_PLAY + UserStatus.get("creditsFreePlay"));
    }
    // }}}

    // update elements displaying 'withdrawalFund' variable {{{
    if (typeof UserStatus.get("withdrawalFund")!== "undefined") {
        var variableContainers = $("[variable=withdrawalFund]");
        variableContainers.html(CURRENCY_REAL_PLAY + UserStatus.get("withdrawalFund"));
    }
    // }}}

    // update elements displaying 'prePaymentFund' variable {{{
    if (typeof UserStatus.get("prePaymentFund") !== "undefined") {
        var variableContainers = $("[variable=prePaymentFund]");
        variableContainers.html(CURRENCY_REAL_PLAY + UserStatus.get("prePaymentFund"));
    }
    // }}}

    // update elements displaying 'unreadMessagesCount' variable {{{
    if (typeof UserStatus.get("unreadMessagesCount") !== "undefined") {
        var variableContainers = $("[variable=unreadMessagesCount]");
        if (UserStatus.get("unreadMessagesCount") == 0) {
            $(".menu_messages").css("opacity", 0.4);
            variableContainers.html("");
        } else {
            $(".menu_messages").css("opacity", 1);
            variableContainers.html(UserStatus.get("unreadMessagesCount"));
        }
    }
    // }}}
    // }}}

    // check if global game reference is valid, and inform game, that status was updated {{{
    if ((typeof _G !== "undefined") && (typeof _G("GAME") !== "undefined")) {
        // dispatch event in game scope, that user status was updated
        _G("GAME").dispatchEvent(new createjs.Event("userStatusUpdated"));
    }
    // }}}
    // CODE }}}
}

window.UserStatus = UserStatus;
// }}}


// class CallbacksContainer {{{

function CallbacksContainer() {
    /* DOC {{{
        Allows to store function calls (callbacks) in globally accessible
        object identified by an 'id'.

    }}} */

    // CODE {{{
    // container for callbacks
    this.callbacks = new Array();
    // CODE }}}
}

CallbacksContainer.prototype.add = function(callback) {
    /* DOC {{{
        Adds new callback and returns its id.

        callback            : callback to add
    }}} */

    // CODE {{{
    // add the callback
    this.callbacks.push(callback);

    // return the callback's index
    return (this.callbacks.length - 1);
    // CODE }}}
}

CallbacksContainer.prototype.get = function(id) {
    /* DOC {{{
        Returns a callback for the specified id.

        id                  : id of the callback to return
    }}} */

    // CODE {{{
    return this.callbacks[id];
    // CODE }}}
}

CallbacksContainer.prototype.execute = function(id) {
    /* DOC {{{
        Executes the callback with the specified id.

        id                  : id of the callback to execute
    }}} */

    // CODE {{{
    this.callbacks[id]();
    // CODE }}}
}
// }}}


// class Callback {{{

function Callback (callbackObject, callbackMethod) {
    /* DOC {{{
        Implementation of a simple callback object with parameters.

        callbackObject      : target callback object
        callbackMethod      : target method on the callback object
    }}} */

    // CODE {{{
    // store callback parameters {{{
    this.callbackObject     = callbackObject;
    this.callbackMethod     = callbackMethod;
    this.callbackParameters = Array.prototype.slice.call(arguments, 2);
    this.callbackData       = new Array();
    // }}}
    // CODE }}}
}

Callback.prototype.addData = function(name, value) {
    /* DOC {{{
        Adds data to the callback.

        name            : name of the parameter
        value           : value associated with the parameter
    }}} */

    // CODE {{{
    this.callbackData[paramName] = paramValue;
    // CODE }}}
}

Callback.prototype.getData = function(name) {
    /* DOC {{{
        Returns the value for the specified parameter name.

        name            : name of the parameter
    }}} */

    // CODE {{{
    return this.callbackData[name];
    // CODE }}}
}

Callback.prototype.call = function () {
    /* DOC {{{
        Invokes the callback. The callback parameters can be overrided by
        sending custom parameters to this method.

    }}} */

    // CODE {{{
    // custom parameters for the callback
    var parameters = Array.prototype.slice.call(arguments, 0)

    // if no arguments were passed, use parameters specified at the time of
    // callback creation {{{
    if (parameters.length == 0) {
        parameters = this.callbackParameters;
    }
    // }}}

    // perform the callback
    return this.callbackObject[this.callbackMethod].apply(this.callbackObject, parameters);
    // CODE }}}
}

// }}}



function ExternalActionsManager() {
}

ExternalActionsManager.setActions = function(externalActions) {
    /* DOC {{{
        Processes the specified external actions and invokes the first
        available one.

        externalActions     : a list or JSON string with external actions
    }}} */

    // CODE {{{
    // if no actions are present, abort {{{
    if (typeof externalActions === 'undefined' || externalActions == "") {
        return false;
    }
    // }}}

    // if actions are in string format, parse them now {{{
    if (typeof externalActions === "string") {
        window.externalActions = JSON.parse(externalActions);
    }
    // }}}
    // otherwise actions are already parsed {{{
    else {
        window.externalActions = externalActions.concat();
    }
    // }}}

    // invoke the external action
    return ExternalActionsManager.invokeAction();
    // CODE }}}
}

ExternalActionsManager.invokeAction = function() {
    /* DOC {{{
        Invokes the first available external action.

    }}} */

    // CODE {{{
    // invoke first available action {{{
    if (window.externalActions.length > 0) {
        // get the action definition
        var action = window.externalActions.shift();
        // get action's name id
        var actionNameId = action[0];
        // get action's data
        var actionData = action[1];

        // invoke the action handler {{{
        if (typeof ExternalActionsManager["show_" + actionNameId] === "function") {
            ExternalActionsManager["show_" + actionNameId](actionData);
        }
        // }}}
        // otherwise, try to invoke the legacy freeslot event handling {{{
        else if (typeof(window["eventAction_" + actionNameId]) == "function") {
            window["eventAction_" + actionNameId].apply(null, action.slice(1));
        }
        // }}}

        // reset external actions, we only support one at a time
        window.externalActions = new Array();

        // external action was invoked successfully
        return true;
    }
    // }}}

    // no external action found
    return false;
    // CODE }}}
}

ExternalActionsManager.ACTION = function(actionNameId, actionData) {
    /* DOC {{{
        Shorthand for invoking specific action manually.

    }}} */

    // CODE {{{
    // invoke the action handler {{{
    if (typeof ExternalActionsManager["show_" + actionNameId] === "function") {
        ExternalActionsManager["show_" + actionNameId](actionData);
    }
    // }}}

    // no external action found
    return false;
    // CODE }}}
}

ExternalActionsManager.doAction = function(actionNameId) {
    /* DOC {{{
        Invokes the main handler for the action.

        actionNameId        : name of the action to invoke
    }}} */

    // CODE {{{
    // remove the top most overlay (always?)
    overlayManager.remove();

    // invoke the action only if the handler exists {{{
    if (typeof ExternalActionsManager["do_" + actionNameId] === "function") {
        ExternalActionsManager["do_" + actionNameId]();
    }
    // }}}
    // CODE }}}
}

ExternalActionsManager.displayOverlay = function(actionNameId, actionTitle, actionMessage, buttons) {
    /* DOC {{{
        Generic method for displaying external actions overlays.

        actionNameId        : name of the action
        actionTitle         : title for the overlay
        actionMessage       : message for the overlay
        buttons             : buttons for the overlay
    }}} */

    // CODE {{{
    // store last overlay name id
    ExternalActionsManager.lastActionOverlayName = actionNameId;

    // remove any existing action overlay(s)
    overlayManager.removeByName("actionOverlay");

    // prepare the container for the action {{{
    // create initial container with required data (title,message) {{{
    var actionContents = $('' +
    '<div class="action generic_form_container">' +
    '<div class="overlay_content_blocks">' +
    '   <a href="#"><div class="close_button"></div></a>' +
    '   <div class="form_label_container">' +
    '       <div class="form_label_huge">' + actionTitle + '</div>' +
    '   </div>' +
    '   <div class="action_message">' + actionMessage + '</div>' +
    '   <div class="clear"></div>' +
    '</div>'+
    '</div>');
    // }}}

    // if buttons were not specified, add the default 'OK' button {{{
    if (typeof buttons === 'undefined') {
        // create the button element
        var button = $('<a class="button">OK</a>');

        // setup the click event {{{
        button.singleClick(
            Utils.createCallback(
                function(actionNameId) {
                    ExternalActionsManager.doAction(actionNameId);
                    return false;
                },
                actionNameId
            )
        );
        // }}}

        // add button the container
        actionContents.find(".action_message").after(button);
    }
    // }}}
    // add the specified buttons to the HTML {{{
    else {
        for (var a = 0; a < buttons.length; a++) {
            // create the button element
            var button = $('<a class="button"></a>');

            // set the button label
            button.html(buttons[a].label);

            // setup the click event {{{
            button.singleClick(
                Utils.createCallback(
                    function(onClickCallback) {
                        onClickCallback.call();
                        return false;
                    },
                    buttons[a].onClick
                )
            );
            // }}}

            // add button the container
            actionContents.find(".action_message").after(button);
        }
    }
    // }}}
    // }}}

    // create the action overlay
    var actionOverlay = overlayManager.createOverlay("actionOverlay", "", actionContents);
    // add the overlay to the overlay manager and display it
    overlayManager.add(actionOverlay);
    // CODE }}}
}

ExternalActionsManager.exitFullScreen = function() {
    /* DOC {{{
        Handles fullscreen exit for flash and canvas games.

    }}} */

    // CODE {{{
    if ((typeof GameAPI === "object") && (typeof GameAPI.disableFullScreen === "function")) {
        GameAPI.disableFullScreen();
    }
    // }}}
}

// EXTERNAL ACTIONS {{{
ExternalActionsManager.show_EA_DEPOSIT_PM_CREATE = function() {
    /* DOC {{{
        Instructs user to create new PM.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_DEPOSIT_PM_CREATE',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_DEPOSIT_PM_CREATE:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_DEPOSIT_PM_CREATE:MESSAGE:SKIPPABLE)]'
    )
    // CODE }}}
}

ExternalActionsManager.do_EA_DEPOSIT_PM_CREATE = function() {
    /* DOC {{{
        Loads the cashier with 'deposit' preselected.

    }}} */

    // CODE {{{
    overlayManager.load('cashier', 'https://www.freeslotsland.eu/en/user/cashier/json?selectTab=deposit');
    // CODE }}}
}

ExternalActionsManager.show_EA_LOGIN = function() {
    /* DOC {{{
        Instructs the user to log in.

    }}} */

    // CODE {{{
    // exit game fullscreen
    this.exitFullScreen("EA_LOGIN");

    // if the game element exists, inform the flash game that login action was invoked {{{
    if ($("#game").length > 0) {
        Game.gameSWF().onExternalActionLogin();
    }
    // }}}

    // display the action overlay {{{
    ExternalActionsManager.displayOverlay(
        'EA_LOGIN',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_LOGIN:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_LOGIN:MESSAGE:SKIPPABLE)]'
    );
    // }}}
    // CODE }}}
}

ExternalActionsManager.do_EA_LOGIN = function() {
    /* DOC {{{
        Shows the 'login' form.

    }}} */

    // CODE {{{
    Utils.showLogin();
    // CODE }}}
}

ExternalActionsManager.show_EA_DEPOSIT = function() {
    /* DOC {{{
        Instructs the user that he must make a deposit.

    }}} */

    // CODE {{{
    // exit game fullscreen
    this.exitFullScreen();

    // display the action overlay {{{
    ExternalActionsManager.displayOverlay(
        'EA_DEPOSIT',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_DEPOSIT:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_DEPOSIT:MESSAGE:SKIPPABLE)]',
        [
            {
                label               : "[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:DEPOSIT_NOW:LABEL)]",
                onClick             : new Callback(ExternalActionsManager, "do_EA_DEPOSIT")
            },
            {
                label               : "close",
                onClick             : new Callback(ExternalActionsManager, "close_EA_DEPOSIT")
            }
        ]
    );
    // }}}
    // CODE }}}
}

ExternalActionsManager.close_EA_DEPOSIT = function() {
    /* DOC {{{
        Closes the dialog and informs game, to reset it's state using it's
        latest server data.

    }}} */

    // CODE {{{
    // remove overlay dialog
    overlayManager.remove();

    // check if handling canvas game {{{
    if ($("#gameCanvas").length > 0) {
        // invoke on error recovery on game
        _G("GAME").onErrorRecovery();

        // update cash displayers
        _G("GAME").setUserCash();
    }
    // }}}
    // CODE }}}
}

ExternalActionsManager.do_EA_DEPOSIT = function() {
    /* DOC {{{
        Loads the cashier overlay.

    }}} */

    // CODE {{{
    // remove any action overlay(s)
    overlayManager.removeByName("actionOverlay");

    // load the cashier overlay
    overlayManager.load('cashier', 'https://www.freeslotsland.eu/en/user/cashier/json');
    // CODE }}}
}

ExternalActionsManager.show_EA_USE_BONUS = function(bonusCode) {
    /* DOC {{{
        Allows 'bonusCode' to be prefilled for the user.

    }}} */

    // CODE {{{
    // 'bonusCode' can be sent in in an object too {{{
    if (typeof bonusCode === "object") {
        bonusCode = bonusCode['bonusCode'];
    }
    // }}}

    // remove any action overlay(s)
    overlayManager.removeByName("actionOverlay");

    // if user is not logged in, tell him to log in {{{
    if (UserStatus.get("userType") === 0) {
        // remember the bonus code
        Utils.setCookie("__TMP_BONUS_CODE", bonusCode);

        // initiate user login
        Utils.showLogin();
    }
    // }}}
    // otherwise load cashier tab {{{
    else {
        // store the 'bonusCode' temporarily so we can retrieve it from overlay later
        window.__TMP_BONUS_CODE = bonusCode;

        // load the cashier overlay
        overlayManager.load('cashier', 'https://www.freeslotsland.eu/en/user/cashier/json?selectTab=bonus');
    }
    // }}}
    // CODE }}}
}

ExternalActionsManager.do_EA_DEPOSIT = function() {
    /* DOC {{{
        Loads the cashier overlay.

    }}} */

    // CODE {{{
    // remove any action overlay(s)
    overlayManager.removeByName("actionOverlay");

    // load the cashier overlay
    overlayManager.load('cashier', 'https://www.freeslotsland.eu/en/user/cashier/json');
    // CODE }}}
}

ExternalActionsManager.show_EA_RESET_FREE_PLAY = function() {
    /* DOC {{{
        Instructs the user that he should reset free play.

    }}} */

    // CODE {{{
    // exit game fullscreen
    this.exitFullScreen();

    ExternalActionsManager.displayOverlay(
        'EA_RESET_FREE_PLAY',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_RESET_FREE_PLAY:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_RESET_FREE_PLAY:MESSAGE:SKIPPABLE)]',
        [
            {
                label               : "[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:RESET:LABEL)]",
                onClick             : new Callback(ExternalActionsManager, "do_EA_RESET_FREE_PLAY")
            },
            {
                label               : "[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:SWITCH_TO_REAL_PLAY:LABEL)]",
                onClick             : new Callback(Utils, "switchToRealPlay")
            }
        ]
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_RESET_FREE_PLAY = function() {
    /* DOC {{{
        Resets free play for the user.

    }}} */

    // CODE {{{
    // perform the request to remove the reset the free play counters {{{
    serverCommunicator.loadJSON(
        "https://www.freeslotsland.eu/en/user/doResetFreePlay/json",
        {
        },
        new Callback(ExternalActionsManager, "onResetFreePlay")
    )
    // }}}
    // CODE }}}
}

ExternalActionsManager.onResetFreePlay = function(response) {
    /* DOC {{{
        Updates the player status after resetting free play.

        response                : server response data
    }}} */

    // CODE {{{
    // if the reset was successfuly, update the user's status {{{
    if (response.status == "1") {
        UserStatus.update({
            cash                : response.cash,
            creditsFreePlay     : response.creditsFreePlay,
            roundsFreePlay      : response.roundsFreePlay,
            jackpot             : response.jackpot
        });

        overlayManager.removeAll();

        // check if handling canvas game {{{
        if ($("#gameCanvas").length > 0) {
            // inform canvas game, that free play was reset
            _G("GAME").onResetFreePlay();
        }
        // }}}
    }
    // }}}
    // CODE }}}
}

ExternalActionsManager.show_EA_REGISTRATION = function() {
    /* DOC {{{
        Loads the registration overlay.

    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();
    overlayManager.load('registration', 'https://www.freeslotsland.eu/en/registrationOverlay/json');
    // CODE }}}
}


ExternalActionsManager.show_EA_PASSWORD_RECOVERY = function() {
    /* DOC {{{
        Loads the password recovery overlay.

    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();

    // load the password recovery
    overlayManager.load('passwordRecovery', 'https://www.freeslotsland.eu/en/user/passwordRecovery/json');
    // CODE }}}
}

ExternalActionsManager.show_EA_PASSWORD_RECOVERY_REQUEST_FAILED = function() {
    /* DOC {{{
        Notifies the user that password recovery has failed.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_PASSWORD_RECOVERY_REQUEST_FAILED',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_PASSWORD_RECOVERY_REQUEST_FAILED:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_PASSWORD_RECOVERY_REQUEST_FAILED:MESSAGE:SKIPPABLE)]',
        [
            {
                label               : "[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:REQUEST_NEW_PASSWORD:LABEL)]",
                onClick             : new Callback(ExternalActionsManager, "do_EA_PASSWORD_RECOVERY_REQUEST_FAILED")
            }
        ]
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_PASSWORD_RECOVERY_REQUEST_FAILED = function() {
    /* DOC {{{
        Initiates new password recovery request.

    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();

    // load the password recovery request overlay
    overlayManager.load('passwordRecoveryRequest', '/en/user/passwordRecoveryRequest');
    // CODE }}}
}

ExternalActionsManager.show_EA_PASSWORD_CHANGE = function() {
    /* DOC {{{
        Instructs the user that he needs to change password.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_PASSWORD_CHANGE',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_PASSWORD_CHANGE:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_PASSWORD_CHANGE:MESSAGE:SKIPPABLE)]',
        [
            {
                label               : "OK",
                onClick             : new Callback(ExternalActionsManager, "do_EA_PASSWORD_CHANGE")
            }
        ]
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_PASSWORD_CHANGE = function() {
    /* DOC {{{
        Loads the profile overlay.

    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();

    // load the user profile overlay
    overlayManager.load('accountViewProfile', 'https://www.freeslotsland.eu/en/user/viewProfile/json');
    // CODE }}}
}

ExternalActionsManager.show_EA_CONTACT_ADDRESS_CHANGE = function() {
    /* DOC {{{
        Instructs the user that he must change his address.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_CONTACT_ADDRESS_CHANGE',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_ADDRESS_CHANGE:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_ADDRESS_CHANGE:MESSAGE:SKIPPABLE)]',
        [
            {
                label               : "OK",
                onClick             : new Callback(ExternalActionsManager, "do_EA_CONTACT_ADDRESS_CHANGE")
            }
        ]
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_CONTACT_ADDRESS_CHANGE = function() {
    /* DOC {{{
        Loads the profile overlay.

    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();

    // load the user profile overlay
    overlayManager.load('accountViewProfile', 'https://www.freeslotsland.eu/en/user/viewProfile/json');
    // CODE }}}
}

ExternalActionsManager.show_EA_CONTACT_EMAIL_CHANGE = function() {
    /* DOC {{{
        Instructs the user that he must change his email.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_CONTACT_EMAIL_CHANGE',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_EMAIL_CHANGE:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_EMAIL_CHANGE:MESSAGE:SKIPPABLE)]',
        [
            {
                label               : "OK",
                onClick             : new Callback(ExternalActionsManager, "do_EA_CONTACT_EMAIL_CHANGE")
            }
        ]
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_CONTACT_EMAIL_CHANGE = function() {
    /* DOC {{{
        Loads the profile overlay.
    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();

    // load the user profile overlay
    overlayManager.load('accountViewProfile', 'https://www.freeslotsland.eu/en/user/viewProfile/json');
    // CODE }}}
}

ExternalActionsManager.show_EA_CONTACT_PHONE_NUMBER_CHANGE = function() {
    /* DOC {{{
        Instructs the user that he must change his phone number before
        continuing.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_CONTACT_PHONE_NUMBER_CHANGE',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_PHONE_NUMBER_CHANGE:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_PHONE_NUMBER_CHANGE:MESSAGE:SKIPPABLE)]',
        [
            {
                label               : "OK",
                onClick             : new Callback(ExternalActionsManager, "do_EA_CONTACT_PHONE_NUMBER_CHANGE")
            }
        ]
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_CONTACT_PHONE_NUMBER_CHANGE = function() {
    /* DOC {{{
        Loads the profile overlay.

    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();

    // load the user profile overlay
    overlayManager.load('accountViewProfile', 'https://www.freeslotsland.eu/en/user/viewProfile/json');
    // CODE }}}
}

ExternalActionsManager.show_EA_TERMS_AND_CONDITIONS = function() {
    /* DOC {{{
        Instructs the user that he must accept T&C.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_TERMS_AND_CONDITIONS',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_TERMS_AND_CONDITIONS:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_TERMS_AND_CONDITIONS:MESSAGE:SKIPPABLE)]',
        [
            {
                label               : "OK",
                onClick             : new Callback(ExternalActionsManager, "do_EA_TERMS_AND_CONDITIONS")
            }
        ]
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_TERMS_AND_CONDITIONS = function() {
    /* DOC {{{
        Loads the profile overlay.

    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();

    // load the user profile overlay
    overlayManager.load('accountViewProfile', 'https://www.freeslotsland.eu/en/user/viewProfile/json');
    // CODE }}}
}


ExternalActionsManager.show_EA_CONTACT_EMAIL_VERIFICATION = function() {
    /* DOC {{{
        Instructs the use that he must verify his email.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_CONTACT_EMAIL_VERIFICATION',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_EMAIL_VERIFICATION:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_EMAIL_VERIFICATION:MESSAGE:SKIPPABLE)]',
        [
            {
                label               : "[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:VERIFY_EMAIL_ADDRESS:LABEL)]",
                onClick             : new Callback(ExternalActionsManager, "do_EA_CONTACT_EMAIL_VERIFICATION")
            }
        ]
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_CONTACT_EMAIL_VERIFICATION = function() {
    /* DOC {{{
        Contacts the server to verify user's email.

    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();

    // contact the server to verify user's email address {{{
    serverCommunicator.loadJSON(
        "https://www.freeslotsland.eu/en/user/doVerifyEmail/json",
        {
        },
        new Callback(ExternalActionsManager, "onVerifyEmail")
    )
    // }}}
    // CODE }}}
}

ExternalActionsManager.onVerifyEmail = function(response) {
    /* DOC {{{
        Notifies the user that verification email was sent.

    }}} */

    // CODE {{{
    // display the message to the user if request was successful {{{
    if (response.status == "1") {
        // remove any displayed overlays
        overlayManager.removeAll();

        // show the message to the user
        overlayManager.showMessage("[UNKNOWN TRANSLATABLE TEXT ID (FORM:VERIFY_EMAIL:EMAIL_SENT:TITLE)]", "[UNKNOWN TRANSLATABLE TEXT ID (FORM:VERIFY_EMAIL:EMAIL_SENT:MESSAGE)]");
    }
    // }}}
    // CODE }}}
}

ExternalActionsManager.show_EA_CONTACT_EMAIL_VERIFICATION_FAILED = function() {
    /* DOC {{{
        Notifies the user that email verificatio has failed.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_CONTACT_EMAIL_VERIFICATION_FAILED',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_EMAIL_VERIFICATION_FAILED:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_EMAIL_VERIFICATION_FAILED:MESSAGE:SKIPPABLE)]'
    );
    // CODE }}}
}

ExternalActionsManager.show_EA_CONTACT_EMAIL_VERIFICATION_SUCCESSFUL = function() {
    /* DOC {{{
        Notifies the uesr that email verification was successful.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_CONTACT_EMAIL_VERIFICATION_SUCCESSFUL',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_EMAIL_VERIFICATION_SUCCESSFUL:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_CONTACT_EMAIL_VERIFICATION_SUCCESSFUL:MESSAGE:SKIPPABLE)]',
        [
            {
                label               : "[UNKNOWN TRANSLATABLE TEXT ID (BUTTON:PROCEED_TO_LOG_IN:LABEL)]",
                onClick             : new Callback(ExternalActionsManager, "do_EA_CONTACT_EMAIL_VERIFICATION_SUCCESSFUL")
            }
        ]
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_CONTACT_EMAIL_VERIFICATION_SUCCESSFUL = function() {
    /* DOC {{{
        Shows the login overlay.

    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();

    // show the login form
    Utils.showLogin();
    // CODE }}}
}

ExternalActionsManager.show_EA_NEWSLETTER_UNSUBSCRIBE_FAILED = function() {
    /* DOC {{{
        Notifies the user that newsletter unsubscribe has failed.

    }}} */

    // CODE {{{
    // track this event
    Utils.eventTracker('newsletterUnsubscribe', 'failed');

    // display the action overlay {{{
    ExternalActionsManager.displayOverlay(
        'EA_NEWSLETTER_UNSUBSCRIBE_FAILED',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_NEWSLETTER_UNSUBSCRIBE_FAILED:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_NEWSLETTER_UNSUBSCRIBE_FAILED:MESSAGE:SKIPPABLE)]'
    );
    // }}}
    // CODE }}}
}

ExternalActionsManager.show_EA_NEWSLETTER_UNSUBSCRIBE_SUCCESSFUL = function(data) {
    /* DOC {{{
        Notifies the user that newsletter subscribe was successful.

    }}} */

    // CODE {{{
    // track this event
    Utils.eventTracker('newsletterUnsubscribe', 'successful', data['campaignId'] + "_" + data['contentId']);

    // display the action overlay {{{
    ExternalActionsManager.displayOverlay(
        'EA_NEWSLETTER_UNSUBSCRIBE_SUCCESSFUL',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_NEWSLETTER_UNSUBSCRIBE_SUCCESSFUL:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_NEWSLETTER_UNSUBSCRIBE_SUCCESSFUL:MESSAGE:SKIPPABLE)]'.replace('(EMAIL_ADDRESS)', data['email']).replace('(LOGIN)', data['login'])
    );
    // }}}
    // CODE }}}
}

ExternalActionsManager.show_EA_USER_SUSPENDED = function() {
    /* DOC {{{
        Notifies the uesr that his account was suspended.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_USER_SUSPENDED',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_USER_SUSPENDED:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_USER_SUSPENDED:MESSAGE:SKIPPABLE)]'
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_USER_SUSPENDED = function() {
    /* DOC {{{
        Removes the overlay.

    }}} */

    // CODE {{{
    overlayManager.removeAll();
    // CODE }}}
}


ExternalActionsManager.show_EA_USER_ACTIVITY_TIMEOUT = function() {
    /* DOC {{{
        Notifies the user that he has timed out.

    }}} */

    // CODE {{{
    // exit game fullscreen
    this.exitFullScreen();

    ExternalActionsManager.displayOverlay(
        'EA_USER_ACTIVITY_TIMEOUT',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_USER_ACTIVITY_TIMEOUT:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_USER_ACTIVITY_TIMEOUT:MESSAGE:SKIPPABLE)]'
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_USER_ACTIVITY_TIMEOUT = function() {
    /* DOC {{{
        Removes the overlay.

    }}} */

    // CODE {{{
    overlayManager.removeAll();
    // CODE }}}
}

ExternalActionsManager.show_EA_DISABLE_DEPOSIT_FORM = function() {
    /* DOC {{{
        Instructs the PM manager to disable deposit form.

    }}} */

    // CODE {{{
    pmManager.disableDeposit();
    // CODE }}}
}

ExternalActionsManager.show_EA_DISABLE_WITHDRAWAL_FORM = function() {
    /* DOC {{{
        Instructs the PM manager to disable withdrawal form.

    }}} */

    // CODE {{{
    pmManager.disableWithdrawal();
    // CODE }}}
}

ExternalActionsManager.show_EA_DISABLE_WITHDRAWAL_CHANGE_PM = function() {
    /* DOC {{{
        Instructs the PM manager to disable PM change.

    }}} */

    // CODE {{{
    pmManager.disablePMChange();
    // CODE }}}
}

ExternalActionsManager.show_EA_DISABLE_CREATE_NEW_PM = function() {
    /* DOC {{{
        Instructs te PM manager to disable new PM creation.

    }}} */

    // CODE {{{
    pmManager.disablePMCreate();
    // CODE }}}
}

ExternalActionsManager.show_EA_DISABLE_EDIT_PM = function() {
    /* DOC {{{
        Instructs the PM manager to disable PM editation.

    }}} */

    // CODE {{{
    pmManager.disablePMEdit();
    // CODE }}}
}

ExternalActionsManager.show_EA_DISABLE_SAVE_PM = function() {
    /* DOC {{{
        Instructs the PM manager to disable PM saving.

    }}} */

    // CODE {{{
    pmManager.disablePMSave();
    // CODE }}}
}

ExternalActionsManager.show_EA_DISABLE_PM_KEY = function() {
    /* DOC {{{
        Instructs the PM manager to disable the PM key field.

    }}} */

    // CODE {{{
    pmManager.disablePMKey();
    // CODE }}}
}

ExternalActionsManager.show_EA_SOFTWARE_UPDATE = function() {
    /* DOC {{{
        Notifies the user that new version of the software was deployed and
        that he should reload.

    }}} */

    // CODE {{{
    ExternalActionsManager.displayOverlay(
        'EA_SOFTWARE_UPDATE',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_SOFTWARE_UPDATE:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_SOFTWARE_UPDATE:MESSAGE:UNSKIPPABLE)]',
        [
            {
                label               : "RELOAD",
                onClick             : new Callback(ExternalActionsManager, "do_EA_SOFTWARE_UPDATE")
            }
        ]
    );
    // CODE }}}
}

ExternalActionsManager.do_EA_SOFTWARE_UPDATE = function() {
    /* DOC {{{
        Reloads the current page location.

    }}} */

    // CODE {{{
    location.reload(true);
    // CODE }}}
}

ExternalActionsManager.show_EA_BONUS_CANCELLED = function(data) {
    /* DOC {{{
        Notifies the user that his active bonus was cancelled.

    }}} */

    // CODE {{{
    // display the action overlay {{{
    ExternalActionsManager.displayOverlay(
        'EA_BONUS_CANCELLED',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_BONUS_CANCELLED:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_BONUS_CANCELLED:MESSAGE:SKIPPABLE)]'.replace('(BONUS_CODE)', data['bonusCode'])
    );
    // }}}
    // CODE }}}
}


ExternalActionsManager.do_EA_BONUS_NOT_ALLOWED_FOR_GAME = function() {
    /* DOC {{{
        Redirects the user to the game selector.

    }}} */

    // CODE {{{
    // remove any displayed overlays
    overlayManager.removeAll();

    // load the cashier overlay
    overlayManager.load('cashier', 'https://www.freeslotsland.eu/en/user/cashier/json?selectTab=bonus');
    // CODE }}}
}

ExternalActionsManager.show_EA_BONUS_NOT_ALLOWED_FOR_GAME = function(data) {
    /* DOC {{{
        Notifies the user that his active bonus is not usable for the
        requested game.

    }}} */

    // CODE {{{
    // display the action overlay {{{
    ExternalActionsManager.displayOverlay(
        'EA_BONUS_NOT_ALLOWED_FOR_GAME',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_BONUS_NOT_ALLOWED_FOR_GAME:TITLE)]',
        '[UNKNOWN TRANSLATABLE TEXT ID (EXTERNAL_ACTION:EA_BONUS_NOT_ALLOWED_FOR_GAME:MESSAGE:UNSKIPPABLE)]',
        [
            {
                label               : "OK",
                onClick             : new Callback(ExternalActionsManager, "do_EA_BONUS_NOT_ALLOWED_FOR_GAME")
            }
        ]
    );
    // }}}
    // CODE }}}
}

window.EA = ExternalActionsManager;

// EXTERNAL ACTIONS }}}


// class ServerCommunicator {{{

function ServerCommunicator() {
    /* DOC {{{
        Provides support for communicating with server.

    }}} */

    // CODE {{{
    // request counter
    this.requestId = 0;

    // container for storing request options
    this.requestOptions = new Object();

    // whether the iframe communicator is ready or not
    this.iframeCommunicatorIsReady = false;

    // successfully loaded javascripts filled only by IE for ErrorJS needs
    this.loadedScripts = [];

    // prepare the iframe communicator for IE {{{
    if ($.browser.msie) {
        $(document).ready(function() {
            serverCommunicator.createIFrameCommunicator();
        });
    }
    // }}}
    // since iframe communicator is not needed pretend its ready {{{
    else {
        this.iframeCommunicatorIsReady = true;
    }
    // }}}

    // holds requests on hold (probably due to iframe not ready yet)
    this.requestsOnHold = new Array();

    // determine the base hostname and protocol {{{
    // use jQuery to easily get full location (protocol and hostname)
    var locationInfo = $('<a>').prop('href', window.location);

    // extract and save the hostname and protocol {{{
    this.hostname = locationInfo.prop("hostname");
    this.protocol = locationInfo.prop("protocol");
    // }}}
    // }}}
    // CODE }}}
}

ServerCommunicator.prototype.createIFrameCommunicator = function() {
    /* DOC {{{
        Creates an iframe communicator required for cross protocol IE
        communication.

    }}} */

    // CODE {{{
    // create the iframe and append it to the body {{{
    $('<iframe />', {
        name        : 'communicator',
        id          : 'communicator',
        style       : 'display: none;',
        src         : 'https://www.freeslotsland.eu/en/shared-iframe-communicator'
    }).appendTo('#page');
    // }}}
    // CODE }}}
}

ServerCommunicator.prototype.load = function(URI, data, successCallback, errorCallback, form, dataType) {
    /* DOC {{{
        Creates the definition of the load request and initiates the loading.

        URI                 : URI to load
        data                : additional post data
        successCallback     : callback to invoke upon successful load
        errorCallback       : callback to invoke when loading has failed
        form                : reference to the form object associated with the request (optional)
        dataType            : expected data type for response
    }}} */

    // CODE {{{
    // generate unique request id
    var id = "r_" + this.requestId++;

    // store the request parameters {{{
    this.requestOptions[id] = {
        URI                 : this.getAbsoluteURI(URI),
        data                : data,
        successCallback     : successCallback,
        errorCallback       : errorCallback,
        form                : form,
        dataType            : dataType,
        contentType         : 'application/x-www-form-urlencoded; charset=UTF-8'
    }
    // }}}

    // if the iframe communicator is not ready yet, put the request on hold {{{
    if (!this.iframeCommunicatorIsReady) {
        this.requestsOnHold.push(id);
        window.setTimeout(this.resumeLoading, 100);
    }
    // }}}
    // otherwise process the request immediately {{{
    else if (this.requestsOnHold.length == 0) {
        this._load(id);
    }
    // }}}

    // return the request id
    return id;
    // CODE }}}
}

ServerCommunicator.prototype._load = function(requestId) {
    /* DOC {{{
        Initiates processing of the request by invoking one of the request
        methods.

        requestId               : id of the request to process
    }}} */

    // CODE {{{
    // get the request options
    var requestOptions = this.requestOptions[requestId];

    // handle IE and cross protocol requests {{{
    if ($.browser.msie && this.isRequestCrossProtocol(requestOptions.URI) == true) {
        this.makeIframeRequest(requestId);
    }
    // }}}
    // otherwise use iframe for the request {{{
    else {
        this.makeDocumentRequest(requestId);
    }
    // }}}
    // CODE }}}
}

ServerCommunicator.prototype.getAbsoluteURI = function(URI) {
    /* DOC {{{
        Checks if the URI is relative and adds protocol and domain.

        URI             : URI to check and convert
    }}} */

    // CODE {{{
    // if the URI is relative, add protocol and hostname {{{
    if (URI.slice(0, 1) == "/") {
        URI = (this.protocol + "//" + this.hostname + URI);
    }
    // }}}

    // return the new URI
    return URI;
    // CODE }}}
}

ServerCommunicator.prototype.resumeLoading = function() {
    /* DOC {{{
        Proxy method since we lost object context.

    }}} */

    // CODE {{{
    serverCommunicator._resumeLoading();
    // CODE }}}
}

ServerCommunicator.prototype._resumeLoading = function() {
    /* DOC {{{
        Checks whether the iframe communicator is ready yet and either setups
        new check or continues to process the held requests.

    }}} */

    // CODE {{{
    // if the iframe is still not ready yet, setup another check and abort {{{
    if (!this.iframeCommunicatorIsReady) {
        window.setTimeout(this.resumeLoading, 100);
        return;
    }
    // }}}

    // get the requests on hold
    var requests = this.requestsOnHold.slice();

    // clear the original requests on hold list
    this.requestsOnHold = new Array();

    // if there are requests to process, process them now {{{
    for (var a = 0; a < requests.length; a++) {
        this._load(requests[a]);
    }
    // }}}
    // CODE }}}
}

ServerCommunicator.prototype.loadJSON = function(URI, data, successCallback, errorCallback, form, trackPage) {
    /* DOC {{{
        Creates a JSON request

        URI                 : URI to load
        data                : additional post data
        successCallback     : callback to invoke upon successful load
        errorCallback       : callback to invoke when loading has failed
        form                : reference to the form object associated with the request (optional)
        trackPage           : whether to track this request
    }}} */

    // CODE {{{
    // initiate the request
    var requestId = this.load(URI, data, successCallback, errorCallback, form, 'json');

    // track the JSON request if requested {{{
    if (typeof trackPage !== "undefined" || trackPage == true) {
        Utils.pageTracker(URI);
    }
    // }}}

    // return the request id
    return requestId;
    // CODE }}}
}

ServerCommunicator.prototype.loadHTML = function(URI, data, successCallback, errorCallback, form) {
    /* DOC {{{
        Convenience method for loading HTML data.

        URI                 : URI to load
        data                : additional post data
        successCallback     : callback to invoke upon successful load
        errorCallback       : callback to invoke when loading has failed
        form                : reference to the form object associated with the request (optional)
    }}} */

    // CODE {{{
    // initiate the request
    var requestId = this.load(URI, data, successCallback, errorCallback, form, 'text');

    // track the HTML request
    Utils.pageTracker(URI);

    // return the request id
    return requestId;
    // CODE }}}
}

ServerCommunicator.prototype.loadCSS = function(URI, data, successCallback, errorCallback) {
    /* DOC {{{
        Method for loading CSS data.

        URI                 : URI to load
        data                : additional post data
        successCallback     : callback to invoke upon successful load
        errorCallback       : callback to invoke when loading has failed
        form                : reference to the form object associated with the request (optional)
    }}} */

    // CODE {{{
    // initiate the request
    var requestId = this.load(URI, data, successCallback, errorCallback, null, 'text');

    // return the request id
    return requestId;
    // CODE }}}
}

ServerCommunicator.prototype.loadScript = function(URI, data, successCallback, errorCallback) {
    /* DOC {{{
        Method for loading CSS data.

        URI                 : URI to load
        data                : additional post data
        successCallback     : callback to invoke upon successful load
        errorCallback       : callback to invoke when loading has failed
        form                : reference to the form object associated with the request (optional)
    }}} */

    // CODE {{{
    // initiate the request
    var requestId = this.load(URI, data, successCallback, errorCallback, null, 'json');

    // return the request id
    return requestId;
    // CODE }}}
}

ServerCommunicator.prototype.embedScript = function(URI, successCallback, errorCallback) {
    /* DOC {{{
        Embeds the specified script URI to current page.

    }}} */

    // CODE {{{
    var thisScope = this;

    $.ajax({
        url         : URI,
        dataType    : "text",
        cache       : true
    }).done(
        function(script, textStatus) {
            // embed script into page
            $('<script type="text/javascript">' + script + '</script>').appendTo($("head"));

            // successfully loaded javascript is saved for ErrorJS needs
            thisScope.loadedScripts.push({
                uri:    URI,
                script: script
            });

            if (successCallback) {
                successCallback();
            }
        }
    ).fail(
        function(jqxhr, settings, exception) {
            if (errorCallback) {
                errorCallback();
            }
        }
    );
    // CODE }}}
}

ServerCommunicator.prototype.makeDocumentRequest = function(requestId) {
    /* DOC {{{
        Performs the request using the document's ajax (through jQuery)
        support.

        requestId           : id of the request do create
    }}} */

    // CODE {{{
    // get the request options
    var request = this.requestOptions[requestId];

    // create the base request URI
    var requestURI = request.URI;

    // add 'sid' to the request URI {{{
    if (requestURI.indexOf("sid") == -1) {
        // if there are no query variables, add 'sid' to beginning of query string {{{
        if (requestURI.indexOf("?") == -1) {
            requestURI += "?sid=" + window.initData['user']['sid'];
        }
        // }}}
        // otherwise append 'sid' to the end of query string {{{
        else {
            requestURI += "&sid=" + window.initData['user']['sid'];
        }
        // }}}
    }
    // }}}

    // perform the ajax request using the XDomainRequest in MSIE {{{
    if ($.browser.msie && window.XDomainRequest) {
        // create the request handler
        var xdr = new XDomainRequest();

        // store the 'requestId'
        xdr.requestId = requestId;

        // open connection to the server
        xdr.open("POST", requestURI);

        // add 'onload' handler which parses the response and invoke's request's success callback {{{
        xdr.onload = function () {
            // make sure the request is asynchronous {{{
            var dom  = new ActiveXObject("Microsoft.XMLDOM");
            dom.async = false;
            // }}}

            // get the response data
            var response = xdr.responseText;

            // parse the JSON response {{{
            if (request.dataType == 'json') {
                response = JSON.parse(response);
            }
            // }}}

            // invoke the success callback
            serverCommunicator.onSuccess(requestId, response);
        };
        // }}}

        // add 'onerror' handler which invokes request's error callback {{{
        xdr.onerror = function() {
            serverCommunicator.onError(requestId, xdr.responseText);
        };
        // }}}

        // prepare request data {{{
        // get data stored in the request definition
        var requestData = request.data;

        // convert the request data to query string {{{
        if (typeof requestData === "object") {
            requestData = $.param(requestData);
        }
        // }}}
        // }}}

        // these callbacks are added purely to ensure XDomainRequest does not
        // fail in some versions of IE {{{
        xdr.onprogress = function(){ };
        xdr.ontimeout = function(){ };
        // }}}

        // set time out of 10 seconds on the request
        xdr.timeout = 10000;

        // perform the request (with a delay to avoid nasty XDR bugs) {{{
        window.setTimeout(
            function () {
                xdr.send(requestData)
            },
            500
        );
        // }}}
    }
    // }}}
    // perform the ajax request for remaining browsers {{{
    else {
        // perform the request {{{
        var request = $.ajax({
            url             : requestURI,
            data            : request.data,
            dataType        : request.dataType,
            contentType     : request.contentType,
            timeout         : 60000,
            type            : 'POST'
        });
        // }}}

        // add the 'success' callback {{{
        request.done(
            function(response) {
                serverCommunicator.onSuccess(requestId, response);
            }
        );
        // }}}

        // add the 'fail' callback {{{
        request.fail(
            function(response) {
                serverCommunicator.onError(requestId, response);
            }
        );
        // }}}
    }
    // }}}
    // CODE }}}
}

ServerCommunicator.prototype.makeIframeRequest = function(requestId) {
    /* DOC {{{
        Performs the request using the iFrame method (cross protocol).

        requestId           : id of the request do create
    }}} */

    // CODE {{{
    // get the request options
    var request = this.requestOptions[requestId];

    // perform the request {{{
    pm({
        target      : window.frames["communicator"],
        type        : 'iframeRequest',
        data        : {
            url             : request.URI,
            sid             : window.initData['user']['sid'],
            dataType        : request.dataType,
            data            : request.data,
            contentType     : request.contentType,
            requestId       : requestId,
            success         : function(response) {
                serverCommunicator.onSuccess(requestId, response);
            },
            error           : function(response) {
                serverCommunicator.onError(requestId, response);
            }
        }
    });
    // }}}
    // CODE }}}
}

ServerCommunicator.prototype.onSuccess = function(requestId, response) {
    /* DOC {{{
        Invoked when the request was completed successfuly. Invokes the
        request's success callback.

        requestId               : id of the request
        response                : server response data
    }}} */

    // CODE {{{
    // try invoking the success callback {{{
    try {
        this.requestOptions[requestId].successCallback.call(response, this.requestOptions[requestId].form);
    } catch (e) {

    }
    // }}}

    // process external actions for JSON requests {{{
    if (this.requestOptions[requestId].dataType == 'json') {
        ExternalActionsManager.setActions(response.actions);
    }
    // }}}

    // display error if request has failed {{{
    if ((response.status == 0 && $.isEmptyObject(response.invalidFields)) && (typeof response.error !== "undefined" && response.error.length > 0)) {
        showError(texts["ERROR:CLIENT:LOADING_FAILED"], false, true);
    }
    // }}}
    // CODE }}}
}

ServerCommunicator.prototype.onError = function(requestId, response) {
    /* DOC {{{
        Invoked when the request has failed. This means we didn't get usable
        server response due to failed connection or some other problem on the
        way.

        requestId               : id of the request
        response                : server response data
    }}} */

    // CODE {{{
    // display an error message
    showError(texts["ERROR:CLIENT:LOADING_FAILED"], false, true);

    // invoke the error callback if it exists {{{
    try {
        this.requestOptions[requestId].errorCallback.call(response, this.requestOptions[requestId].form);
    } catch (e) {
    }
    // }}}
    // CODE }}}
}

ServerCommunicator.prototype.iframeReady = function() {
    /* DOC {{{
        Notifies the server communicator that the iframe for cross domain requests is ready now.

    }}} */

    // CODE {{{
    serverCommunicator.iframeCommunicatorIsReady = true;
    // CODE }}}
}

ServerCommunicator.prototype.iframeResponse = function(response) {
    /* DOC {{{
        Method used for receiving the response from an iframe request.

        response                : server response data
    }}} */

    // CODE {{{
    // try to process the response {{{
    try {
        // determien the request id for this response
        var requestId = response.requestId;

        // get the requests ajax options
        var requestOptions = serverCommunicator.requestOptions[requestId];

        // get the response data
        var responseData = response.response;

        // parse the JSON response {{{
        if (typeof responseData === "string" && requestOptions.dataType == 'json') {
            responseData = JSON.parse(responseData);
        }
        // }}}

        // if an error occured, invoke error callback {{{
        if (response.error == 1) {
            serverCommunicator.onError(requestId, responseData);
        }
        // }}}
        // otherwise invoke the success callback {{{
        else {
            serverCommunicator.onSuccess(requestId, responseData);
        }
        // }}}
    }
    // }}}
    // otherwise fail silently {{{
    catch (e) {
    }
    // }}}
    // CODE }}}
}

ServerCommunicator.prototype.isRequestCrossProtocol = function(URI) {
    /* DOC {{{
        Determines whether the specified URI would be a cross protocol request
        or not.

        URI                 : URI to check
    }}} */

    // CODE {{{
    // get the URI protocol
    URIProtocol = this.getURIProtocol(URI);

    // if the protocols match, its not a cross protocol request {{{
    if (URIProtocol == document.location.protocol) {
        return false;
    }
    // }}}
    // otherwise it is a cross protocol request {{{
    else {
        return true;
    }
    // }}}
    // CODE }}}
}

ServerCommunicator.prototype.getURIProtocol = function(URI) {
    /* DOC {{{
        Determines the protocol for the specified URI and returns it.

        URI                 : URI to check
    }}} */

    // CODE {{{
    // https {{{
    if (URI.indexOf("https://") != -1) {
        return "https:";
    }
    // }}}
    // http {{{
    else if (URI.indexOf("http://")) {
        return "http:";
    }
    // }}}
    // document protocol {{{
    else {
        return document.location.protocol;
    }
    // }}}
    // CODE }}}
}

// }}}



// setup global variables and managers {{{

// available currency symbols {{{
var CURRENCY_REAL_PLAY = '$';
var CURRENCY_FREE_PLAY = '[UNKNOWN TRANSLATABLE TEXT ID (CURRENCY:SYMBOL:FP_CREDIT:LONG)] ';
// }}}

// countries which require state to be selected {{{
var stateCodeRequiredCountries = {
    'country_224'       : true, // US
    'country_13'        : true, // AUSTRALIA
    'country_38'        : true  // CANADA
}
// }}}

// create instances of the globally accessible managers {{{
// create the server communicator
var serverCommunicator = new ServerCommunicator();

// register the iframeReady and iframeResponse to receive iframe communicator messages {{{
pm.bind("iframeReady", serverCommunicator.iframeReady);
pm.bind("iframeResponse", serverCommunicator.iframeResponse);
// }}}

// create the callbacks container
var callbacksContainer = new CallbacksContainer();
// }}}
// }}}

// register dynamic elements for overlays {{{
var protocolURIPart = ('https:' == document.location.protocol ? 'https://' : 'http://')
// }}}

function checkReferrer() {
        /* DOC {{{
                Checks current window referrer. Used to decide, whether display
                registration button or bonus timer. If the referrer host name is the
                same as homepage's host name (self window request), or there's no
                referrer (direct URI), don't allow to display the bonus clock. In other
                cases - links from other sites or search engines, set flag to display
                the bonus timer.

        }}} */

        // CODE {{{
        // window referrer reference
        var ref = document.referrer;

        // system domain reference
        var systemDomain = "www.freeslotsland.eu";

        // init parser object - empty element
        var parser = document.createElement('a');

        // store the referrer uri in the parser object
        parser.href = ref;

        // if no referrer (direct URI), do not display the bonus timer too {{{
        if((ref == "") || (ref == undefined) || (ref == null)) {
                return false;
        }
        // }}}

        // match the hostnames, if referrer hostname is the same as domain host name, referrer was our site {{{
        if (parser.hostname == systemDomain) {
                return false;
        }
        // }}}

        // allow to display the bonus timer
        return true;
        // CODE }}}
}

function onLoad() {
    /* DOC {{{
        Client initialization when loading of the document has completed and
        all elements are available and ready.

    }}} */

    // CODE {{{
    // if 'userStatus' data are supplied in page's init data, re-send them to the UserStatus
    if ((typeof initData !== "undefined") && (typeof initData['userStatus'] !== undefined)) {
        UserStatus.onLoaded(initData['userStatus']);
    }

    // if variable with method callbacks that needs to be processed on load event
    // is defined, process all defined callbacks {{{
    if (typeof onloadProcessQueue !== "undefined") {
        while (onloadProcessQueue.length > 0) {
            var item = onloadProcessQueue.shift();

            item.callback.call(item.scope, item.params);
        }
    }
    // }}}

    // insert the registration helper (if needed) {{{
    if (((typeof initData === "undefined") || (initData['userStatus']['userType']) == 0) && ($("#registration_helper").length > 0)) {
        $("#registration_helper").flash({
            id                      : 'registration_helper',
            src                     : '//media.freeslotsland.eu/en/flash/boot/registrationHelper.swf?build=201904161200',
            width                   : 1,
            height                  : 1,
            allowscriptaccess       : 'always',
            wmode                   : 'transparent',
            swliveconnect           : 'true',
            availparams             : ['swliveconnect', 'src', 'allowscriptaccess', 'wmode']
        });
    }
    // }}}
    // CODE }}}
}

$(window).load(function() {
    // due to sometimes buggy 'onload' event reporting, use a delay to execute
    // the onload stuff
    window.setTimeout(onLoad, 1);
});

