';
+ }
+ pokemonhtml = '
' + pokemonhtml + '
';
+ if (selfS.n === 1) {
+ if (selfS.initialized) self.rightbarElem.html('
' + sanitize(selfS.name) + '
' + pokemonhtml + '
').find('.trainer').css('opacity',1);
+ else self.rightbarElem.find('.trainer').css('opacity',0.4);
+ } else {
+ if (selfS.initialized) self.leftbarElem.html('
' + sanitize(selfS.name) + '
' + pokemonhtml + '
').find('.trainer').css('opacity',1);
+ else self.leftbarElem.find('.trainer').css('opacity',0.4);
+ }
+ };
+ this.addSideCondition = function (condition) {
+ condition = toId(condition);
+ if (selfS.sideConditions[condition]) {
+ if (condition === 'spikes' || condition === 'toxicspikes') {
+ selfS.sideConditions[condition][2]++;
+ if (condition === 'spikes' && selfS.sideConditions[condition][2] == 2) {
+ self.spriteElemsFront[selfS.n].append('
');
+ curelem = self.spriteElemsFront[selfS.n].children().last();
+ curelem.css(self.pos({
+ display: 'block',
+ x: selfS.x + 50,
+ y: selfS.y - 40,
+ z: selfS.z,
+ scale: .3
+ }, BattleEffects.caltrop));
+ selfS.sideConditions['spikes'][1] = selfS.sideConditions['spikes'][1].add(curelem);
+ } else if (condition === 'spikes') {
+ self.spriteElemsFront[selfS.n].append('
');
+ curelem = self.spriteElemsFront[selfS.n].children().last();
+ curelem.css(self.pos({
+ display: 'block',
+ x: selfS.x + 30,
+ y: selfS.y - 45,
+ z: selfS.z,
+ scale: .3
+ }, BattleEffects.caltrop));
+ selfS.sideConditions['spikes'][1] = selfS.sideConditions['spikes'][1].add(curelem);
+ } else if (condition === 'toxicspikes') {
+ self.spriteElemsFront[selfS.n].append('
');
+ curelem = self.spriteElemsFront[selfS.n].children().last();
+ curelem.css(self.pos({
+ display: 'block',
+ x: selfS.x - 15,
+ y: selfS.y - 35,
+ z: selfS.z,
+ scale: .3
+ }, BattleEffects.poisoncaltrop));
+ selfS.sideConditions['toxicspikes'][1] = selfS.sideConditions['toxicspikes'][1].add(curelem);
+ }
+ }
+ return;
+ }
+ var elem, curelem;
+ switch (condition) {
+ case 'reflect':
+ self.spriteElemsFront[selfS.n].append('
');
+ curelem = self.spriteElemsFront[selfS.n].children().last();
+ curelem.css(self.pos({
+ display: 'block',
+ x: selfS.x,
+ y: selfS.y,
+ z: selfS.behind(-17),
+ xscale: 1,
+ yscale: 0,
+ opacity: .1
+ }, BattleEffects.none)).animate(self.pos({
+ x: selfS.x,
+ y: selfS.y,
+ z: selfS.behind(-17),
+ xscale: 1,
+ yscale: .5,
+ opacity: .7
+ }, BattleEffects.none)).animate({
+ opacity: .3
+ }, 300);
+ elem = curelem;
+ selfS.sideConditions[condition] = [condition, elem, 5];
+ break;
+ case 'safeguard':
+ self.spriteElemsFront[selfS.n].append('
');
+ curelem = self.spriteElemsFront[selfS.n].children().last();
+ curelem.css(self.pos({
+ display: 'block',
+ x: selfS.x,
+ y: selfS.y,
+ z: selfS.behind(-20),
+ xscale: 1,
+ yscale: 0,
+ opacity: .1
+ }, BattleEffects.none)).animate(self.pos({
+ x: selfS.x,
+ y: selfS.y,
+ z: selfS.behind(-20),
+ xscale: 1,
+ yscale: .5,
+ opacity: .7
+ }, BattleEffects.none)).animate({
+ opacity: .2
+ }, 300);
+ elem = curelem;
+ selfS.sideConditions[condition] = [condition, elem, 5];
+ break;
+ case 'lightscreen':
+ self.spriteElemsFront[selfS.n].append('
');
+ curelem = self.spriteElemsFront[selfS.n].children().last();
+ curelem.css(self.pos({
+ display: 'block',
+ x: selfS.x,
+ y: selfS.y,
+ z: selfS.behind(-23),
+ xscale: 1,
+ yscale: 0,
+ opacity: .1
+ }, BattleEffects.none)).animate(self.pos({
+ x: selfS.x,
+ y: selfS.y,
+ z: selfS.behind(-23),
+ xscale: 1,
+ yscale: .5,
+ opacity: .7
+ }, BattleEffects.none)).animate({
+ opacity: .3
+ }, 300);
+ elem = curelem;
+ selfS.sideConditions[condition] = [condition, elem, 5];
+ break;
+ case 'mist':
+ self.spriteElemsFront[selfS.n].append('
');
+ curelem = self.spriteElemsFront[selfS.n].children().last();
+ curelem.css(self.pos({
+ display: 'block',
+ x: selfS.x,
+ y: selfS.y,
+ z: selfS.behind(-27),
+ xscale: 1,
+ yscale: 0,
+ opacity: .1
+ }, BattleEffects.none)).animate(self.pos({
+ x: selfS.x,
+ y: selfS.y,
+ z: selfS.behind(-27),
+ xscale: 1,
+ yscale: .5,
+ opacity: .7
+ }, BattleEffects.none)).animate({
+ opacity: .2
+ }, 300);
+ elem = curelem;
+ selfS.sideConditions[condition] = [condition, elem, 5];
+ break;
+ case 'tailwind':
+ selfS.sideConditions[condition] = [condition, null, 5];
+ break;
+ case 'stealthrock':
+ self.spriteElemsFront[selfS.n].append('
');
+ curelem = self.spriteElemsFront[selfS.n].children().last();
+ curelem.css(self.pos({
+ display: 'block',
+ x: selfS.leftof(-40),
+ y: selfS.y - 10,
+ z: selfS.z,
+ opacity: .5,
+ scale: .3
+ }, BattleEffects.rock1));
+ elem = curelem;
+ selfS.sideConditions[condition] = [condition, elem, 1];
+ break;
+ case 'spikes':
+ self.spriteElemsFront[selfS.n].append('
');
+ curelem = self.spriteElemsFront[selfS.n].children().last();
+ curelem.css(self.pos({
+ display: 'block',
+ x: selfS.x - 25,
+ y: selfS.y - 40,
+ z: selfS.z,
+ scale: .3
+ }, BattleEffects.caltrop));
+ elem = curelem;
+ selfS.sideConditions[condition] = [condition, elem, 1];
+ break;
+ case 'toxicspikes':
+ self.spriteElemsFront[selfS.n].append('
');
+ curelem = self.spriteElemsFront[selfS.n].children().last();
+ curelem.css(self.pos({
+ display: 'block',
+ x: selfS.x + 5,
+ y: selfS.y - 40,
+ z: selfS.z,
+ scale: .3
+ }, BattleEffects.poisoncaltrop));
+ elem = curelem;
+ selfS.sideConditions[condition] = [condition, elem, 1];
+ break;
+ default:
+ selfS.sideConditions[condition] = [condition, null, 1];
+ }
+ };
+ this.removeSideCondition = function (condition) {
+ condition = toId(condition);
+ if (!selfS.sideConditions[condition]) return;
+ if (selfS.sideConditions[condition][1]) selfS.sideConditions[condition][1].remove();
+ delete selfS.sideConditions[condition];
+ };
+ this.newPokemon = function (species, replaceSlot) {
+ var id;
+ var pokeobj;
+ if (species.species) {
+ pokeobj = species;
+ species = pokeobj.species;
+ id = pokeobj.id;
+ }
+ var poke = Tools.getTemplate(species);
+ poke = $.extend(new Pokemon(species), poke);
+ poke.side = selfS;
+ poke.atkStat = 10;
+ poke.defStat = 10;
+ poke.spaStat = 10;
+ poke.spdStat = 10;
+ poke.maxhp = 1000;
+ if (self.gen === 5 && (species === 'Mienfoo' || species === 'Mienshao' || species === 'Tangrowth' || species === 'Slowking' || species === 'Slowbro')) {
+ poke.ability = '??Regenerator';
+ }
+ if (self.gen > 2 && (species === 'Staryu' || species === 'Starmie' || species === 'Shaymin' || species === 'Blissey' || species === 'Chansey' || species === 'Celebi')) {
+ poke.ability = '??NaturalCure';
+ }
+ if (pokeobj) poke = $.extend(poke, pokeobj);
+ if ((!poke.ability || poke.ability.substr(0,2) === '??') && poke.baseAbility) poke.ability = poke.baseAbility;
+ poke.id = id;
+ poke.reset();
+ poke.sprite = new self.Sprite(Tools.getSpriteData(poke, selfS.n), selfS.x, selfS.y, selfS.z, selfS.n);
+
+ if (typeof replaceSlot !== 'undefined') {
+ selfS.pokemon[replaceSlot] = poke;
+ } else {
+ selfS.pokemon.push(poke);
+ }
+ if (selfS.pokemon.length == 7) {
+ // something's wrong
+ self.logConsole('corruption');
+
+ // the other possibility is Illusion, which we'll assume
+ var existingTable = {};
+ for (var i=0; i<6; i++) {
+ var poke1 = selfS.pokemon[i];
+ if (existingTable[poke1.searchid]) {
+ var j = existingTable[poke1.searchid];
+ var poke2 = selfS.pokemon[j];
+ if (selfS.active.indexOf(poke1) >= 0) {
+ selfS.pokemon.splice(j,1);
+ } else if (selfS.active.indexOf(poke2) >= 0) {
+ selfS.pokemon.splice(i,1);
+ } else if (poke1.fainted && !poke2.fainted) {
+ selfS.pokemon.splice(j,1);
+ } else {
+ selfS.pokemon.splice(i,1);
+ }
+ break;
+ }
+ existingTable[poke1.searchid] = i;
+ }
+ }
+ selfS.updateSidebar();
+
+ return poke;
+ };
+
+ this.getStatbarHTML = function (pokemon) {
+ var gender = '';
+ if (pokemon.gender === 'F') gender = '
♀ ';
+ if (pokemon.gender === 'M') gender = '
♂ ';
+ return '
' + sanitize(pokemon.name) + gender + (pokemon.level === 100 ? '' : ' L' + pokemon.level + ' ') + ' ';
+ };
+ this.switchIn = function (pokemon, slot) {
+ if (slot === undefined) slot = pokemon.slot;
+ selfS.active[slot] = pokemon;
+ pokemon.slot = slot;
+ pokemon.clearVolatile();
+ pokemon.lastmove = '';
+ self.lastmove = 'switch-in';
+ if (selfS.lastPokemon && selfS.lastPokemon.lastmove === 'batonpass') {
+ pokemon.copyVolatileFrom(selfS.lastPokemon);
+ }
+
+ self.message('' + sanitize(pokemon.side.name) + ' sent out ' + pokemon.getFullName() + '!');
+
+ pokemon.sprite.animSummon(slot);
+ if (pokemon.hasVolatile('substitute')) {
+ pokemon.sprite.animSub();
+ }
+ if (pokemon.statbarElem) {
+ pokemon.statbarElem.remove();
+ }
+ self.statElem.append(selfS.getStatbarHTML(pokemon));
+ pokemon.statbarElem = self.statElem.children().last();
+ selfS.updateStatbar(pokemon, true);
+ pokemon.side.updateSidebar();
+ if (self.fastForward) {
+ pokemon.statbarElem.css({
+ display: 'block',
+ left: pokemon.sprite.left - 80,
+ top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
+ opacity: 1
+ });
+ if (self.switchCallback) self.switchCallback(self, selfS);
+ return;
+ }
+ pokemon.statbarElem.css({
+ display: 'block',
+ left: pokemon.sprite.left - 80,
+ top: pokemon.sprite.top - 53 - pokemon.sprite.statbarOffset,
+ opacity: 0
+ });
+ pokemon.statbarElem.delay(300).animate({
+ top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
+ opacity: 1
+ }, 400);
+ if (self.switchCallback) self.switchCallback(self, selfS);
+ };
+ this.dragIn = function (pokemon, slot) {
+ if (slot === undefined) slot = pokemon.slot;
+ self.message('' + pokemon.getFullName() + ' was dragged out!');
+ if (pokemon === selfS.active[slot]) return;
+ var oldpokemon = selfS.active[slot];
+ selfS.lastPokemon = oldpokemon;
+ if (oldpokemon) oldpokemon.clearVolatile();
+ pokemon.clearVolatile();
+ pokemon.lastmove = '';
+ self.lastmove = 'switch-in';
+ selfS.active[slot] = pokemon;
+
+ if (oldpokemon === pokemon) return;
+
+ if (oldpokemon) {
+ oldpokemon.sprite.animDragOut();
+ }
+ pokemon.sprite.animDragIn(slot);
+ if (pokemon.statbarElem) {
+ pokemon.statbarElem.remove();
+ }
+ self.statElem.append(selfS.getStatbarHTML(pokemon));
+ pokemon.statbarElem = self.statElem.children().last();
+ selfS.updateStatbar(pokemon, true);
+ if (self.fastForward) {
+ if (oldpokemon) {
+ oldpokemon.statbarElem.remove();
+ oldpokemon.statbarElem = null;
+ }
+ pokemon.statbarElem.css({
+ display: 'block',
+ left: (selfS.n == 0 ? 100 : 340),
+ top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
+ opacity: 1
+ });
+ if (self.dragCallback) self.dragCallback(self, selfS);
+ return;
+ }
+ if (selfS.n == 0) {
+ if (oldpokemon) {
+ oldpokemon.statbarElem.animate({
+ left: pokemon.sprite.left - 130,
+ opacity: 0
+ }, 400, function () {
+ oldpokemon.statbarElem.remove();
+ oldpokemon.statbarElem = null;
+ });
+ }
+ pokemon.statbarElem.css({
+ display: 'block',
+ left: pokemon.sprite.left - 30,
+ top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
+ opacity: 0
+ });
+ pokemon.statbarElem.delay(300).animate({
+ left: pokemon.sprite.left - 80,
+ opacity: 1
+ }, 400);
+ } else {
+ if (oldpokemon) {
+ oldpokemon.statbarElem.animate({
+ left: pokemon.sprite.left - 30,
+ opacity: 0
+ }, 400, function () {
+ oldpokemon.statbarElem.remove();
+ oldpokemon.statbarElem = null;
+ });
+ }
+ pokemon.statbarElem.css({
+ display: 'block',
+ left: pokemon.sprite.left - 130,
+ top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
+ opacity: 0
+ });
+ pokemon.statbarElem.delay(300).animate({
+ left: pokemon.sprite.left - 80,
+ opacity: 1
+ }, 400);
+ }
+ if (self.dragCallback) self.dragCallback(self, selfS);
+ };
+ this.replace = function (pokemon, slot) {
+ if (slot === undefined) slot = pokemon.slot;
+ var oldpokemon = selfS.active[slot];
+ if (pokemon === oldpokemon) return;
+ selfS.lastPokemon = oldpokemon;
+ pokemon.clearVolatile();
+ if (oldpokemon) {
+ pokemon.lastmove = oldpokemon.lastmove;
+ pokemon.hp = oldpokemon.hp;
+ pokemon.maxhp = oldpokemon.maxhp;
+ pokemon.status = oldpokemon.status;
+ pokemon.copyVolatileFrom(oldpokemon, true);
+ }
+ selfS.active[slot] = pokemon;
+
+ if (oldpokemon) {
+ oldpokemon.sprite.animUnsummon(true);
+ }
+ pokemon.sprite.animSummon(slot, true);
+ if (oldpokemon) {
+ oldpokemon.statbarElem.remove();
+ oldpokemon.statbarElem = null;
+ }
+ if (pokemon.statbarElem) {
+ pokemon.statbarElem.remove();
+ }
+ self.statElem.append(selfS.getStatbarHTML(pokemon));
+ pokemon.statbarElem = self.statElem.children().last();
+ selfS.updateStatbar(pokemon, true);
+ pokemon.statbarElem.css({
+ display: 'block',
+ left: pokemon.sprite.left - 80,
+ top: pokemon.sprite.top - 73 - pokemon.sprite.statbarOffset,
+ opacity: 1
+ });
+ // not sure if we want a different callback
+ if (self.dragCallback) self.dragCallback(self, selfS);
+ };
+ this.switchOut = function (pokemon, slot) {
+ if (slot === undefined) slot = pokemon.slot;
+ if (pokemon.lastmove !== 'batonpass') {
+ pokemon.clearVolatile();
+ } else {
+ pokemon.removeVolatile('transform');
+ pokemon.removeVolatile('formechange');
+ }
+ self.message('' + sanitize(pokemon.side.name) + ' called ' + sanitize(pokemon.name) + ' back!');
+ selfS.lastPokemon = pokemon;
+ selfS.active[slot] = null;
+
+ if ((pokemon.ability === 'Regenerator' || pokemon.ability === '??Regenerator') && pokemon.hp < pokemon.maxhp) {
+ var damage = 100 / 3;
+ pokemon.hp += pokemon.maxhp * damage / 100;
+ if (pokemon.hp > pokemon.maxhp) {
+ damage -= 100 * (pokemon.hp - pokemon.maxhp) / pokemon.maxhp;
+ pokemon.hp = pokemon.maxhp;
+ }
+ }
+ if ((pokemon.ability === 'NaturalCure' || pokemon.ability === '??NaturalCure') && pokemon.status) {
+ pokemon.status = '';
+ }
+
+ selfS.updateStatbar(pokemon, true);
+ pokemon.sprite.animUnsummon();
+ if (self.fastForward) {
+ pokemon.statbarElem.remove();
+ pokemon.statbarElem = null;
+ return;
+ }
+ pokemon.statbarElem.animate({
+ top: pokemon.sprite.top - 43 - pokemon.sprite.statbarOffset,
+ opacity: 0
+ }, 300, function () {
+ pokemon.statbarElem.remove();
+ pokemon.statbarElem = null;
+ });
+ //pokemon.statbarElem.done(pokemon.statbarElem.remove());
+ };
+ this.faint = function (pokemon, slot) {
+ if (slot === undefined) slot = pokemon.slot;
+ pokemon.clearVolatile();
+ selfS.lastPokemon = pokemon;
+ selfS.active[slot] = null;
+
+ self.message('' + pokemon.getName() + ' fainted!');
+
+ pokemon.fainted = true;
+ pokemon.zerohp = true;
+ pokemon.hp = 0;
+ pokemon.side.updateStatbar(pokemon, false, true);
+ pokemon.side.updateSidebar();
+
+ pokemon.sprite.animFaint();
+ pokemon.statbarElem.animate({
+ opacity: 0
+ }, 300, function () {
+ pokemon.statbarElem.remove();
+ pokemon.statbarElem = null;
+ });
+ if (self.faintCallback) self.faintCallback(self, selfS);
+ };
+ this.updateStatbar = function (pokemon, updatePrevhp, updateHp) {
+ if (!pokemon) {
+ if (selfS.active[0]) selfS.updateStatbar(selfS.active[0], updatePrevhp, updateHp);
+ if (selfS.active[1]) selfS.updateStatbar(selfS.active[1], updatePrevhp, updateHp);
+ return;
+ }
+ if (!pokemon || !pokemon.statbarElem) {
+ return;
+ }
+ if (updatePrevhp) {
+ pokemon.statbarElem.find('.prevhp').css('width', pokemon.hpWidth(150) + 1);
+ }
+ if (updatePrevhp || updateHp) {
+ var w = pokemon.hpWidth(150);
+ pokemon.statbarElem.find('.hp').css({
+ width: w,
+ 'border-right-width': (w ? 1 : 0)
+ });
+ pokemon.statbarElem.find('.hptext').html('' + pokemon.hpWidth(100) + '%');
+ }
+ var status = '';
+ if (pokemon.status === 'brn') {
+ status += '
BRN ';
+ } else if (pokemon.status === 'psn') {
+ status += '
PSN ';
+ } else if (pokemon.status === 'tox') {
+ status += '
TOX ';
+ } else if (pokemon.status === 'slp') {
+ status += '
SLP ';
+ } else if (pokemon.status === 'par') {
+ status += '
PAR ';
+ } else if (pokemon.status === 'frz') {
+ status += '
FRZ ';
+ }
+ for (x in pokemon.boosts) {
+ if (pokemon.boosts[x]) {
+ status += '
' + pokemon.getBoost(x) + ' ';
+ }
+ }
+ var statusTable = {
+ confusion: '
Confused ',
+ healblock: '
Heal Block ',
+ yawn: '
Drowsy ',
+ smackdown: '
Grounded ',
+ flashfire: '
Flash Fire ',
+ imprison: '
Imprisoning foe ',
+ formechange: '',
+ typechange: '',
+ autotomize: '
Lightened ',
+ miracleeye: '
Miracle Eye ',
+ foresight: '
Foresight ',
+ telekinesis: '
Telekinesis ',
+ transform: '
Transformed ',
+ powertrick: '
Power Trick ',
+ curse: '
Curse ',
+ nightmare: '
Nightmare ',
+ attract: '
Attract ',
+ torment: '
Torment ',
+ taunt: '
Taunt ',
+ disable: '
Disable ',
+ embargo: '
Embargo ',
+ ingrain: '
Ingrain ',
+ aquaring: '
Aqua Ring ',
+ stockpile1: '
Stockpile ',
+ stockpile2: '
Stockpile×2 ',
+ stockpile3: '
Stockpile×3 ',
+ perish1: '
Perish next turn ',
+ perish2: '
Perish in 2 ',
+ perish3: '
Perish in 3 ',
+ airballoon: '
Balloon ',
+ leechseed: '
Leech Seed ',
+ encore: '
Encore ',
+ mustrecharge: '
Must recharge ',
+ bide: '
Bide ',
+ magnetrise: '
Magnet Rise ',
+ smackdown: '
Smack Down ',
+ focusenergy: '
Focus Energy ',
+ slowstart: '
Slow Start ',
+ doomdesire: '',
+ futuresight: '',
+ mimic: '
Mimic ',
+ watersport: '
Water Sport ',
+ mudsport: '
Mud Sport ',
+ substitute: '',
+ // sub graphics are handled elsewhere, see Battle.Sprite.animSub()
+ roost: '
Landed ',
+ protect: '
Protect ',
+ quickguard: '
Quick Guard ',
+ wideguard: '
Wide Guard ',
+ helpinghand: '
Helping Hand ',
+ magiccoat: '
Magic Coat ',
+ destinybond: '
Destiny Bond ',
+ snatch: '
Snatch ',
+ grudge: '
Grudge ',
+ endure: '
Endure ',
+ focuspunch: '
Focusing '
+ };
+ for (i in pokemon.volatiles) {
+ if (typeof statusTable[i] === 'undefined') status += '
[['+i+']] ';
+ else status += statusTable[i];
+ }
+ for (i in pokemon.turnstatuses) {
+ if (typeof statusTable[i] === 'undefined') status += '
[['+i+']] ';
+ else status += statusTable[i];
+ }
+ for (i in pokemon.movestatuses) {
+ if (typeof statusTable[i] === 'undefined') status += '
[['+i+']] ';
+ else status += statusTable[i];
+ }
+ var statusbar = pokemon.statbarElem.find('.status');
+ statusbar.html(status);
+ }
+ };
+ this.sidesSwitched = false;
+ this.switchSides = function () {
+ self.sidesSwitched = !self.sidesSwitched;
+ if (self.sidesSwitched) {
+ self.mySide = self.p2;
+ self.yourSide = self.p1;
+ } else {
+ self.mySide = self.p1;
+ self.yourSide = self.p2;
+ }
+ self.mySide.n = 0;
+ self.yourSide.n = 1;
+ self.sides[0] = self.mySide;
+ self.sides[1] = self.yourSide;
+
+ self.mySide.updateSidebar();
+ self.mySide.updateSprites();
+ self.yourSide.updateSidebar();
+ self.yourSide.updateSprites();
+ // nothing else should need updating - don't call this function after sending out pokemon
+ }
+
+ this.messageActive = false;
+ this.message = function (message, hiddenmessage) {
+ if (message && !self.messageActive) {
+ self.log('
');
+ }
+ if (message && !self.fastForward) {
+ if (!self.messageActive) {
+ self.messagebarElem.empty();
+ self.messagebarElem.css({
+ display: 'block',
+ opacity: 0,
+ height: 'auto'
+ });
+ self.messagebarElem.animate({
+ opacity: 1
+ }, 300);
+ }
+ self.hiddenMessageElem.append('
');
+ var messageElem = self.hiddenMessageElem.children().last();
+ messageElem.html(message);
+ messageElem.css({
+ display: 'block',
+ opacity: 0
+ });
+ messageElem.animate({
+ height: 'hide'
+ }, 1, function () {
+ messageElem.appendTo(self.messagebarElem);
+ messageElem.animate({
+ height: 'show',
+ 'padding-bottom': 4,
+ opacity: 1
+ }, 300);
+ });
+ self.activityWait(messageElem);
+ }
+ self.messageActive = true;
+ self.log('
' + message + (hiddenmessage ? hiddenmessage : '') + '
');
+ }
+ this.endAction = function () {
+ if (self.messageActive) {
+ self.messageActive = false;
+ if (!self.fastForward) {
+ self.messagebarElem.delay(self.messageDelay).animate({
+ height: 'toggle',
+ opacity: 0
+ }, 300);
+ self.activityWait(self.messagebarElem);
+ }
+ }
+ }
+
+ //
+ // activities
+ //
+ this.start = function () {
+ self.log('
Battle between ' + sanitize(self.p1.name) + ' and ' + sanitize(self.p2.name) + ' started!
');
+ if (self.startCallback) self.startCallback(self);
+ }
+ this.winner = function (winner) {
+ if (self.fastForward !== -2) self.fastForwardOff();
+ if (winner) self.message('' + winner + ' won the battle!');
+ else self.message('Tie between ' + sanitize(self.p1.name) + ' and ' + sanitize(self.p2.name) + '!');
+ self.done = 1;
+ }
+ this.prematureEnd = function () {
+ if (self.fastForward !== -2) self.fastForwardOff();
+ self.message('This replay ends here.');
+ self.done = 1;
+ }
+ this.setTurn = function (turnnum) {
+ turnnum = parseInt(turnnum);
+ self.turn = turnnum;
+ self.updateWeatherLeft();
+
+ if (self.mySide.active[0]) self.mySide.active[0].clearTurnstatuses();
+ if (self.mySide.active[1]) self.mySide.active[1].clearTurnstatuses();
+ if (self.yourSide.active[0]) self.yourSide.active[0].clearTurnstatuses();
+ if (self.yourSide.active[1]) self.yourSide.active[1].clearTurnstatuses();
+ self.mySide.updateStatbar(null, true);
+ self.yourSide.updateStatbar(null, true);
+
+ self.log('
Turn ' + turnnum + ' ');
+
+ var prevTurnElem = self.turnElem.children();
+ if (self.fastForward) {
+ if (prevTurnElem.length) prevTurnElem.html('Turn ' + turnnum);
+ else self.turnElem.append('
Turn ' + turnnum + '
');
+ if (self.turnCallback) self.turnCallback(self);
+ if (self.fastForward > -1 && turnnum >= self.fastForward) {
+ self.fastForwardOff();
+ }
+ return;
+ }
+ self.turnElem.append('
Turn ' + turnnum + '
');
+ var newTurnElem = self.turnElem.children().last();
+ newTurnElem.css({
+ display: 'block',
+ opacity: 0,
+ left: 160
+ });
+ newTurnElem.animate({
+ opacity: 1,
+ left: 110
+ }, 500).animate({
+ opacity: .4
+ }, 1500);
+ prevTurnElem.animate({
+ opacity: 0,
+ left: 60
+ }, 500, function () {
+ prevTurnElem.remove();
+ });
+ self.activityWait(500);
+ if (self.turnCallback) self.turnCallback(self);
+ }
+ this.changeWeather = function (weather, poke, isUpkeep) {
+ weather = toId(weather);
+ var weatherTable = {
+ sunnyday: {
+ name: 'Sun',
+ startMessage: 'The sunlight turned harsh!',
+ abilityMessage: "'s Drought intensified the sun's rays!",
+ //upkeepMessage: 'The sunlight is strong!',
+ endMessage: "The sunlight faded."
+ },
+ raindance: {
+ name: 'Rain',
+ startMessage: 'It started to rain!',
+ abilityMessage: "'s Drizzle made it rain!",
+ //upkeepMessage: 'Rain continues to fall!',
+ endMessage: 'The rain stopped.'
+ },
+ sandstorm: {
+ name: 'Sandstorm',
+ startMessage: 'A sandstorm kicked up!',
+ abilityMessage: "'s Sand Stream whipped up a sandstorm!",
+ upkeepMessage: 'The sandstorm rages.',
+ endMessage: 'The sandstorm subsided.'
+ },
+ hail: {
+ name: 'Hail',
+ startMessage: 'It started to hail!',
+ abilityMessage: "'s Snow Warning whipped up a hailstorm!",
+ upkeepMessage: 'The hail crashes down.',
+ endMessage: 'The hail stopped.'
+ }
+ };
+ if (!weather || weather === 'none') {
+ weather = '';
+ }
+ var newWeather = weatherTable[weather];
+ if (isUpkeep) {
+ if (!self.fastForward) {
+ self.weatherElem.animate({
+ opacity: 1.0
+ }, 400).animate({
+ opacity: .4
+ }, 400);
+ }
+ if (newWeather && newWeather.upkeepMessage) self.log('
' + newWeather.upkeepMessage + '
');
+ return;
+ }
+ if (newWeather) {
+ if (poke) {
+ self.message('
' + poke.getName() + newWeather.abilityMessage + ' ');
+ self.weatherTimeLeft = 0;
+ self.weatherMinTimeLeft = 0;
+ } else if (isUpkeep) {
+ self.log('
' + newWeather.upkeepMessage + '
');
+ self.weatherTimeLeft = 0;
+ self.weatherMinTimeLeft = 0;
+ } else {
+ self.message('
' + newWeather.startMessage + ' ');
+ if (self.turn === 0) {
+ self.weatherTimeLeft = 0;
+ self.weatherMinTimeLeft = 0;
+ } else {
+ self.weatherTimeLeft = 8;
+ self.weatherMinTimeLeft = 5;
+ }
+ }
+ }
+ if (self.weather && !newWeather) {
+ self.message(weatherTable[self.weather].endMessage);
+ }
+ self.updateWeather(weather);
+ }
+ this.updateWeatherLeft = function () {
+ for (var i = 0; i < self.pseudoWeather.length; i++) {
+ if (self.pseudoWeather[i][1] > 0) self.pseudoWeather[i][1]--;
+ }
+ if (self.weather && self.weatherTimeLeft) {
+ self.weatherTimeLeft--;
+ if (self.weatherMinTimeLeft != 0) self.weatherMinTimeLeft--;
+ }
+ self.updateWeather();
+ };
+ this.weatherLeft = function (weather) {
+ if (weather) {
+ for (var i = 0; i < self.pseudoWeather.length; i++) {
+ if (self.pseudoWeather[i][0] === weather) {
+ if (self.pseudoWeather[i][1]) {
+ return '
(' + self.pseudoWeather[i][1] + ' turn' + (self.pseudoWeather[i][1] == 1 ? '' : 's') + ' left) ';
+ }
+ return '';
+ }
+ }
+ return ''; // weather doesn't exist
+ }
+ if (self.weatherMinTimeLeft != 0) {
+ return '
(' + self.weatherMinTimeLeft + ' to ' + self.weatherTimeLeft + ' turns left) ';
+ }
+ if (self.weatherTimeLeft != 0) {
+ return '
(' + self.weatherTimeLeft + ' turn' + (self.weatherTimeLeft == 1 ? '' : 's') + ' left) ';
+ }
+ return '';
+ }
+ this.updateWeather = function (weather) {
+ var weatherNameTable = {
+ sunnyday: 'Sun',
+ raindance: 'Rain',
+ sandstorm: 'Sandstorm',
+ hail: 'Hail'
+ };
+
+ if (typeof weather === 'undefined') {
+ weather = self.weather;
+ }
+ if (weather === '' || weather === 'none' || weather === 'pseudo') {
+ weather = (self.pseudoWeather.length ? 'pseudo' : '');
+ }
+
+ var oldweather = self.weather;
+ self.weather = weather;
+
+ var weatherhtml = '';
+ if (weather) {
+ if (weather !== 'pseudo') {
+ weatherhtml += weatherNameTable[weather] + self.weatherLeft();
+ }
+ for (var i = 0; i < self.pseudoWeather.length; i++) {
+ weatherhtml += '
' + Tools.getMove(self.pseudoWeather[i][0]).name + self.weatherLeft(self.pseudoWeather[i][0]);
+ }
+ }
+ if (weather === oldweather) {
+ if (weather) self.weatherElem.html('
' + weatherhtml + ' ');
+ return;
+ }
+ if (oldweather) {
+ if (weather) {
+ self.weatherElem.animate({
+ opacity: 0
+ }, 300, function () {
+ self.weatherElem.css({
+ display: 'block'
+ });
+ self.weatherElem.attr('class', 'weather ' + weather + 'weather');
+ self.weatherElem.html('
' + weatherhtml + ' ');
+ });
+ } else {
+ self.weatherElem.animate({
+ opacity: 0
+ }, 500);
+ }
+ } else if (weather) {
+ self.weatherElem.css({
+ display: 'block',
+ opacity: 0
+ });
+ self.weatherElem.attr('class', 'weather ' + weather + 'weather');
+ self.weatherElem.html('
' + weatherhtml + ' ');
+ }
+ if (weather) {
+ if (self.fastForward) {
+ self.weatherElem.css({opacity:.4});
+ return;
+ }
+ self.weatherElem.animate({
+ opacity: 1.0
+ }, 400).animate({
+ opacity: .4
+ }, 400);
+ }
+ }
+ this.resultAnim = function (pokemon, result, type, i) {
+ if (self.fastForward) {
+ pokemon.side.updateStatbar(pokemon, false, true);
+ return;
+ }
+ if (!i) {
+ i = 0;
+ }
+ self.fxElem.append('
' + result + '
');
+ effectElem = self.fxElem.children().last();
+ effectElem.delay(i * 350 + self.animationDelay).css({
+ display: 'block',
+ opacity: 0,
+ top: pokemon.sprite.top - 5,
+ left: pokemon.sprite.left - 75
+ }).animate({
+ opacity: 1
+ }, 1);
+ effectElem.animate({
+ opacity: 0,
+ top: pokemon.sprite.top - 65
+ }, 1000, 'swing');
+ pokemon.side.updateStatbar(pokemon);
+ self.activityWait(effectElem);
+ }
+ this.damageAnim = function (pokemon, damage, i) {
+ if (!pokemon.statbarElem) return;
+ if (!i) {
+ i = 0;
+ }
+ var w = pokemon.hpWidth(150);
+ self.resultAnim(pokemon, '−' + Math.round(damage) + '%', 'bad', i);
+ pokemon.statbarElem.find('.hptext').html('' + pokemon.hpWidth(100) + '%');
+ if (!self.fastForward) pokemon.statbarElem.find('div.hp').delay(self.animationDelay).animate({
+ width: w,
+ 'border-right-width': w ? 1 : 0
+ }, 350);
+ }
+ this.healAnim = function (pokemon, damage, i) {
+ if (!pokemon.statbarElem) return;
+ if (!i) {
+ i = 0;
+ }
+ var w = pokemon.hpWidth(150);
+ self.resultAnim(pokemon, '+' + Math.round(damage) + '%', 'good', i);
+ pokemon.statbarElem.find('.hptext').html('' + pokemon.hpWidth(100) + '%');
+ if (!self.fastForward) pokemon.statbarElem.find('div.hp').animate({
+ width: w,
+ 'border-right-width': w ? 1 : 0
+ }, 350);
+ }
+ this.useMove = function (pokemon, move, target, kwargs) {
+ var fromeffect = Tools.getEffect(kwargs.from);
+ pokemon.clearMovestatuses();
+ pokemon.side.updateStatbar(pokemon, true);
+ if (move.id === 'focuspunch') {
+ pokemon.removeTurnstatus('focuspunch');
+ pokemon.side.updateStatbar(pokemon);
+ }
+ if (!target) {
+ target = pokemon.side.foe.active[0];
+ }
+ if (!target) {
+ target = pokemon.side.foe.missedPokemon;
+ }
+ if (!self.fastForward) {
+ // skip
+ if (kwargs.miss) {
+ target = target.side.missedPokemon;
+ }
+ if (kwargs.notarget) {
+ target = pokemon.side.foe.missedPokemon;
+ }
+ if (kwargs.prepare || kwargs.anim === 'prepare') {
+ self.prepareMove(pokemon, move, target);
+ } else if (!kwargs.still && !kwargs.notarget) {
+ move.anim(self, [pokemon.sprite, target.sprite]);
+ }
+ }
+ if (!kwargs.silent) {
+ switch (fromeffect.id) {
+ case 'snatch':
+ break;
+ case 'metronome':
+ self.message('Waggling a finger let it use
' + move.name + ' !');
+ break;
+ case 'naturepower':
+ self.message('Nature Power turned into
' + move.name + ' !');
+ break;
+ case 'sleeptalk':
+ default:
+ self.message(pokemon.getName() + ' used
' + move.name + ' !');
+ break;
+ }
+ }
+ pokemon.lastmove = move.id;
+ self.lastmove = move.id;
+ if (move.id === 'wish' || move.id === 'healingwish') {
+ pokemon.side.wisher = pokemon;
+ }
+ if (move.id === 'hyperbeam' || move.id === 'gigaimpact' || move.id === 'rockwrecker' || move.id === 'roaroftime' || move.id === 'blastburn' || move.id === 'frenzyplant' || move.id === 'hydrocannon') {
+ if (!kwargs.miss && !kwargs.notarget) {
+ pokemon.addMovestatus('mustrecharge');
+ pokemon.side.updateStatbar();
+ self.animationDelay += 500;
+ }
+ }
+ };
+ this.cantUseMove = function (pokemon, effect, move, kwargs) {
+ pokemon.clearMovestatuses();
+ pokemon.side.updateStatbar(pokemon, true);
+ switch (effect.id)
+ {
+ case 'taunt':
+ self.message('' + pokemon.getName() + ' can\'t use ' + move.name + ' after the taunt!');
+ break;
+ case 'imprison':
+ self.message('' + pokemon.getName() + ' can\'t use the sealed ' + move.name + '!');
+ break;
+ case 'par':
+ self.resultAnim(pokemon, 'Paralyzed', 'par');
+ BattleOtherAnims['fullparalysis'].anim(self, [pokemon.sprite]);
+ self.message('' + pokemon.getName() + ' is paralyzed! It can\'t move!');
+ break;
+ case 'frz':
+ self.resultAnim(pokemon, 'Frozen', 'frz');
+ self.message('' + pokemon.getName() + ' is frozen solid!');
+ break;
+ case 'slp':
+ self.resultAnim(pokemon, 'Asleep', 'slp');
+ self.message('' + pokemon.getName() + ' is fast asleep.');
+ break;
+ case 'skydrop':
+ self.message('Sky Drop won\'t let ' + pokemon.getLowerName() + ' go!');
+ break;
+ case 'truant':
+ self.resultAnim(pokemon, 'Truant', 'neutral');
+ self.message('' + pokemon.getName() + ' is loafing around!');
+ break;
+ case 'recharge':
+ BattleOtherAnims['selfstatus'].anim(self, [pokemon.sprite]);
+ self.resultAnim(pokemon, 'Must recharge', 'neutral');
+ self.message('
' + pokemon.getName() + ' must recharge! ');
+ break;
+ case 'focuspunch':
+ self.resultAnim(pokemon, 'Lost focus', 'neutral');
+ self.message(pokemon.getName() + ' lost its focus and couldn\'t move!');
+ pokemon.removeTurnstatus('focuspunch');
+ break;
+ case 'flinch':
+ self.resultAnim(pokemon, 'Flinched', 'neutral');
+ self.message(pokemon.getName() + ' flinched!');
+ pokemon.removeTurnstatus('focuspunch');
+ break;
+ case 'attract':
+ self.resultAnim(pokemon, 'Immobilized', 'neutral');
+ self.message(pokemon.getName() + ' is immobilized by love!');
+ break;
+ default:
+ self.message('
' + pokemon.getName() + (move.name ? ' can\'t use ' + move.name + '' : ' can\'t move') + '! ');
+ break;
+ }
+ };
+ this.prepareMove = function (pokemon, move, target) {
+ if (!move.prepareAnim) return;
+ if (!target) {
+ target = pokemon.side.foe.active[0];
+ }
+ if (!target) {
+ target = pokemon;
+ }
+ if (!self.fastForward) move.prepareAnim(self, [pokemon.sprite, target.sprite]);
+ self.message('
'+move.prepareMessage(pokemon, target)+' ');
+ };
+ this.animMultiHitMove = function () {
+ if (self.multiHitMove && !self.fastForward) {
+ self.multiHitMove[0].anim(self, [self.multiHitMove[1], self.multiHitMove[2]]);
+ self.multiHitMove[3]++;
+ self.animationDelay += 500;
+ }
+ };
+ this.runMinor = function (args, kwargs) {
+ var actions = '';
+ var hiddenactions = '';
+ var minors = self.minorQueue;
+ if (self.multiHitMove && minors.length) {
+ var lastMinor = minors[minors.length - 1];
+ //if (lastMinor[0][0] === '-damage' || lastMinor[0][1]['subdamage']) self.animMultiHitMove();
+ }
+ if (args) {
+ if (args[0] === '-crit' || args[0] === '-supereffective' || args[0] === '-resisted') args.then = '.';
+ minors.push([args, kwargs]);
+ if (args.simult || args.then) {
+ return;
+ }
+ }
+ var animDelay = 0;
+ var nextAnimDelay = 0;
+ while (minors.length) {
+ var row = minors.shift();
+ args = row[0];
+ kwargs = row[1];
+ animDelay = nextAnimDelay;
+ if (!kwargs.simult) nextAnimDelay++;
+
+ switch (args[0]) {
+ case '-damage':
+ var poke = this.getPokemon(args[1]);
+ var damage = parseFloat(args[2]);
+ if (isNaN(damage)) damage = 50; // wtf
+ poke.hp -= poke.maxhp * damage / 100;
+ poke.healthParse(args[2]);
+ self.damageAnim(poke, damage, animDelay);
+ self.lastDamage = (damage || 1);
+
+ if (kwargs.silent) {
+ // do nothing
+ } else if (kwargs.from) {
+ var effect = Tools.getEffect(kwargs.from);
+ var ofpoke = this.getPokemon(kwargs.of);
+ switch (effect.id) {
+ case 'stealthrock':
+ actions += "Pointed stones dug into " + poke.getLowerName() + "!";
+ break;
+ case 'spikes':
+ actions += "" + poke.getName() + " is hurt by the spikes!";
+ break;
+ case 'brn':
+ actions += "" + poke.getName() + " was hurt by its burn!";
+ break;
+ case 'psn':
+ actions += "" + poke.getName() + " was hurt by poison!";
+ break;
+ case 'lifeorb':
+ hiddenactions += "" + poke.getName() + " lost some of its HP!";
+ break;
+ case 'recoil':
+ actions += "" + poke.getName() + " is damaged by recoil!";
+ break;
+ case 'sandstorm':
+ actions += "" + poke.getName() + " is buffeted by the sandstorm!";
+ break;
+ case 'hail':
+ actions += "" + poke.getName() + " is buffeted by the hail!";
+ break;
+ case 'baddreams':
+ actions += "" + poke.getName() + " is tormented!";
+ break;
+ case 'nightmare':
+ actions += "" + poke.getName() + " is locked in a nightmare!";
+ break;
+ case 'confusion':
+ actions += "It hurt itself in its confusion! ";
+ break;
+ case 'leechseed':
+ if (!self.fastForward) {
+ BattleOtherAnims.leech.anim(self, [ofpoke.sprite, poke.sprite]);
+ self.activityWait(500);
+ }
+ actions += "" + poke.getName() + "'s health is sapped by Leech Seed!";
+ break;
+ default:
+ if (ofpoke) {
+ actions += "" + poke.getName() + " is hurt by " + ofpoke.getLowerName() + "'s " + effect.name + "!";
+ } else if (effect.effectType === 'Item' || effect.effectType === 'Ability') {
+ actions += "" + poke.getName() + " is hurt by its " + effect.name + "!";
+ } else if (kwargs.partiallytrapped) {
+ actions += "" + poke.getName() + ' is hurt by ' + effect.name + '!';
+ } else {
+ actions += "" + poke.getName() + " lost some HP because of " + effect.name + "!";
+ }
+ break;
+ }
+ } else {
+ hiddenactions += "" + poke.getName() + " lost " + damage + "% of its health!";
+ }
+ break;
+ case '-heal':
+ var poke = this.getPokemon(args[1]);
+ var damage = parseFloat(args[2]);
+ if (isNaN(damage)) damage = 50;
+ poke.hp += poke.maxhp * damage / 100;
+ if (poke.hp > poke.maxhp) {
+ poke.hp = poke.maxhp;
+ }
+ poke.healthParse(args[2]);
+ self.healAnim(poke, damage, animDelay);
+
+ if (kwargs.silent) {
+ // do nothing
+ } else if (kwargs.from) {
+ var effect = Tools.getEffect(kwargs.from);
+ var ofpoke = this.getPokemon(kwargs.of);
+ switch (effect.id) {
+ case 'ingrain':
+ actions += "" + poke.getName() + " absorbed nutrients with its roots!";
+ break;
+ case 'aquaring':
+ actions += "Aqua Ring restored " + poke.getLowerName() + "'s HP!";
+ break;
+ case 'raindish': case 'dryskin': case 'icebody':
+ actions += "" + poke.getName() + "'s " + effect.name + " heals it!";
+ break;
+ case 'healingwish':
+ actions += "The healing wish came true for "+poke.getLowerName()+"!";
+ self.lastmove = 'healing-wish';
+ Tools.getMove('healingwish').residualAnim(self, [poke.sprite]);
+ poke.side.wisher = null;
+ break;
+ case 'lunardance':
+ actions += ""+poke.getName()+" became cloaked in mystical moonlight!";
+ self.lastmove = 'healing-wish';
+ Tools.getMove('healingwish').residualAnim(self, [poke.sprite]);
+ poke.side.wisher = null;
+ break;
+ case 'wish':
+ actions += "" + kwargs.wisher + "'s wish came true!";
+ Tools.getMove('wish').residualAnim(self, [poke.sprite]);
+ self.animationDelay += 500;
+ break;
+ case 'drain':
+ actions += ofpoke.getName() + ' had its energy drained!';
+ break;
+ default:
+ if (kwargs.absorb) {
+ actions += "" + poke.getName() + "'s " + effect.name + " absorbs the attack!";
+ } else if (effect.id) {
+ actions += "" + poke.getName() + " restored HP using its " + effect.name + "!";
+ } else {
+ actions += poke.getName() + ' regained health!';
+ }
+ break;
+ }
+ } else {
+ actions += poke.getName() + ' regained health!';
+ }
+ break;
+ case '-sethp':
+ var effect = Tools.getEffect(kwargs.from);
+ var poke, ofpoke;
+ for (var k=0; k<2; k++)
+ {
+ var cpoke = self.getPokemon(args[1+2*k]);
+ if (cpoke) {
+ var oldhp = cpoke.hp;
+ cpoke.healthParse(args[2+2*k]);
+ var diff = parseFloat(args[2+2*k]);
+ if (isNaN(diff)) {
+ diff = cpoke.hp - oldhp;
+ }
+ if (diff > 0) {
+ self.healAnim(cpoke, diff, animDelay);
+ } else {
+ self.damageAnim(cpoke, -diff, animDelay);
+ }
+ }
+ if (k==0) poke = cpoke;
+ if (k==1) ofpoke = cpoke;
+ }
+ switch (effect.id) {
+ case 'painsplit':
+ actions += 'The battlers shared their pain!';
+ break;
+ }
+
+ break;
+
+ case '-boost':
+ var poke = this.getPokemon(args[1]);
+ var stat = args[2];
+ var amount = parseInt(args[3]);
+ if (!poke.boosts[stat]) {
+ poke.boosts[stat] = 0;
+ }
+ poke.boosts[stat] += amount;
+ self.resultAnim(poke, poke.getBoost(stat), 'good', animDelay);
+
+ var amountString = '';
+ if (amount === 2) amountString = ' sharply';
+ if (amount >= 3) amountString = ' drastically';
+ if (kwargs.silent) {
+ // do nothing
+ } else if (kwargs.from) {
+ var effect = Tools.getEffect(kwargs.from);
+ var ofpoke = this.getPokemon(kwargs.of);
+ switch (effect.id) {
+ default:
+ if (effect.effectType === 'Item') {
+ actions += "The " + effect.name + amountString+" raised " + poke.getLowerName() + "'s " + BattleStats[stat] + "!";
+ } else {
+ actions += "" + poke.getName() + "'s " + effect.name +amountString+" raised its " + BattleStats[stat] + "!";
+ }
+ break;
+ }
+ } else {
+ actions += "" + poke.getName() + "'s " + BattleStats[stat] + amountString + " rose" + "!";
+ }
+ break;
+ case '-unboost':
+ var poke = this.getPokemon(args[1]);
+ var stat = args[2];
+ var amount = parseInt(args[3]);
+ if (!poke.boosts[stat]) {
+ poke.boosts[stat] = 0;
+ }
+ poke.boosts[stat] -= amount;
+ self.resultAnim(poke, poke.getBoost(stat), 'bad', animDelay);
+
+ var amountString = '';
+ if (amount === 2) amountString = ' harshly';
+ if (amount >= 3) amountString = ' severely';
+ if (kwargs.silent) {
+ // do nothing
+ } else if (kwargs.from) {
+ var effect = Tools.getEffect(kwargs.from);
+ var ofpoke = this.getPokemon(kwargs.of);
+ switch (effect.id) {
+ default:
+ if (effect.effectType === 'Item') {
+ actions += "The " + effect.name + amountString+" lowered " + poke.getLowerName() + "'s " + BattleStats[stat] + "!";
+ } else {
+ actions += "" + poke.getName() + "'s " + effect.name +amountString+" lowered its " + BattleStats[stat] + "!";
+ }
+ break;
+ }
+ } else {
+ actions += "" + poke.getName() + "'s " + BattleStats[stat] + amountString + " fell!";
+ }
+ break;
+ case '-setboost':
+ var poke = this.getPokemon(args[1]);
+ var stat = args[2];
+ var amount = parseInt(args[3]);
+ var effect = Tools.getEffect(kwargs.from);
+ var ofpoke = this.getPokemon(kwargs.of);
+ poke.boosts[stat] = amount;
+ self.resultAnim(poke, poke.getBoost(stat), (amount>0?'good':'bad'), animDelay);
+
+ if (kwargs.silent) {
+ // do nothing
+ } else if (kwargs.from) {
+ switch (effect.id) {
+ case 'bellydrum':
+ actions += '' + poke.getName() + ' cut its own HP and maximized its Attack!';
+ break;
+ case 'angerpoint':
+ actions += '' + poke.getName() + ' maxed its Attack!';
+ break;
+ }
+ }
+ break;
+ case '-swapboost':
+ var poke = this.getPokemon(args[1]);
+ var poke2 = this.getPokemon(args[2]);
+ var stats = args[3]?args[3].split(', '):['atk','def','spa','spd','spe','accuracy','evasion'];
+ var effect = Tools.getEffect(kwargs.from);
+ for (var i=0; i
0) self.animMultiHitMove();
+ actions += 'Hit ' + hits + ' time(s)!';
+ break;
+
+ case '-nothing':
+ actions += "But nothing happened! ";
+ break;
+
+ case '-prepare':
+ var poke = this.getPokemon(args[1]);
+ var move = Tools.getMove(args[2]);
+ var target = this.getPokemon(args[3]);
+ self.prepareMove(poke, move, target);
+ break;
+
+ case '-status':
+ var poke = this.getPokemon(args[1]);
+ var effect = Tools.getEffect(kwargs.from);
+ poke.status = args[2];
+ poke.removeVolatile('yawn');
+
+ switch (args[2]) {
+ case 'brn':
+ self.resultAnim(poke, 'Burned', 'brn', animDelay);
+ actions += "" + poke.getName() + " was burned!";
+ break;
+ case 'tox':
+ self.resultAnim(poke, 'Toxic poison', 'psn', animDelay);
+ actions += "" + poke.getName() + " was badly poisoned!";
+ break;
+ case 'psn':
+ self.resultAnim(poke, 'Poisoned', 'psn', animDelay);
+ actions += "" + poke.getName() + " was poisoned!";
+ break;
+ case 'slp':
+ if (effect.id === 'rest') {
+ self.resultAnim(poke, 'Asleep', 'slp', animDelay);
+ actions += '' + poke.getName() + ' slept and became healthy!';
+ } else {
+ self.resultAnim(poke, 'Asleep', 'slp', animDelay);
+ actions += "" + poke.getName() + " fell asleep!";
+ }
+ break;
+ case 'par':
+ self.resultAnim(poke, 'Paralyzed', 'par', animDelay);
+ actions += "" + poke.getName() + " was paralyzed! It may be unable to move!";
+ break;
+ case 'frz':
+ self.resultAnim(poke, 'Frozen', 'frz', animDelay);
+ actions += "" + poke.getName() + " was frozen solid!";
+ break;
+ }
+ break;
+
+ case '-curestatus':
+ var poke = this.getPokemon(args[1]);
+ var effect = Tools.getEffect(kwargs.from);
+ var ofpoke = this.getPokemon(kwargs.of);
+ poke.status = '';
+
+ if (effect.id) switch (effect.id) {
+ case 'psychoshift':
+ actions += '' + poke.getName() + ' moved its status onto ' + ofpoke.getLowerName() + '!';
+ self.resultAnim(poke, 'Cured', 'good', animDelay);
+ break;
+ default:
+ self.resultAnim(poke, 'Cured', 'good', animDelay);
+ actions += "" + poke.getName() + "'s "+effect.name+" heals its status!";
+ break;
+ } else switch (args[2]) {
+ case 'brn':
+ self.resultAnim(poke, 'Burn cured', 'good', animDelay);
+ if (poke.side.n === 0) actions += "" + poke.getName() + "'s burn was healed.";
+ else actions += "" + poke.getName() + " healed its burn!";
+ break;
+ case 'tox':
+ case 'psn':
+ self.resultAnim(poke, 'Poison cured', 'good', animDelay);
+ var n = poke.side.n; // hack for eliminating "the foe's"
+ poke.side.n = 0;
+ actions += "" + poke.getName() + " was cured of its poisoning.";
+ poke.side.n = n;
+ break;
+ case 'slp':
+ self.resultAnim(poke, 'Woke up', 'good', animDelay);
+ actions += "" + poke.getName() + " woke up!";
+ break;
+ case 'par':
+ self.resultAnim(poke, 'Paralysis cured', 'good', animDelay);
+ actions += "" + poke.getName() + " was cured of paralysis.";
+ break;
+ case 'frz':
+ self.resultAnim(poke, 'Thawed', 'good', animDelay);
+ actions += "" + poke.getName() + " thawed out!";
+ break;
+ default:
+ poke.removeVolatile('confusion');
+ self.resultAnim(poke, 'Cured', 'good', animDelay);
+ actions += "" + poke.getName() + "'s status cleared!";
+ }
+ break;
+
+ case '-cureteam':
+ var poke = this.getPokemon(args[1]);
+ for (var k = 0; k < poke.side.pokemon.length; k++) {
+ poke.side.pokemon[k].status = '';
+ }
+
+ self.resultAnim(poke, 'Team Cured', 'good', animDelay);
+ var effect = Tools.getEffect(kwargs.from);
+ switch (effect.id) {
+ case 'aromatherapy':
+ actions += 'A soothing aroma wafted through the area!';
+ break;
+ case 'healbell':
+ actions += 'A bell chimed!';
+ break;
+ default:
+ actions += "" + poke.getName() + "'s team was cured!";
+ break;
+ }
+ break;
+
+ case '-item':
+ var poke = this.getPokemon(args[1]);
+ var item = Tools.getItem(args[2]);
+ var effect = Tools.getEffect(kwargs.from);
+ var ofpoke = this.getPokemon(kwargs.of);
+ poke.item = item.name;
+ poke.removeVolatile('airballoon');
+ if (item.id === 'airballoon') poke.addVolatile('airballoon');
+
+ if (effect.id) switch (effect.id) {
+ case 'recycle':
+ actions += '' + poke.getName() + ' found one ' + item.name + '!';
+ self.resultAnim(poke, item.name, 'neutral', animDelay);
+ break;
+ case 'frisk':
+ actions += "" + ofpoke.getName() + " frisked its target and found one " + item.name + "!";
+ break;
+ case 'pickup':
+ actions += '' + poke.getName() + ' found one ' + item.name + '!';
+ self.resultAnim(poke, item.name, 'neutral', animDelay);
+ break;
+ case 'thief':
+ case 'covet':
+ actions += '' + poke.getName() + ' stole ' + ofpoke.getLowerName() + "'s item!";
+ self.resultAnim(poke, item.name, 'neutral', animDelay);
+ self.resultAnim(ofpoke, 'Item Stolen', 'bad', animDelay);
+ break;
+ case 'harvest':
+ actions += '' + poke.getName() + ' harvested one ' + item.name + '!';
+ self.resultAnim(poke, item.name, 'neutral', animDelay);
+ break;
+ default:
+ actions += '' + poke.getName() + ' obtained one ' + item.name + '!';
+ self.resultAnim(poke, item.name, 'neutral', animDelay);
+ break;
+ } else switch (item.id) {
+ case 'airballoon':
+ self.resultAnim(poke, 'Balloon', 'good', animDelay);
+ actions += "" + poke.getName() + " floats in the air with its Air Balloon!";
+ break;
+ default:
+ actions += "" + poke.getName() + " has " + item.name + "!";
+ break;
+ }
+ break;
+
+ case '-enditem':
+ var poke = this.getPokemon(args[1]);
+ var item = Tools.getItem(args[2]);
+ var effect = Tools.getEffect(kwargs.from);
+ var ofpoke = this.getPokemon(kwargs.of);
+ poke.item = '';
+ poke.removeVolatile('airballoon');
+
+ if (kwargs.silent) {
+ // do nothing
+ } else if (kwargs.eat) {
+ actions += '' + poke.getName() + ' ate its ' + item.name + '!';
+ self.lastmove = item.id;
+ } else if (kwargs.weaken) {
+ actions += 'The ' + item.name + ' weakened the damage to '+poke.getLowerName();
+ self.lastmove = item.id;
+ } else if (effect.id) switch (effect.id) {
+ case 'fling':
+ actions += "" + poke.getName() + ' flung its ' + item.name + '!';
+ break;
+ case 'knockoff':
+ actions += '' + ofpoke.getName() + ' knocked off ' + poke.getLowerName() + '\'s ' + item.name + '!';
+ self.resultAnim(poke, 'Item knocked off', 'neutral', animDelay);
+ break;
+ case 'stealeat':
+ actions += '' + ofpoke.getName() + ' stole and ate its target\'s ' + item.name + '!';
+ break;
+ case 'gem':
+ actions += 'The ' + item.name + ' strengthened ' + Tools.getMove(kwargs.move).name + '\'s power!';
+ break;
+ case 'incinerate':
+ actions += "" + poke.getName() + "'s " + item.name + " was burnt up!";
+ break;
+ default:
+ actions += "" + poke.getName() + ' lost its ' + item.name + '!';
+ break;
+ } else switch (item.id) {
+ case 'airballoon':
+ poke.removeVolatile('airballoon');
+ self.resultAnim(poke, 'Balloon popped', 'neutral', animDelay);
+ actions += "" + poke.getName() + "'s Air Balloon popped!";
+ break;
+ case 'focussash':
+ self.resultAnim(poke, 'Sash', 'neutral', animDelay);
+ actions += "" + poke.getName() + ' hung on using its Focus Sash!';
+ break;
+ case 'focusband':
+ self.resultAnim(poke, 'Focus Band', 'neutral', animDelay);
+ actions += "" + poke.getName() + ' hung on using its Focus Band!';
+ break;
+ case 'mentalherb':
+ poke.removeVolatile('taunt');
+ poke.removeVolatile('encore');
+ poke.removeVolatile('torment');
+ self.resultAnim(poke, 'Cured', 'good', animDelay);
+ actions += "" + poke.getName() + " used its " + item.name + " to come back to its senses!";
+ break;
+ case 'whiteherb':
+ actions += "" + poke.getName() + " restored its status using White Herb!";
+ break;
+ case 'ejectbutton':
+ actions += "" + poke.getName() + " is switched out with the Eject Button!";
+ break;
+ case 'redcard':
+ actions += "" + poke.getName() + " held up its Red Card against " + ofpoke.getLowerName() + "!";
+ break;
+ default:
+ actions += "" + poke.getName() + "'s " + item.name + " activated!";
+ break;
+ }
+ break;
+
+ case '-ability':
+ var poke = this.getPokemon(args[1]);
+ var ability = Tools.getAbility(args[2]);
+ var effect = Tools.getEffect(kwargs.from);
+ var ofpoke = this.getPokemon(kwargs.of);
+ poke.ability = ability.name;
+
+ if (kwargs.silent) {
+ // do nothing
+ } else if (effect.id) switch (effect.id) {
+ case 'trace':
+ actions += '' + poke.getName() + ' traced ' + ofpoke.getLowerName() + '\'s ' + ability.name + '!';
+ break;
+ case 'roleplay':
+ actions += '' + poke.getName() + ' copied ' + ofpoke.getLowerName() + '\'s ' + ability.name + '!';
+ break;
+ case 'mummy':
+ actions += "" + poke.getName() + "'s Ability became Mummy!";
+ break;
+ default:
+ actions += "" + poke.getName() + " acquired " + ability.name + "!";
+ break;
+ } else switch (ability.id) {
+ case 'pressure':
+ actions += "" + poke.getName() + " is exerting its pressure!";
+ break;
+ case 'moldbreaker':
+ actions += "" + poke.getName() + " breaks the mold!";
+ break;
+ case 'turboblaze':
+ actions += "" + poke.getName() + " is radiating a blazing aura!";
+ break;
+ case 'teravolt':
+ actions += "" + poke.getName() + " is radiating a bursting aura!";
+ break;
+ case 'intimidate':
+ actions += '' + poke.getName() + ' intimidates ' + ofpoke.getLowerName() + '!';
+ break;
+ case 'unnerve':
+ actions += "" + poke.getName() + "'s Unnerve makes " + args[3] + "'s team too nervous to eat Berries!";
+ break;
+ default:
+ actions += "" + poke.getName() + " has " + ability.name + "!";
+ break;
+ }
+ break;
+
+ case '-endability':
+ var poke = this.getPokemon(args[1]);
+ var ability = Tools.getAbility(args[2]);
+ var effect = Tools.getEffect(kwargs.from);
+ poke.ability = '';
+
+ if (kwargs.silent) {
+ // do nothing
+ } else switch (effect.id) {
+ default:
+ actions += "" + poke.getName() + "\'s Ability was suppressed!";
+ break;
+ }
+ break;
+
+ case '-transform':
+ var poke = this.getPokemon(args[1]);
+ var tpoke = this.getPokemon(args[2]);
+ actions += '' + poke.getName() + ' transformed into ' + tpoke.species + '!';
+ poke.sprite.animTransform(tpoke);
+ poke.boosts = $.extend({}, tpoke.boosts);
+ poke.addVolatile('transform');
+ poke.addVolatile('formechange'); // the formechange volatile reminds us to revert the sprite change on switch-out
+ //poke.removeVolatile('typechange'); // does this happen??
+ poke.ability = tpoke.ability;
+ poke.volatiles.formechange[2] = (tpoke.volatiles.formechange ? tpoke.volatiles.formechange[2] : tpoke.species);
+ self.resultAnim(poke, 'Transformed', 'good', animDelay);
+ break;
+ case '-formechange':
+ var poke = this.getPokemon(args[1]);
+ var template = Tools.getTemplate(args[2]);
+ if (poke.sprite.sp.shiny) template.shiny = true;
+ poke.sprite.animTransform(template);
+ poke.addVolatile('formechange'); // the formechange volatile reminds us to revert the sprite change on switch-out
+ poke.volatiles.formechange[2] = template.species;
+ poke.side.updateStatbar();
+ break;
+
+ case '-start':
+ var poke = this.getPokemon(args[1]);
+ var effect = Tools.getEffect(args[2]);
+ var ofpoke = this.getPokemon(kwargs.of);
+ var fromeffect = Tools.getEffect(kwargs.from);
+ poke.addVolatile(effect.id);
+
+ switch (effect.id) {
+ case 'typechange':
+ poke.volatiles.typechange[2] = args[3];
+ if (fromeffect.id) {
+ if (fromeffect.id === 'reflecttype') {
+ actions += "" + poke.getName() + "'s type changed to match " + ofpoke.getLowerName() + "!";
+ } else {
+ actions += "" + poke.getName() + "'s " + fromeffect.name + " made it the " + args[3] + " type!";
+ }
+ } else {
+ actions += "" + poke.getName() + " transformed into the " + args[3] + " type!";
+ }
+ break;
+ case 'powertrick':
+ self.resultAnim(poke, 'Power Trick', 'neutral', animDelay);
+ actions += "" + poke.getName() + " switched its Attack and Defense!";
+ break;
+ case 'foresight':
+ self.resultAnim(poke, 'Foresight', 'bad', animDelay);
+ actions += "" + poke.getName() + " was identified!";
+ break;
+ case 'telekinesis':
+ self.resultAnim(poke, 'Telekinesis', 'neutral', animDelay);
+ actions += "" + poke.getName() + " was hurled into the air!";
+ break;
+ case 'confusion':
+ if (kwargs.already) {
+ actions += "" + poke.getName() + " is already confused!";
+ } else {
+ self.resultAnim(poke, 'Confused', 'bad', animDelay);
+ actions += "" + poke.getName() + " became confused!";
+ }
+ break;
+ case 'leechseed':
+ poke.side.updateStatbar(poke);
+ actions += '' + poke.getName() + ' was seeded!';
+ break;
+ case 'healblock':
+ self.resultAnim(poke, 'Heal Block', 'bad', animDelay);
+ actions += "" + poke.getName() + " was prevented from healing!";
+ break;
+ case 'mudsport':
+ self.resultAnim(poke, 'Mud Sport', 'neutral', animDelay);
+ actions += "Electricity's power was weakened!";
+ break;
+ case 'watersport':
+ self.resultAnim(poke, 'Water Sport', 'neutral', animDelay);
+ actions += "Fire's power was weakened!";
+ break;
+ case 'yawn':
+ self.resultAnim(poke, 'Drowsy', 'slp', animDelay);
+ actions += "" + poke.getLowerName() + ' grew drowsy!';
+ break;
+ case 'smackdown':
+ self.resultAnim(poke, 'Grounded', 'bad', animDelay);
+ actions += "" + poke.getLowerName() + ' fell straight down!';
+ break;
+ case 'flashfire':
+ self.resultAnim(poke, 'Flash Fire', 'good', animDelay);
+ actions += poke.getName() + '\'s Flash Fire raised the power of its Fire-type moves!';
+ break;
+ case 'taunt':
+ self.resultAnim(poke, 'Taunted', 'bad', animDelay);
+ actions += '' + poke.getName() + ' fell for the taunt!';
+ break;
+ case 'imprison':
+ self.resultAnim(poke, 'Imprisoning', 'good', animDelay);
+ actions += "" + poke.getName() + " sealed the opponent's move(s)!";
+ break;
+ case 'disable':
+ self.resultAnim(poke, 'Disabled', 'bad', animDelay);
+ actions += "" + poke.getName() + "'s " + args[3] + " was disabled!";
+ break;
+ case 'embargo':
+ self.resultAnim(poke, 'Embargo', 'bad', animDelay);
+ actions += "" + poke.getName() + " can't use items anymore!";
+ break;
+ case 'torment':
+ self.resultAnim(poke, 'Tormented', 'bad', animDelay);
+ actions += '' + poke.getName() + ' was subjected to torment!';
+ break;
+ case 'ingrain':
+ self.resultAnim(poke, 'Ingrained', 'good', animDelay);
+ actions += '' + poke.getName() + ' planted its roots!';
+ break;
+ case 'aquaring':
+ self.resultAnim(poke, 'Aqua Ring', 'good', animDelay);
+ actions += '' + poke.getName() + ' surrounded itself with a veil of water!';
+ break;
+ case 'stockpile1':
+ self.resultAnim(poke, 'Stockpile', 'good', animDelay);
+ actions += '' + poke.getName() + ' stockpiled 1!';
+ break;
+ case 'stockpile2':
+ poke.removeVolatile('stockpile1');
+ self.resultAnim(poke, 'Stockpile×2', 'good', animDelay);
+ actions += '' + poke.getName() + ' stockpiled 2!';
+ break;
+ case 'stockpile3':
+ poke.removeVolatile('stockpile2');
+ self.resultAnim(poke, 'Stockpile×3', 'good', animDelay);
+ actions += '' + poke.getName() + ' stockpiled 3!';
+ break;
+ case 'perish0':
+ poke.removeVolatile('perish1');
+ actions += '' + poke.getName() + "'s perish count fell to 0.";
+ break;
+ case 'perish1':
+ poke.removeVolatile('perish2');
+ self.resultAnim(poke, 'Perish next turn', 'bad', animDelay);
+ actions += '' + poke.getName() + "'s perish count fell to 1.";
+ break;
+ case 'perish2':
+ poke.removeVolatile('perish3');
+ self.resultAnim(poke, 'Perish in 2', 'bad', animDelay);
+ actions += '' + poke.getName() + "'s perish count fell to 2.";
+ break;
+ case 'perish3':
+ self.resultAnim(poke, 'Perish in 3', 'bad', animDelay);
+ actions += '' + poke.getName() + "'s perish count fell to 3.";
+ break;
+ case 'encore':
+ self.resultAnim(poke, 'Encored', 'bad', animDelay);
+ actions += '' + poke.getName() + ' received an encore!';
+ break;
+ case 'bide':
+ self.resultAnim(poke, 'Bide', 'good', animDelay);
+ actions += "" + poke.getName() + " is storing energy!";
+ break;
+ case 'slowstart':
+ self.resultAnim(poke, 'Slow Start', 'bad', animDelay);
+ actions += "" + poke.getName() + " can't get it going because of its Slow Start!";
+ break;
+ case 'attract':
+ self.resultAnim(poke, 'Attracted', 'bad', animDelay);
+ if (fromeffect.id) {
+ actions += "" + poke.getName() + " fell in love from the " + fromeffect.name + "!";
+ } else {
+ actions += "" + poke.getName() + " fell in love!";
+ }
+ break;
+ case 'autotomize':
+ self.resultAnim(poke, 'Lightened', 'good', animDelay);
+ actions += "" + poke.getName() + " became nimble!";
+ break;
+ case 'focusenergy':
+ self.resultAnim(poke, '+Crit rate', 'good', animDelay);
+ actions += "" + poke.getName() + " is getting pumped!";
+ break;
+ case 'curse':
+ self.resultAnim(poke, 'Cursed', 'bad', animDelay);
+ actions += "" + ofpoke.getName() + " cut its own HP and laid a curse on " + poke.getLowerName() + "!";
+ break;
+ case 'nightmare':
+ self.resultAnim(poke, 'Nightmare', 'bad', animDelay);
+ actions += "" + poke.getName() + " began having a nightmare!";
+ break;
+ case 'magnetrise':
+ self.resultAnim(poke, 'Magnet Rise', 'good', animDelay);
+ actions += "" + poke.getName() + " levitated with electromagnetism!";
+ break;
+ case 'smackdown':
+ self.resultAnim(poke, 'Smacked Down', 'bad', animDelay);
+ actions += "" + poke.getName() + " fell straight down!";
+ break;
+ case 'substitute':
+ if (kwargs.damage) {
+ self.resultAnim(poke, 'Damage', 'bad', animDelay);
+ actions += "The substitute took damage for "+poke.getLowerName()+"!";
+ } else if (kwargs.block) {
+ self.resultAnim(poke, 'Blocked', 'neutral', animDelay);
+ actions += 'But it failed!';
+ } else if (kwargs.already) {
+ actions += '' + poke.getName() + ' already has a substitute!';
+ } else {
+ poke.sprite.animSub();
+ actions += '' + poke.getName() + ' put in a substitute!';
+ }
+ break;
+ case 'doomdesire':
+ actions += '' + poke.getName() + ' chose Doom Desire as its destiny!';
+ break;
+ case 'futuresight':
+ actions += '' + poke.getName() + ' foresaw an attack!';
+ break;
+ case 'mimic':
+ actions += '' + poke.getName() + ' learned ' + args[3] + '!';
+ break;
+ default:
+ actions += "" + poke.getName() + "'s " + effect.name + " started!";
+ }
+ break;
+ case '-end':
+ var poke = this.getPokemon(args[1]);
+ var effect = Tools.getEffect(args[2]);
+ var fromeffect = Tools.getEffect(kwargs.from);
+ poke.removeVolatile(effect.id);
+ switch (effect.id) {
+ case 'powertrick':
+ self.resultAnim(poke, 'Power Trick', 'neutral', animDelay);
+ actions += "" + poke.getName() + " switched its Attack and Defense!";
+ break;
+ case 'telekinesis':
+ self.resultAnim(poke, 'Telekinesis ended', 'neutral', animDelay);
+ actions += "Telekinesis ended!";
+ break;
+ case 'confusion':
+ self.resultAnim(poke, 'Confusion ended', 'good', animDelay);
+ if (!kwargs.silent) {
+ if (poke.side.n === 0) actions += "" + poke.getName() + " snapped out of its confusion.";
+ else actions += "" + poke.getName() + " snapped out of confusion!";
+ }
+ break;
+ case 'leechseed':
+ if (fromeffect.id === 'rapidspin') {
+ self.resultAnim(poke, 'De-seeded', 'good', animDelay);
+ actions += "" + poke.getName() + " was freed from Leech Seed!";
+ }
+ break;
+ case 'healblock':
+ self.resultAnim(poke, 'Heal Block ended', 'good', animDelay);
+ actions += "" + poke.getName() + "'s Heal Block wore off!";
+ break;
+ case 'taunt':
+ self.resultAnim(poke, 'Taunt ended', 'good', animDelay);
+ actions += '' + poke.getName() + "'s taunt wore off!";
+ break;
+ case 'disable':
+ self.resultAnim(poke, 'Disable ended', 'good', animDelay);
+ actions += '' + poke.getName() + " is no longer disabled!";
+ break;
+ case 'embargo':
+ self.resultAnim(poke, 'Embargo ended', 'good', animDelay);
+ actions += "" + poke.getName() + " can use items again!";
+ break;
+ case 'torment':
+ self.resultAnim(poke, 'Torment ended', 'good', animDelay);
+ actions += '' + poke.getName() + "'s torment wore off!";
+ break;
+ case 'encore':
+ self.resultAnim(poke, 'Encore ended', 'good', animDelay);
+ actions += '' + poke.getName() + "'s encore ended!";
+ break;
+ case 'bide':
+ actions += "" + poke.getName() + " unleashed energy!";
+ break;
+ case 'magnetrise':
+ if (poke.side.n === 0) actions += "" + poke.getName() + "'s electromagnetism wore off!";
+ else actions += "The electromagnetism of "+poke.getLowerName()+" wore off!";
+ break;
+ case 'perishsong':
+ poke.removeVolatile('perish3');
+ break;
+ case 'substitute':
+ poke.sprite.animSubFade();
+ self.resultAnim(poke, 'Faded', 'bad', animDelay);
+ actions += '' + poke.getName() + "'s substitute faded!";
+ break;
+ default:
+ if (effect.effectType === 'Move') {
+ actions += '' + poke.getName() + " took the " + effect.name + " attack!";
+ } else {
+ actions += "" + poke.getName() + "'s " + effect.name + " ended!";
+ }
+ }
+ break;
+ case '-singleturn':
+ var poke = this.getPokemon(args[1]);
+ var effect = Tools.getEffect(args[2]);
+ var ofpoke = this.getPokemon(kwargs.of);
+ var fromeffect = Tools.getEffect(kwargs.from);
+ poke.addTurnstatus(effect.id);
+
+ switch (effect.id) {
+ case 'roost':
+ self.resultAnim(poke, 'Landed', 'neutral', animDelay);
+ //actions += '' + poke.getName() + ' landed on the ground!';
+ break;
+ case 'quickguard':
+ self.resultAnim(poke, 'Quick Guard', 'good', animDelay);
+ actions += "Quick Guard protected " + poke.side.getLowerTeamName() + "!";
+ break;
+ case 'wideguard':
+ self.resultAnim(poke, 'Wide Guard', 'good', animDelay);
+ actions += "Wide Guard protected " + poke.side.getLowerTeamName() + "!";
+ break;
+ case 'protect':
+ self.resultAnim(poke, 'Protected', 'good', animDelay);
+ actions += '' + poke.getName() + ' protected itself!';
+ break;
+ case 'endure':
+ self.resultAnim(poke, 'Enduring', 'good', animDelay);
+ actions += '' + poke.getName() + ' braced itself!';
+ break;
+ case 'helpinghand':
+ self.resultAnim(poke, 'Helping Hand', 'good', animDelay);
+ actions += '' + ofpoke.getName() + " is ready to help " + poke.getLowerName() + "!";
+ break;
+ case 'focuspunch':
+ self.resultAnim(poke, 'Focusing', 'neutral', animDelay);
+ actions += '' + poke.getName() + ' is tightening its focus!';
+ break;
+ case 'snatch':
+ actions += '' + poke.getName() + ' waits for a target to make a move!';
+ break;
+ case 'magiccoat':
+ actions += '' + poke.getName() + ' shrouded itself with Magic Coat!';
+ break;
+ }
+ break;
+ case '-singlemove':
+ var poke = this.getPokemon(args[1]);
+ var effect = Tools.getEffect(args[2]);
+ var ofpoke = this.getPokemon(kwargs.of);
+ var fromeffect = Tools.getEffect(kwargs.from);
+ poke.addMovestatus(effect.id);
+
+ switch (effect.id) {
+ case 'grudge':
+ actions += '' + poke.getName() + ' wants its target to bear a grudge!';
+ break;
+ case 'destinybond':
+ actions += '' + poke.getName() + ' is trying to take its foe down with it!';
+ break;
+ }
+ break;
+
+ case '-activate':
+ var poke = this.getPokemon(args[1]);
+ var effect = Tools.getEffect(args[2]);
+ var ofpoke = this.getPokemon(kwargs.of);
+ switch (effect.id) {
+ case 'calm':
+ actions += '' + poke.getName() + ' calmed down!';
+ break;
+ case 'confusion':
+ actions += "" + poke.getName() + " is confused!";
+ break;
+ case 'destinybond':
+ actions += '' + poke.getName() + ' took its attacker down with it!';
+ break;
+ case 'snatch':
+ actions += "" + poke.getName() + " snatched " + ofpoke.getLowerName() + "'s move!";
+ break;
+ case 'grudge':
+ actions += "" + poke.getName() + "'s " + args[3] + " lost all its PP due to the grudge!";
+ break;
+ case 'quickguard':
+ poke.addTurnstatus('quickguard');
+ self.resultAnim(poke, 'Quick Guard', 'good', animDelay);
+ actions += "Quick Guard protected " + poke.getLowerName() + "!";
+ break;
+ case 'protect':
+ poke.addTurnstatus('protect');
+ self.resultAnim(poke, 'Protected', 'good', animDelay);
+ actions += '' + poke.getName() + ' protected itself!';
+ break;
+ case 'substitute':
+ if (kwargs.damage) {
+ self.resultAnim(poke, 'Damage', 'bad', animDelay);
+ actions += '' + poke.getName() + "'s substitute took the damage!";
+ } else if (kwargs.block) {
+ self.resultAnim(poke, 'Blocked', 'neutral', animDelay);
+ actions += '' + poke.getName() + "'s Substitute blocked " + Tools.getMove(kwargs.block || args[3]).name + '!';
+ }
+ break;
+ case 'skillswap':
+ actions += '' + poke.getName() + ' swapped Abilities with its target!';
+ break;
+ case 'attract':
+ actions += '' + poke.getName() + ' is in love with ' + ofpoke.getLowerName() + '!';
+ break;
+ case 'bide':
+ actions += "" + poke.getName() + " is storing energy!";
+ break;
+ case 'mist':
+ actions += "" + poke.getName() + " is protected by the mist!";
+ break;
+
+ // move activations
+ case 'trick':
+ case 'switcheroo':
+ actions += '' + poke.getName() + ' switched items with ' + ofpoke.getLowerName() + '!';
+ break;
+ case 'brickbreak':
+ actions += poke.getName() + " shattered " + ofpoke.getTeamName() + " protections!";
+ ofpoke.removeSideCondition('Reflect');
+ ofpoke.removeSideCondition('LightScreen');
+ break;
+ case 'pursuit':
+ actions += "" + poke.getName() + " is being sent back!";
+ break;
+ case 'feint':
+ actions += "" + poke.getName() + " fell for the feint!";
+ break;
+ case 'spite':
+ actions += "It reduced the PP of " + args[3] + " by " + args[4] + "!";
+ break;
+ case 'gravity':
+ actions += "" + poke.getName() + " couldn't stay airborne because of gravity!";
+ break;
+ case 'magnitude':
+ actions += "Magnitude " + args[3] + "!";
+ break;
+ case 'sketch':
+ actions += "" + poke.getName() + " learned " + args[3] + "!";
+ break;
+ case 'skillswap':
+ actions += "" + poke.getName() + " swapped Abilities with its target!";
+ break;
+ case 'charge':
+ actions += "" + poke.getName() + " began charging power!";
+ break;
+ case 'struggle':
+ actions += "" + poke.getName() + " has no moves left!";
+ break;
+
+ // ability activations
+ case 'sturdy':
+ actions += '' + poke.getName() + ' held on thanks to Sturdy!';
+ break;
+ case 'magicbounce':
+ case 'magiccoat':
+ case 'rebound':
+ self.resultAnim(poke, 'Magic Coat', 'good', animDelay);
+ if (effect.id === 'magiccoat') {
+ poke.addTurnstatus('magiccoat');
+ }
+ actions += "" + ofpoke.getName() + "'s " + args[3] + " was bounced back by " + effect.name + "!";
+ Tools.getMove(args[3]).anim(self, [poke.sprite, ofpoke.sprite]);
+ break;
+ case 'wonderguard':
+ self.resultAnim(poke, 'Immune', 'neutral', animDelay);
+ actions += '' + poke.getName() + '\'s Wonder Guard evades the attack!';
+ break;
+ case 'speedboost':
+ actions += "" + poke.getName() + "'s' Speed Boost increases its speed!";
+ break;
+ case 'forewarn':
+ actions += "" + poke.getName() + "'s Forewarn alerted it to " + args[3] + "!";
+ break;
+ case 'anticipation':
+ actions += "" + poke.getName() + " shuddered!";
+ break;
+ case 'telepathy':
+ actions += "" + poke.getName() + " avoids attacks by its ally Pokémon!";
+ break;
+
+ // item activations
+ case 'custapberry':
+ //actions += ''+poke.getName()+' is already preparing its next move!';
+ actions += '' + poke.getName() + '\'s Custap Berry lets it move first!';
+ break;
+ case 'leppaberry':
+ actions += '' + poke.getName() + " restored " + args[3] + "'s PP using its Leppa Berry!";
+ break;
+ default:
+ actions += "" + poke.getName() + "'s " + effect.name + " activated!";
+ }
+ break;
+
+ case '-sidestart':
+ var side = this.getSide(args[1]);
+ var effect = Tools.getEffect(args[2]);
+ side.addSideCondition(effect.name);
+
+ switch (effect.id) {
+ case 'stealthrock':
+ actions += "Pointed stones float in the air around " + side.getLowerTeamName() + "!";
+ break;
+ case 'spikes':
+ actions += "Spikes were scattered all around the feet of " + side.getLowerTeamName() + "!";
+ break;
+ case 'toxicspikes':
+ actions += "Poison spikes were scattered all around the feet of " + side.getLowerTeamName() + "!";
+ break;
+ case 'tailwind':
+ actions += "A tailwind started blowing behind " + side.getLowerTeamName() + "!";
+ break;
+ case 'reflect':
+ actions += "Reflect raised " + side.getLowerTeamName() + "'s defense!";
+ break;
+ case 'lightscreen':
+ actions += "Light Screen raised " + side.getLowerTeamName() + "'s special defense!";
+ break;
+ case 'safeguard':
+ actions += "" + side.getTeamName() + " became cloaked in a mystical veil!";
+ break;
+ case 'mist':
+ actions += "" + side.getTeamName() + " became shrouded in mist!";
+ break;
+ }
+ break;
+ case '-sideend':
+ var side = this.getSide(args[1]);
+ var effect = Tools.getEffect(args[2]);
+ var from = Tools.getEffect(kwargs.from);
+ var ofpoke = this.getPokemon(kwargs.of);
+ side.removeSideCondition(effect.name);
+
+ switch (effect.id) {
+ case 'stealthrock':
+ actions += "The pointed stones disappeared from around " + side.getLowerTeamName() + "!";
+ break;
+ case 'spikes':
+ actions += "The spikes disappeared from around " + side.getLowerTeamName() + "'s feet!";
+ break;
+ case 'toxicspikes':
+ actions += "The poison spikes disappeared from around " + side.getLowerTeamName() + "'s feet!";
+ break;
+ case 'tailwind':
+ actions += "" + side.getTeamName() + "'s tailwind petered out!";
+ break;
+ case 'reflect':
+ actions += "" + side.getTeamName() + "'s reflect wore off!";
+ break;
+ case 'lightscreen':
+ actions += "" + side.getTeamName() + "'s light screen wore off!";
+ break;
+ case 'safeguard':
+ actions += "" + side.getTeamName() + " is no longer protected by Safeguard!";
+ break;
+ case 'mist':
+ actions += "" + side.getTeamName() + " is no longer protected by mist!";
+ break;
+ }
+ break;
+
+ case '-weather':
+ var effect = Tools.getEffect(args[1]);
+ var poke = this.getPokemon(kwargs.of);
+ self.changeWeather(effect.name, poke, kwargs.upkeep);
+ break;
+
+ case '-fieldstart':
+ var effect = Tools.getEffect(args[1]);
+ var poke = this.getPokemon(kwargs.of);
+ self.addPseudoWeather(effect.name, poke);
+
+ switch (effect.id) {
+ case 'trickroom':
+ actions += "" + poke.getName() + ' twisted the dimensions!';
+ break;
+ case 'wonderroom':
+ actions += "" + poke.getName() + ' swapped the Sp. Def. and the Defense of all the pokemon!';
+ break;
+ case 'magicroom':
+ actions += "" + poke.getName() + ' cancelled the items\' effects!';
+ break;
+ case 'gravity':
+ actions += "Gravity intensified!";
+ break;
+ }
+ break;
+
+ case '-fieldend':
+ var effect = Tools.getEffect(args[1]);
+ var poke = this.getPokemon(kwargs.of);
+ self.removePseudoWeather(effect.name, poke);
+
+ switch (effect.id) {
+ case 'trickroom':
+ actions += 'The twisted dimensions returned to normal!';
+ break;
+ case 'wonderroom':
+ actions += 'The Sp. Def and Defense of the pokemon went back to normal!';
+ break;
+ case 'magicroom':
+ actions += 'The items are now working again!';
+ break;
+ case 'gravity':
+ actions += 'Gravity returned to normal!';
+ break;
+ }
+ break;
+
+ case '-fieldactivate':
+ var effect = Tools.getEffect(args[1]);
+ switch (effect.id) {
+ case 'perishsong':
+ actions += 'All Pokémon hearing the song will faint in three turns!';
+ if (self.mySide.active[0]) self.mySide.active[0].addVolatile('perish3');
+ if (self.yourSide.active[0]) self.yourSide.active[0].addVolatile('perish3');
+ self.mySide.updateStatbar();
+ self.yourSide.updateStatbar();
+ break;
+ default:
+ actions += ''+effect.name+' hit!';
+ break;
+ }
+ break;
+
+ case '-message':
+ actions += self.sanitize(args[1]);
+ break;
+
+ case '-anim':
+ var poke = self.getPokemon(args[1]);
+ var move = Tools.getMove(args[2]);
+ if (self.checkActive(poke)) return;
+ poke2 = self.getPokemon(args[3]);
+ poke.sprite.beforeMove();
+ kwargs.silent = true;
+ self.useMove(poke, move, poke2, kwargs);
+ poke.sprite.afterMove();
+ break;
+
+ case '-hint':
+ hiddenactions += '('+args[1]+')';
+ break;
+
+ default:
+ self.logConsole('Unknown minor: ' + args[0]);
+ break;
+ }
+ }
+ if (actions) {
+ self.message('' + actions + ' ', hiddenactions ? '' + hiddenactions + ' ' : '');
+ } else if (hiddenactions) {
+ self.message('', '' + hiddenactions + ' ');
+ }
+ }
+
+ /* this.parseSpriteData = function (name) {
+ var siden = 0,
+ foe = false;
+ while (true) {
+ if (name.substr(0, 6) === 'foeof-') {
+ foe = true;
+ name = name.substr(6);
+ } else if (name.substr(0, 9) === 'switched-') name = name.substr(9);
+ else if (name.substr(0, 9) === 'existing-') name = name.substr(9);
+ else if (name.substr(0, 4) === 'foe-') {
+ siden = self.p2.n;
+ name = name.substr(4);
+ } else if (name.substr(0, 5) === 'ally-') {
+ siden = self.p1.n;
+ name = name.substr(5);
+ } else break;
+ }
+ if (name.substr(name.length - 1) === ')') {
+ var parenIndex = name.lastIndexOf('(');
+ if (parenIndex > 0) {
+ var species = name.substr(parenIndex + 1);
+ name = species.substr(0, species.length - 1);
+ }
+ }
+ if (foe) siden = (siden ? 0 : 1);
+
+ var data = Tools.getTemplate(name);
+ return data.spriteData[siden];
+ } */
+ this.parseDetails = function (name, pokemonid, details, output) {
+ if (!output) output = {};
+ output.details = details;
+ output.name = name;
+ output.species = name;
+ output.level = 100;
+ output.shiny = false;
+ output.gender = '';
+ output.ident = (name?pokemonid:'');
+ output.searchid = (name?(pokemonid + '|' + details):'');
+ var splitDetails = details.split(', ');
+ if (splitDetails[splitDetails.length-1] === 'shiny')
+ {
+ output.shiny = true;
+ splitDetails.pop();
+ }
+ if (splitDetails[splitDetails.length-1] === 'M' || splitDetails[splitDetails.length-1] === 'F')
+ {
+ output.gender = splitDetails[splitDetails.length-1];
+ splitDetails.pop();
+ }
+ if (splitDetails[1])
+ {
+ output.level = parseInt(splitDetails[1].substr(1)) || 100;
+ }
+ if (splitDetails[0])
+ {
+ output.species = splitDetails[0];
+ }
+ return output;
+ };
+ this.getPokemon = function (pokemonid, details) {
+ var siden = -1;
+ var name = pokemonid;
+ var isNew = false; // if yes, don't match any pokemon that already exists (for Team Preview)
+ var isOld = false; // if yes, match only pokemon that have been revealed, and can match fainted pokemon (now default)
+ var isOther = false; // if yes, don't match an active pokemon (for switching)
+ //var position = 0; // todo: use for position in doubles/triples
+ var getfoe = false;
+ var slot; // if there is an explicit slot for this pokemon
+ var slotChart = {a:0,b:1,c:2,d:3,e:4,f:5};
+ if (typeof pokemonid === 'undefined' || name === '??') return null;
+ if (name.substr(0, 5) === 'foe: ') {
+ name = name.substr(5);
+ pokemonid = name;
+ getfoe = true;
+ }
+ if (name.substr(0, 5) === 'new: ') {
+ name = name.substr(5);
+ pokemonid = name;
+ isNew = true;
+ isOther = true;
+ }
+ if (name.substr(0, 7) === 'other: ') {
+ name = name.substr(7);
+ pokemonid = name;
+ isOther = true;
+ }
+ if (name.substr(0, 5) === 'old: ') {
+ name = name.substr(5);
+ pokemonid = name;
+ isOld = true;
+ }
+ if (name.substr(0, 4) === 'p2: ' || name === 'p2') {
+ siden = self.p2.n;
+ name = name.substr(4);
+ species = name;
+ } else if (name.substr(0, 4) === 'p1: ' || name === 'p1') {
+ siden = self.p1.n;
+ name = name.substr(4);
+ species = name;
+ } else if (name.substr(0, 2) === 'p2' && name.substr(3, 2) === ': ') {
+ slot = slotChart[name.substr(2,1)];
+ siden = self.p2.n;
+ name = name.substr(5);
+ pokemonid = 'p2: '+name;
+ species = name;
+ } else if (name.substr(0, 2) === 'p1' && name.substr(3, 2) === ': ') {
+ slot = slotChart[name.substr(2,1)];
+ siden = self.p1.n;
+ name = name.substr(5);
+ pokemonid = 'p1: '+name;
+ species = name;
+ }
+
+ if (!slot) slot = 0;
+
+ if (!details) {
+ if (siden < 0) return null;
+ if (self.sides[siden].active[slot]) return self.sides[siden].active[slot];
+ }
+
+ var species = name;
+ var gender = '';
+ var level = 100;
+ var shiny = false;
+ var searchid = '';
+ if (details) searchid = pokemonid+'|'+details;
+
+ var bestMatchName = null;
+ if (siden !== self.p2.n && !isNew) {
+ if (self.p1.active[slot] && self.p1.active[slot].searchid === searchid && !isOther) {
+ self.p1.active[slot].slot = slot;
+ return self.p1.active[slot];
+ }
+ for (var i = 0; i < self.p1.pokemon.length; i++) {
+ var pokemon = self.p1.pokemon[i];
+ if (pokemon.fainted && (isNew || isOther)) continue;
+ if (isOther) {
+ if (self.p1.active.indexOf(pokemon) >= 0) continue;
+ if (pokemon == self.p1.lastPokemon && !self.p1.active[slot]) continue;
+ }
+ if (pokemon.searchid === searchid || (!pokemon.searchid && pokemon.checkDetails(details)) || (!searchid && pokemon.ident === pokemonid)) {
+ if (!pokemon.searchid)
+ {
+ pokemon.name = name;
+ pokemon.searchid = searchid;
+ pokemon.ident = pokemonid;
+ if (pokemon.needsReplace) {
+ pokemon = self.p1.newPokemon(self.parseDetails(name, pokemonid, details), i);
+ }
+ }
+ pokemon.slot = slot;
+ return pokemon;
+ }
+ }
+ }
+ if (siden !== self.p1.n && !isNew) {
+ if (self.p2.active[slot] && self.p2.active[slot].searchid === searchid && !isOther) {
+ self.p2.active[slot].slot = slot;
+ return self.p2.active[slot];
+ }
+ for (var i = 0; i < self.p2.pokemon.length; i++) {
+ var pokemon = self.p2.pokemon[i];
+ if (pokemon.fainted && (isNew || isOther)) continue;
+ if (isOther) {
+ if (self.p2.active.indexOf(pokemon) >= 0) continue;
+ if (pokemon == self.p2.lastPokemon && !self.p2.active[slot]) continue;
+ }
+ if (pokemon.searchid === searchid || (!pokemon.searchid && pokemon.checkDetails(details)) || (!searchid && pokemon.ident === pokemonid)) {
+ if (!pokemon.searchid)
+ {
+ pokemon.name = name;
+ pokemon.searchid = searchid;
+ pokemon.ident = pokemonid;
+ if (pokemon.needsReplace) {
+ pokemon = self.p2.newPokemon(self.parseDetails(name, pokemonid, details), i);
+ }
+ }
+ pokemon.slot = slot;
+ return pokemon;
+ }
+ }
+ }
+ if (!isNew && !isOther && !details) {
+ return false;
+ }
+ if (siden < 0) siden = self.p1.n;
+ if (details) {
+ var splitDetails = details.split(', ');
+ if (splitDetails[splitDetails.length-1] === 'shiny') {
+ shiny = true;
+ splitDetails.pop();
+ }
+ if (splitDetails[splitDetails.length-1] === 'M' || splitDetails[splitDetails.length-1] === 'F') {
+ gender = splitDetails[splitDetails.length-1];
+ splitDetails.pop();
+ }
+ if (splitDetails[1]) {
+ level = parseInt(splitDetails[1].substr(1)) || 100;
+ }
+ if (splitDetails[0]) {
+ species = splitDetails[0];
+ }
+ }
+ var pokemon = self.sides[siden].newPokemon({
+ species: species,
+ details: details,
+ name: name,
+ ident: (name?pokemonid:''),
+ searchid: (name?(pokemonid + '|' + details):''),
+ level: level,
+ gender: gender,
+ shiny: shiny,
+ slot: slot
+ });
+ return pokemon;
+ }
+ this.getSide = function (sidename) {
+ if (sidename === 'p1' || sidename.substr(0,3)==='p1:') return self.p1;
+ if (sidename === 'p2' || sidename.substr(0,3)==='p2:') return self.p2;
+ if (self.mySide.id == sidename) return self.mySide;
+ if (self.yourSide.id == sidename) return self.yourSide;
+ if (self.mySide.name == sidename) return self.mySide;
+ if (self.yourSide.name == sidename) return self.yourSide;
+ return {
+ name: sidename,
+ id: sidename.replace(/ /g, '')
+ };
+ }
+
+ this.add = function (command) {
+ if (self.playbackState === 0) {
+ self.playbackState = 1;
+ self.activityQueue.push(command);
+ } else if (self.playbackState === 4) {
+ self.playbackState = 2;
+ self.paused = false;
+ self.activityQueue.push(command);
+ self.activityQueueActive = true;
+ self.soundStart();
+ self.nextActivity();
+ } else {
+ self.activityQueue.push(command);
+ }
+ }
+ this.instantAdd = function (command) {
+ self.run(command, true);
+ self.preemptActivityQueue.push(command);
+ self.add(command);
+ }
+ this.sanitize = function (str) {
+ return str.replace(//g, '>');
+ }
+ this.teamPreview = function (start) {
+ for (var k = 0; k < 2; k++) {
+ var teamText = '';
+ var text = '';
+ self.spriteElems[k].empty();
+ if (!start) {
+ self.sides[k].updateSprites();
+ continue;
+ }
+ for (var i = 0; i < self.sides[k].pokemon.length; i++) {
+ var pokemon = self.sides[k].pokemon[i];
+
+ var spriteData = Tools.getSpriteData(pokemon, k);
+ var y = 0;
+ var x = 0;
+ if (k) {
+ y = Math.floor(96-spriteData.h)/2 + 50 + 3 * (i + 6 - self.sides[k].pokemon.length);
+ x = Math.floor(96-spriteData.w)/2 + 180 + 50 * (i + 6 - self.sides[k].pokemon.length);
+ } else {
+ y = Math.floor(96-spriteData.h)/2 + 200 + 3 * i;
+ x = Math.floor(96-spriteData.w)/2 + 100 + 50 * i;
+ }
+ if (teamText) teamText += ' / ';
+ teamText += pokemon.species;
+ text += ' ';
+ }
+ self.sides[k].totalPokemon = i;
+ self.sides[k].updateSidebar();
+ if (teamText) {
+ self.log('' + self.sanitize(self.sides[k].name) + '\'s team: ' + self.sanitize(teamText) + '
');
+ }
+ self.spriteElems[k].html(text);
+ }
+ };
+ this.runMajor = function(args, kwargs, preempt) {
+ switch (args[0]) {
+ case 'start':
+ self.teamPreview(false);
+ self.mySide.active[0] = null;
+ self.yourSide.active[0] = null;
+ if (self.waitForResult()) return;
+ self.start();
+ break;
+ case 'turn':
+ if (self.endPrevAction()) return;
+ self.setTurn(args[1]);
+ break;
+ case 'tier':
+ if (!args[1]) args[1] = '';
+ for (var i in kwargs) args[1] += '['+i+'] '+kwargs[i];
+ self.log('Format: ' + self.sanitize(args[1]) + '
');
+ break;
+ case 'gametype':
+ self.gameType = args[1];
+ if (args[1] === 'doubles') {
+ if (self.mySide.active.length < 2) self.mySide.active.push(null);
+ if (self.yourSide.active.length < 2) self.yourSide.active.push(null);
+ }
+ break;
+ case 'variation':
+ self.log('Variation: ' + self.sanitize(args[1]) + '
');
+ break;
+ case 'rule':
+ var ruleArgs = args[1].split(': ');
+ self.log('' + self.sanitize(ruleArgs[0]) + (ruleArgs[1]?':':'') + ' ' + self.sanitize(ruleArgs[1]||'') + '
');
+ break;
+ case 'rated':
+ self.rated = true;
+ self.log('Rated battle
');
+ break;
+ case 'chat':
+ case 'c':
+ name = args[1];
+ args.shift();
+ args.shift();
+ var message = args.join('|');
+ if (message.substr(0,2) === '//') {
+ self.log('' + self.sanitize(name) + ': ' + messageSanitize(message.substr(1)) + '
', preempt);
+ } else if (message.substr(0,4).toLowerCase() === '/me ') {
+ self.log('• ' + self.sanitize(name) + ' ' + messageSanitize(message.substr(4)) + '
', preempt);
+ } else if (message.substr(0,14).toLowerCase() === '/data-pokemon ') {
+ self.log(''+Chart.pokemonRow(Tools.getTemplate(message.substr(14)),'',{})+' ', preempt);
+ } else if (message.substr(0,11).toLowerCase() === '/data-item ') {
+ self.log(''+Chart.itemRow(Tools.getItem(message.substr(11)),'',{})+' ', preempt);
+ } else if (message.substr(0,14).toLowerCase() === '/data-ability ') {
+ self.log(''+Chart.abilityRow(Tools.getAbility(message.substr(14)),'',{})+' ', preempt);
+ } else if (message.substr(0,11).toLowerCase() === '/data-move ') {
+ self.log(''+Chart.moveRow(Tools.getMove(message.substr(11)),'',{})+' ', preempt);
+ } else {
+ self.log('' + self.sanitize(name) + ': ' + messageSanitize(message) + '
', preempt);
+ }
+ break;
+ case 'chatmsg':
+ args.shift();
+ list = args.join('|');
+ self.log('' + self.sanitize(list) + '
', preempt);
+ break;
+ case 'chatmsg-raw':
+ case 'raw':
+ args.shift();
+ list = args.join('|');
+ self.log('' + list + '
', preempt);
+ break;
+ case 'inactive':
+ self.kickingInactive = true;
+ args.shift();
+ list = args.join('|');
+ self.log('' + self.sanitize(list) + '
', preempt);
+ break;
+ case 'inactiveoff':
+ self.kickingInactive = false;
+ args.shift();
+ list = args.join('|');
+ self.log('' + self.sanitize(list) + '
', preempt);
+ break;
+ case 'join':
+ case 'j':
+ case 'J':
+ self.log('' + self.sanitize(args[1]) + ' joined.
', preempt);
+ break;
+ case 'leave':
+ case 'l':
+ case 'L':
+ self.log('' + self.sanitize(args[1]) + ' left.
', preempt);
+ break;
+ case 'spectator':
+ case 'spectatorleave':
+ break;
+ case 'player':
+ self.getSide(args[1]).setName(args[2]);
+ self.getSide(args[1]).setSprite(parseInt(args[3]));
+ break;
+ case 'win':
+ self.winner(args[1]);
+ break;
+ case 'tie':
+ self.winner();
+ break;
+ case 'prematureend':
+ self.prematureEnd();
+ break;
+ case 'clearpoke':
+ self.p1.pokemon = [];
+ self.p2.pokemon = [];
+ for (var i=0; iError: ' + self.sanitize(args.join('|')));
+ self.message('Bug? Report it to the replay viewer\'s Smogon thread ');
+ break;
+ case 'warning':
+ args.shift();
+ self.message('Warning: ' + self.sanitize(args.join('|')));
+ self.message('Bug? Report it to the replay viewer\'s Smogon thread ');
+ self.activityWait(1000);
+ break;
+ case 'gen':
+ self.gen = parseInt(args[1]);
+ break;
+ case 'callback':
+ args.shift();
+ if (self.customCallback) self.customCallback(self, args[0], args, kwargs);
+ break;
+ case 'debug':
+ args.shift();
+ name = args.join(' ');
+ self.log('[DEBUG] ' + self.sanitize(name) + '.
', preempt);
+ break;
+ default:
+ self.logConsole('unknown command: ' + args[0]);
+ self.log('Unknown command: ' + self.sanitize(args[0]) + '
');
+ break;
+ }
+ };
+ this.run = function (str, preempt) {
+ if (self.preemptActivityQueue.length && str === self.preemptActivityQueue[0]) {
+ self.preemptActivityQueue.shift();
+ self.preemptCatchup();
+ return;
+ }
+ str = $.trim(str);
+ if (str.substr(0,1) === '|') {
+ var args = ['done'], kwargs = {};
+ str = $.trim(str.substr(1));
+ if (str !== '') {
+ args = str.split('|');
+ for (var i=0,len=args.length; iError parsing: ' + self.sanitize(str) + ' ', preempt);
+ if (e.stack) {
+ var stack = ''+e.stack;
+ stack = stack.split("\n").slice(0,2).join("\n");
+ self.log('
' + self.sanitize(stack) + '
', preempt);
+ } else {
+ self.log('
Error: ' + self.sanitize(''+e) + '
', preempt);
+ }
+ }
+ } else {
+ self.log('
' + self.sanitize(str) + '
', preempt);
+ }
+ }
+ this.endPrevAction = function () {
+ if (self.minorQueue.length) {
+ self.runMinor();
+ self.activityStep--;
+ return true;
+ }
+ if (self.resultWaiting || self.messageActive) {
+ self.endAction();
+ self.activityStep--;
+ self.resultWaiting = false;
+ self.multiHitMove = null;
+ return true;
+ }
+ return false;
+ }
+ this.checkActive = function (poke) {
+ if (!poke.side.active[poke.slot]) {
+ // SOMEONE jumped in in the middle of a replay. <_<
+ poke.side.replace(poke);
+ }
+ return false;
+ }
+ this.waitForResult = function () {
+ if (self.endPrevAction()) return true;
+ self.resultWaiting = true;
+ return false;
+ }
+ this.doBeforeThis = function (act) {
+ if (act()) {
+ self.activityStep--;
+ return true;
+ }
+ return false;
+ }
+ this.doAfterThis = function (act) {
+ this.activityAfter = act;
+ }
+
+ // activity queue
+ this.animationDelay = 0;
+ this.activityStep = 0;
+ this.activityDelay = 0;
+ this.activityQueue = [];
+ this.preemptActivityQueue = [];
+ this.activityAfter = null;
+ this.activityAnimations = $();
+ this.activityQueueActive = false;
+ this.fastForward = false;
+ this.minorQueue = [];
+ this.resultWaiting = false;
+ this.multiHitMove = null;
+
+ this.queue1 = function () {
+ if (self.activeQueue === self.queue1) self.nextActivity();
+ };
+ this.queue2 = function () {
+ if (self.activeQueue === self.queue2) self.nextActivity();
+ };
+ this.swapQueues = function () {
+ if (self.activeQueue === self.queue1) self.activeQueue = self.queue2;
+ else self.activeQueue = self.queue2;
+ };
+ this.activeQueue = this.queue1;
+
+ this.pause = function () {
+ self.paused = true;
+ self.playbackState = 3;
+ if (self.resumeButton) {
+ self.frameElem.append('
Resume
');
+ self.frameElem.find('div.playbutton button').click(self.resumeButton);
+ }
+ self.soundPause();
+ }
+ this.play = function () {
+ if (self.fastForward) {
+ self.paused = false;
+ self.playbackState = 5;
+ } else if (self.paused) {
+ self.paused = false;
+ if (self.playbackState === 1) {
+ self.soundStop();
+ }
+ self.playbackState = 2;
+ if (!self.done) {
+ self.soundStart();
+ }
+ self.nextActivity();
+ }
+ self.frameElem.find('div.playbutton').remove();
+ }
+ this.skipTurn = function () {
+ self.fastForwardTo(self.turn + 1);
+ };
+ this.fastForwardTo = function (time) {
+ self.playbackState = 5;
+ if (self.fastForward) return;
+ time = parseInt(time);
+ if (isNaN(time)) return;
+ if (self.activityStep >= self.activityQueue.length - 1 && time >= self.turn + 1 && !self.activityQueueActive) return;
+ if (self.done && time >= self.turn + 1) return;
+ self.messagebarElem.empty().css({
+ opacity: 0,
+ height: 0
+ });
+ if (time <= self.turn && time !== -1) {
+ var paused = self.paused;
+ self.reset();
+ self.activityQueueActive = true;
+ if (paused) self.pause();
+ else self.paused = false;
+ self.fastForward = time;
+ self.elem.append('
seeking...
');
+ $.fx.off = true;
+ self.swapQueues();
+ self.nextActivity();
+ return;
+ }
+ self.fxElem.empty();
+ self.fastForward = time;
+ self.elem.append('
seeking...
');
+ $.fx.off = true;
+ if (self.yourSide.active[0] && self.yourSide.active[0].sprite) {
+ self.yourSide.active[0].sprite.animReset();
+ }
+ if (self.mySide.active[0] && self.mySide.active[0].sprite) {
+ self.mySide.active[0].sprite.animReset();
+ }
+ self.swapQueues();
+ self.nextActivity();
+ };
+ this.fastForwardOff = function () {
+ self.fastForward = false;
+ self.elem.find('.seeking').remove();
+ $.fx.off = false;
+ self.playbackState = 2;
+ };
+ this.nextActivity = function () {
+ if (self.paused && !self.fastForward) {
+ return;
+ }
+ self.activityQueueActive = true;
+ self.fxElem.empty();
+ self.animationDelay = 0;
+ while (true) {
+ self.activityAnimations = $();
+ if (self.activityStep == self.activityQueue.length) {
+ self.activityQueueActive = false;
+ self.paused = true;
+ self.fastForwardOff();
+ if (self.done) {
+ self.soundStop();
+ }
+ self.playbackState = 4;
+ if (self.endCallback) self.endCallback(self);
+ return;
+ }
+ var ret;
+ if (self.activityAfter) {
+ ret = self.activityAfter();
+ self.activityAfter = null;
+ }
+ if (self.paused && !self.fastForward) return;
+ if (!ret) {
+ self.run(self.activityQueue[self.activityStep]);
+ self.activityStep++;
+ }
+ if (self.activityDelay) {
+ self.delayElem.delay(self.activityDelay);
+ self.activityWait(self.delayElem);
+ self.activityDelay = 0;
+ }
+ if (self.activityAnimations.length) break;
+ }
+ self.activityAnimations.promise().done(self.activeQueue);
+ }
+ this.activityWait = function (elem) {
+ if (typeof elem === 'number' && elem > self.activityDelay) {
+ self.activityDelay = elem;
+ return;
+ }
+ self.activityAnimations = self.activityAnimations.add(elem);
+ }
+
+ this.newBattle = function () {
+ self.reset();
+ self.activityQueue = [];
+ }
+ this.setQueue = function (queue) {
+ self.reset();
+ self.activityQueue = queue;
+
+ /* for (var i = 0; i < queue.length && i < 20; i++) {
+ if (queue[i].substr(0, 8) === 'pokemon ') {
+ var sp = self.parseSpriteData(queue[i].substr(8));
+ self.preloadAudio(sp.cryurl);
+ self.preloadImage(sp.url);
+ if (sp.url === '/sprites/bwani/meloetta.gif') {
+ self.preloadImage('/sprites/bwani/meloetta-pirouette.gif');
+ }
+ if (sp.url === '/sprites/bwani-back/meloetta.gif') {
+ self.preloadImage('/sprites/bwani-back/meloetta-pirouette.gif');
+ }
+ }
+ } */
+ self.playbackState = 1;
+ }
+
+ // callback
+ this.faintCallback = null;
+ this.switchCallback = null;
+ this.dragCallback = null;
+ this.turnCallback = null;
+ this.startCallback = null;
+ this.stagnateCallback = null;
+ this.endCallback = null;
+ this.customCallback = null;
+
+ // external
+ this.resumeButton = this.play;
+
+ this.preloadCache = {};
+ this.preloadDone = 0;
+ this.preloadNeeded = 0;
+ this.bgm = null;
+
+ this.mute = false;
+
+ this.preloadImage = function (url) {
+ if (noPreload) return;
+ var token = url.replace(/\.(gif|png)$/, '').replace(/\//g, '-');
+ if (self.preloadCache[token]) {
+ return;
+ }
+ self.preloadNeeded++;
+ self.preloadCache[token] = new Image();
+ self.preloadCache[token].onload = function () {
+ self.preloadDone++;
+ self.preloadCallback(self.preloadNeeded === self.preloadDone, self.preloadDone, self.preloadNeeded);
+ };
+ self.preloadCache[token].src = url;
+ };
+ this.preloadCallback = function () {};
+ this.preloadEffects = function () {
+ if (noPreload) return;
+ for (i in BattleEffects) {
+ if (BattleEffects[i].url) self.preloadImage(BattleEffects[i].url);
+ }
+ self.preloadImage('/fx/weather-raindance.jpg'); // rain is used often enough to precache
+ self.preloadImage('/sprites/bw/substitute.png');
+ self.preloadImage('/sprites/bw-back/substitute.png');
+ //self.preloadImage('/fx/bg.jpg');
+ };
+ this.preloadSounds = function () {
+ //self.preloadAudio('audio/bw-trainer-battle.mp3');
+ }
+ this.preloadAudio = function (url, autoplay) {
+ if (noPreload) return;
+ var token = url.replace(/\.(wav|mp3)$/, '').replace(/\//g, '-');
+ if (self.preloadCache[token]) {
+ return;
+ }
+ self.preloadNeeded++;
+ if ((sound = soundManager.getSoundById(token))) {
+ self.preloadCache[token] = sound;
+ sound.play();
+ self.preloadDone++;
+ self.preloadCallback(self.preloadNeeded === self.preloadDone, self.preloadDone, self.preloadNeeded);
+ } else {
+ self.preloadCache[token] = soundManager.createSound({
+ id: token,
+ url: url,
+ autoPlay: autoplay,
+ volume: 50,
+ onload: function () {
+ self.preloadDone++;
+ self.preloadCallback(self.preloadNeeded === self.preloadDone, self.preloadDone, self.preloadNeeded);
+ }
+ });
+ }
+ if (!self.preloadCache[token]) {
+ // error
+ return;
+ }
+ if (!autoplay) {
+ self.preloadCache[token].load();
+ }
+ };
+ this.preloadBgm = function (url, autoplay, loopstart, loopend) {
+ if (!url) {
+ var bgmNum = Math.floor(Math.random() * 7);
+ if (window.forceBgm) bgmNum = window.forceBgm;
+ switch (bgmNum) {
+ case -1:
+ self.preloadBgm('/audio/bw2-homika-dogars.mp3', true, 1661, 68131);
+ break;
+ case 0:
+ self.preloadBgm('/audio/hgss-kanto-trainer.mp3', true, 13003, 94656);
+ break;
+ case 1:
+ self.preloadBgm('/audio/bw-subway-trainer.mp3', true, 15503, 110984);
+ break;
+ case 2:
+ self.preloadBgm('/audio/bw-trainer.mp3', true, 14629, 110109);
+ break;
+ case 3:
+ self.preloadBgm('/audio/bw-rival.mp3', true, 19180, 57373);
+ break;
+ case 4:
+ self.preloadBgm('/audio/dpp-trainer.mp3', true, 13440, 96959);
+ break;
+ case 5:
+ self.preloadBgm('/audio/hgss-johto-trainer.mp3', true, 23731, 125086);
+ break;
+ case 6:
+ default:
+ self.preloadBgm('/audio/dpp-rival.mp3', true, 13888, 66352);
+ break;
+ }
+ return;
+ }
+ if (noPreload) return;
+ var token = url.replace(/\.(wav|mp3)$/, '').replace(/\//g, '-');
+ if (self.preloadCache[token]) {
+ if (autoplay) {
+ self.preloadCache[token].play();
+ }
+ return;
+ }
+ self.preloadNeeded++;
+ var sound;
+ if ((sound = soundManager.getSoundById(token))) {
+ self.preloadCache[token] = sound;
+ sound.play();
+ self.preloadDone++;
+ self.preloadCallback(self.preloadNeeded === self.preloadDone, self.preloadDone, self.preloadNeeded);
+ } else {
+ self.preloadCache[token] = soundManager.createSound({
+ id: token,
+ url: url,
+ autoPlay: autoplay,
+ volume: 50,
+ onload: function () {
+ self.preloadDone++;
+ self.preloadCallback(self.preloadNeeded === self.preloadDone, self.preloadDone, self.preloadNeeded);
+ }
+ });
+ }
+ if (!self.preloadCache[token]) {
+ // error
+ return;
+ }
+ self.bgm = self.preloadCache[token];
+ self.preloadCache[token].onposition(loopend, function () {
+ // loop music
+ self.preloadCache[token].setPosition(loopstart);
+ //$('#loopcount').html(''+(++self.loopcount));
+ });
+ if (!autoplay) {
+ self.preloadCache[token].load();
+ }
+ };
+ this.getToken = function (url) {
+ return url.replace(/\.(wav|mp3)$/, '').replace(/\//g, '-');
+ };
+ this.playAudio = function (url) {
+ if (self.mute) return;
+ var token = url.replace(/\.(wav|mp3)$/, '').replace(/\//g, '-');
+ if (!self.preloadCache[token]) {
+ self.preloadAudio(url, true);
+ } else {
+ self.preloadCache[token].play();
+ }
+ };
+ this.setMute = function (mute) {
+ self.mute = mute;
+ if (!mute) {
+ if (self.playbackState === 2 || self.playbackState === 5) {
+ self.soundStart();
+ }
+ if (self.playbackState === 4 && !self.done) {
+ self.soundStart();
+ }
+ } else {
+ self.soundPause();
+ }
+ };
+ self.soundState = 0;
+ self.bgm = null;
+ self.loopcount = 0;
+ // 0 = stopped
+ // 1 = playing
+ // 2 = paused
+ this.soundStart = function () {
+ if (self.mute) return;
+ if (self.soundState === 0) {
+ self.soundState = 1;
+ self.preloadBgm();
+ //self.playAudio('audio/bw-trainer-battle.mp3');
+ //self.bgm = self.preloadCache[self.getToken('audio/bw-trainer-battle.mp3')];
+ } else if (self.soundState === 2) {
+ self.soundState = 1;
+ if (self.bgm) self.bgm.resume();
+ }
+ };
+ this.soundStop = function () {
+ soundManager.stopAll();
+ self.soundState = 0;
+ };
+ this.soundPause = function () {
+ if (self.soundState === 1) {
+ if (self.bgm) self.bgm.pause();
+ self.soundState = 2;
+ }
+ };
+
+ this.messageDelay = 8;
+
+ this.preloadEffects();
+
+ self.init();
+}
+
+/*
+
+ self.lastmove = 'healing-wish';
+ Tools.getMove('HealingWish').residualAnim(self, [pokemon.sprite]);
+ pokemon.side.wisher = null;
+
+*/
diff --git a/js/battledata.js b/js/battledata.js
new file mode 100644
index 0000000000..eb84b23d76
--- /dev/null
+++ b/js/battledata.js
@@ -0,0 +1,604 @@
+/*
+
+License: MIT License
+
+
+*/
+
+if (!window.exports) window.exports = window;
+
+// todo: http://www.youtube.com/watch?v=eEwAPnIev38
+// 32.930 - 1:13.032
+// 32930 to 73032
+// subway
+// 1:33.120 - 3:08.614
+/*
+
+// PO importer
+
+text = $('textarea')[1].value
+text = text.split("\n");
+
+for (var i=0; i>> 0;
+Â Â Â Â Â Â Â Â if (len === 0) {
+Â Â Â Â Â Â Â Â Â Â Â Â return -1;
+Â Â Â Â Â Â Â Â }
+Â Â Â Â Â Â Â Â var n = 0;
+Â Â Â Â Â Â Â Â if (arguments.length > 1) {
+Â Â Â Â Â Â Â Â Â Â Â Â n = Number(arguments[1]);
+Â Â Â Â Â Â Â Â Â Â Â Â if (n != n) { // shortcut for verifying if it's NaN
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â n = 0;
+Â Â Â Â Â Â Â Â Â Â Â Â } else if (n != 0 && n != Infinity && n != -Infinity) {
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â n = (n > 0 || -1) * Math.floor(Math.abs(n));
+Â Â Â Â Â Â Â Â Â Â Â Â }
+Â Â Â Â Â Â Â Â }
+Â Â Â Â Â Â Â Â if (n >= len) {
+Â Â Â Â Â Â Â Â Â Â Â Â return -1;
+Â Â Â Â Â Â Â Â }
+Â Â Â Â Â Â Â Â var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
+Â Â Â Â Â Â Â Â for (; k < len; k++) {
+Â Â Â Â Â Â Â Â Â Â Â Â if (k in t && t[k] === searchElement) {
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â return k;
+Â Â Â Â Â Â Â Â Â Â Â Â }
+Â Â Â Â Â Â Â Â }
+Â Â Â Â Â Â Â Â return -1;
+Â Â Â Â }
+}
+
+// MD5 minified
+window.MD5=function(f){function i(b,c){var d,e,f,g,h;f=b&2147483648;g=c&2147483648;d=b&1073741824;e=c&1073741824;h=(b&1073741823)+(c&1073741823);return d&e?h^2147483648^f^g:d|e?h&1073741824?h^3221225472^f^g:h^1073741824^f^g:h^f^g}function j(b,c,d,e,f,g,h){b=i(b,i(i(c&d|~c&e,f),h));return i(b<>>32-g,c)}function k(b,c,d,e,f,g,h){b=i(b,i(i(c&e|d&~e,f),h));return i(b<>>32-g,c)}function l(b,c,e,d,f,g,h){b=i(b,i(i(c^e^d,f),h));return i(b<>>32-g,c)}function m(b,c,e,d,f,g,h){b=i(b,i(i(e^(c|~d),
+f),h));return i(b<>>32-g,c)}function n(b){var c="",e="",d;for(d=0;d<=3;d++)e=b>>>d*8&255,e="0"+e.toString(16),c+=e.substr(e.length-2,2);return c}var g=[],o,p,q,r,b,c,d,e,f=function(b){for(var b=b.replace(/\r\n/g,"\n"),c="",e=0;e127&&d<2048?c+=String.fromCharCode(d>>6|192):(c+=String.fromCharCode(d>>12|224),c+=String.fromCharCode(d>>6&63|128)),c+=String.fromCharCode(d&63|128))}return c}(f),g=function(b){var c,d=b.length;c=
+d+8;for(var e=((c-c%64)/64+1)*16,f=Array(e-1),g=0,h=0;h>>29;return f}(f);b=1732584193;c=4023233417;d=2562383102;e=271733878;for(f=0;f /g, '>').replace(/"/g, '"');
+ if (jsEscapeToo) str = str.replace(/'/g, '\\\'');
+ return str;
+}
+function jsEscape(str) {
+ str = (str?''+str:'');
+ str = str.replace(/'/g, '\\\'');
+ return str;
+}
+
+function messageSanitize(str) {
+ return sanitize(str).replace(/\`\`([^< ]([^<`]*?[^< ])?)\`\`/g, '$1
').replace(/\~\~([^< ]([^<]*?[^< ])?)\~\~/g, '$1 ').replace(/(https?\:\/\/[a-z0-9-.]+(\/([^\s]*[^\s?.,])?)?|[a-z0-9]([a-z0-9-\.]*[a-z0-9])?\.(com|org|net|edu|tk)((\/([^\s]*[^\s?.,])?)?|\b))/ig, '$1 ').replace(/$1 ').replace(/(\bgl ?\[([^\]<]+)\])/ig, '$1 ').replace(/(\bwiki ?\[([^\]<]+)\])/ig, '$1 ').replace(/\[\[([^< ]([^<`]*?[^< ])?)\]\]/ig, '$1 ').replace(/\_\_([^< ]([^<]*?[^< ])?)\_\_/g, '$1 ').replace(/\*\*([^< ]([^<]*?[^< ])?)\*\*/g, '$1 ');
+}
+
+function toId(text) {
+ text = text || '';
+ if (typeof text === 'number') text = ''+text;
+ if (typeof text !== 'string') return toId(text && text.id);
+ return text.toLowerCase().replace(/[^a-z0-9]+/g, '');
+}
+
+function toUserid(text) {
+ text = text || '';
+ if (typeof text === 'number') text = ''+text;
+ if (typeof text !== 'string') return ''; //???
+ return text.toLowerCase().replace(/[^a-z0-9]+/g, '');
+}
+
+// miscellaneous things too minor to deserve their own resource file
+var BattleNatures = {
+ Adamant: {
+ plus: 'atk',
+ minus: 'spa'
+ },
+ Bashful: {},
+ Bold: {
+ plus: 'def',
+ minus: 'atk'
+ },
+ Brave: {
+ plus: 'atk',
+ minus: 'spe'
+ },
+ Calm: {
+ plus: 'spd',
+ minus: 'atk'
+ },
+ Careful: {
+ plus: 'spd',
+ minus: 'spa'
+ },
+ Docile: {},
+ Gentle: {
+ plus: 'spd',
+ minus: 'def'
+ },
+ Hardy: {},
+ Hasty: {
+ plus: 'spe',
+ minus: 'def'
+ },
+ Impish: {
+ plus: 'def',
+ minus: 'spa'
+ },
+ Jolly: {
+ plus: 'spe',
+ minus: 'spa'
+ },
+ Lax: {
+ plus: 'def',
+ minus: 'spd'
+ },
+ Lonely: {
+ plus: 'atk',
+ minus: 'def'
+ },
+ Mild: {
+ plus: 'spa',
+ minus: 'def'
+ },
+ Modest: {
+ plus: 'spa',
+ minus: 'atk'
+ },
+ Naive: {
+ plus: 'spe',
+ minus: 'spd'
+ },
+ Naughty: {
+ plus: 'atk',
+ minus: 'spd'
+ },
+ Quiet: {
+ plus: 'spa',
+ minus: 'spe'
+ },
+ Quirky: {},
+ Rash: {
+ plus: 'spa',
+ minus: 'spd'
+ },
+ Relaxed: {
+ plus: 'def',
+ minus: 'spe'
+ },
+ Sassy: {
+ plus: 'spd',
+ minus: 'spe'
+ },
+ Serious: {},
+ Timid: {
+ plus: 'spe',
+ minus: 'atk'
+ }
+};
+var StatIDs = {
+ HP: 'hp',
+ hp: 'hp',
+ Atk: 'atk',
+ atk: 'atk',
+ Def: 'def',
+ def: 'def',
+ SpA: 'spa',
+ SAtk: 'spa',
+ SpAtk: 'spa',
+ spa: 'spa',
+ SpD: 'spd',
+ SDef: 'spd',
+ SpDef: 'spd',
+ spd: 'spd',
+ Spe: 'spe',
+ Spd: 'spe',
+ spe: 'spe'
+};
+var POStatNames = { // PO style
+ hp: 'HP',
+ atk: 'Atk',
+ def: 'Def',
+ spa: 'SAtk',
+ spd: 'SDef',
+ spe: 'Spd'
+};
+var StatNames = { // proper style
+ hp: 'HP',
+ atk: 'Atk',
+ def: 'Def',
+ spa: 'SpA',
+ spd: 'SpD',
+ spe: 'Spe'
+};
+
+var basespecieschart = {
+ 'unown': 1,
+ 'castform': 1,
+ 'deoxys': 1,
+ 'burmy': 1,
+ 'wormadam': 1,
+ 'cherrim': 1,
+ 'shellos': 1,
+ 'gastrodon': 1,
+ 'rotom': 1,
+ 'giratina': 1,
+ 'arceus': 1,
+ 'shaymin': 1,
+ 'basculin': 1,
+ 'darmanitan': 1,
+ 'deerling': 1,
+ 'sawsbuck': 1,
+ 'meloetta': 1,
+ 'genesect': 1,
+ 'tornadus': 1,
+ 'thundurus': 1,
+ 'landorus': 1,
+ 'kyurem': 1,
+ 'keldeo': 1
+};
+
+var Tools = {
+
+ getEffect: function(effect) {
+ if (!effect || typeof effect === 'string') {
+ var name = $.trim(effect||'');
+ if (name.substr(0,5) === 'item:') {
+ return Tools.getItem(name.substr(5));
+ } else if (name.substr(0,8) === 'ability:') {
+ return Tools.getAbility(name.substr(8));
+ } else if (name.substr(0,5) === 'move:') {
+ return Tools.getMove(name.substr(5));
+ }
+ var id = toId(name);
+ effect = {};
+ if (id && window.BattleStatuses && BattleStatuses[id]) {
+ effect = BattleStatuses[id];
+ effect.exists = true;
+ } else if (id && window.BattleMovedex && BattleMovedex[id] && BattleMovedex[id].effect) {
+ effect = BattleMovedex[id].effect;
+ effect.exists = true;
+ } else if (id && window.BattleAbilities && BattleAbilities[id] && BattleAbilities[id].effect) {
+ effect = BattleAbilities[id].effect;
+ effect.exists = true;
+ } else if (id && window.BattleItems && BattleItems[id] && BattleItems[id].effect) {
+ effect = BattleItems[id].effect;
+ effect.exists = true;
+ } else if (id && window.BattleFormats && BattleFormats[id]) {
+ effect = BattleFormats[id];
+ effect.exists = true;
+ if (!effect.effectType) effect.effectType = 'Format';
+ } else if (id === 'recoil') {
+ effect = {
+ effectType: 'Recoil'
+ };
+ effect.exists = true;
+ } else if (id === 'drain') {
+ effect = {
+ effectType: 'Drain'
+ };
+ effect.exists = true;
+ }
+ if (!effect.id) effect.id = id;
+ if (!effect.name) effect.name = name;
+ if (!effect.category) effect.category = 'Effect';
+ if (!effect.effectType) effect.effectType = 'Effect';
+ }
+ return effect;
+ },
+
+ getMove: function(move) {
+ if (!move || typeof move === 'string') {
+ var name = $.trim(move||'');
+ var id = toId(name);
+ move = (window.BattleMovedex && window.BattleMovedex[id]) || {};
+ if (move.name) move.exists = true;
+
+ if (!move.id) move.id = id;
+ if (!move.name) move.name = name;
+
+ if (!move.critRatio) move.critRatio = 1;
+ if (!move.baseType) move.baseType = move.type;
+ if (!move.effectType) move.effectType = 'Move';
+ if (!move.secondaries && move.secondary) move.secondaries = [move.secondary];
+
+ if (!move.anim) move.anim = BattleOtherAnims.attack.anim;
+ $.extend(move, BattleMoveAnims[move.id]);
+ }
+ return move;
+ },
+
+ getItem: function(item) {
+ if (!item || typeof item === 'string') {
+ var name = $.trim(item||'');
+ var id = toId(name);
+ item = (window.BattleItems && window.BattleItems[id]) || {};
+ if (item.name) item.exists = true;
+ if (!item.id) item.id = id;
+ if (!item.name) item.name = name;
+ if (!item.category) item.category = 'Effect';
+ if (!item.effectType) item.effectType = 'Item';
+ }
+ return item;
+ },
+
+ getAbility: function(ability) {
+ if (!ability || typeof ability === 'string') {
+ var name = $.trim(ability||'');
+ var id = toId(name);
+ ability = (window.BattleAbilities && window.BattleAbilities[id]) || {};
+ if (ability.name) ability.exists = true;
+ if (!ability.id) ability.id = id;
+ if (!ability.name) ability.name = name;
+ if (!ability.category) ability.category = 'Effect';
+ if (!ability.effectType) ability.effectType = 'Ability';
+ }
+ return ability;
+ },
+
+ getTemplate: function(template) {
+ if (!template || typeof template === 'string') {
+ var name = template;
+ var id = toId(name);
+ if (window.BattleAliases && BattleAliases[id]) {
+ name = BattleAliases[id];
+ id = toId(name);
+ }
+ if (!window.BattlePokedex) window.BattlePokedex = {};
+ if (!window.BattlePokedex[id]) {
+ template = window.BattlePokedex[id] = {};
+ for (var k in basespecieschart) {
+ if (id.length > k.length && id.substr(0, k.length) === k) {
+ template.basespecies = k;
+ template.forme = id.substr(k.length);
+ }
+ }
+ template.exists = false;
+ }
+ template = window.BattlePokedex[id];
+ if (template.exists === undefined) template.exists = true;
+ if (window.BattleFormatsData && window.BattleFormatsData[id]) {
+ template.tier = window.BattleFormatsData[id].tier;
+ template.isNonstandard = window.BattleFormatsData[id].isNonstandard;
+ }
+ if (window.BattleLearnsets && window.BattleLearnsets[id]) {
+ template.learnset = window.BattleLearnsets[id].learnset;
+ }
+ if (!template.id) template.id = id;
+ if (!template.name) template.name = name;
+ if (!template.speciesid) template.speciesid = id;
+ if (!template.species) template.species = name;
+ if (!template.basespecies) template.basespecies = name;
+ if (!template.forme) template.forme = '';
+ if (!template.formeletter) template.formeletter = '';
+ if (!template.spriteid) template.spriteid = toId(template.basespecies)+(template.basespecies!==name?'-'+toId(template.forme):'');
+ }
+ return template;
+ },
+
+ getLearnset: function(template) {
+ template = Tools.getTemplate(template);
+ var alreadyChecked = {};
+ var learnset = {};
+ do {
+ alreadyChecked[template.speciesid] = true;
+ if (template.learnset) {
+ for (var l in template.learnset) {
+ learnset[l] = template.learnset[l];
+ }
+ }
+ if (template.speciesid === 'shaymin') {
+ template = Tools.getTemplate('shayminsky');
+ } else if (template.basespecies !== template.species) {
+ template = Tools.getTemplate(template.basespecies);
+ } else {
+ template = Tools.getTemplate(template.prevo);
+ }
+ } while (template && template.species && !alreadyChecked[template.speciesid]);
+ return learnset;
+ },
+
+ getSpriteData: function(pokemon, siden) {
+ pokemon = Tools.getTemplate(pokemon);
+ var isBack = !siden;
+ var back = (siden?'':'-back');
+ var facing = (siden?'front':'back');
+ var cryurl = '';
+ var spriteid = pokemon.spriteid;
+ if (window.BattlePokemonSprites && BattlePokemonSprites[pokemon.speciesid]) {
+ var num = '' + BattlePokemonSprites[pokemon.speciesid].num;
+ if (num.length < 3) num = '0' + num;
+ if (num.length < 3) num = '0' + num;
+ cryurl = '/audio/cries/' + num + '.wav';
+ }
+ if (pokemon.shiny) back += '-shiny';
+ if (window.BattlePokemonSprites && BattlePokemonSprites[pokemon.speciesid] && BattlePokemonSprites[pokemon.speciesid][facing]) {
+ var url = '/sprites/bwani'+back;
+ url += '/'+spriteid;
+ var spriteType = 'ani';
+ if (BattlePokemonSprites[pokemon.speciesid][facing]['anif'] && pokemon.gender === 'F') {
+ url += '-f';
+ spriteType = 'anif';
+ }
+ url += '.gif';
+ return {
+ w: BattlePokemonSprites[pokemon.speciesid][facing][spriteType].w,
+ h: BattlePokemonSprites[pokemon.speciesid][facing][spriteType].h,
+ url: url,
+ cryurl: cryurl,
+ isBackSprite: isBack,
+ shiny: pokemon.shiny
+ };
+ }
+ return {
+ w: 96,
+ h: 96,
+ url: '/sprites/bw'+back+'/' + spriteid + '.png',
+ cryurl: cryurl,
+ isBackSprite: isBack
+ };
+ },
+
+ getIcon: function(pokemon) {
+ var num = 0;
+ if (pokemon === 'pokeball') {
+ return 'background:transparent url(/sprites/bwicons-pokeball-sheet.png) no-repeat scroll -0px -8px';
+ } else if (pokemon === 'pokeball-statused') {
+ return 'background:transparent url(/sprites/bwicons-pokeball-sheet.png) no-repeat scroll -32px -8px';
+ } else if (pokemon === 'pokeball-none') {
+ return 'background:transparent url(/sprites/bwicons-pokeball-sheet.png) no-repeat scroll -64px -8px';
+ }
+ var id = toId(pokemon);
+ if (pokemon && pokemon.species) id = toId(pokemon.species);
+ if (pokemon && pokemon.volatiles && pokemon.volatiles.formechange && !pokemon.volatiles.transform) id = toId(pokemon.volatiles.formechange[2]);
+ if (pokemon && pokemon.num) num = pokemon.num;
+ else if (BattlePokemonSprites[id] && BattlePokemonSprites[id].num) num = BattlePokemonSprites[id].num;
+ else if (exports.BattlePokedex[id] && exports.BattlePokedex[id].num) num = exports.BattlePokedex[id].num;
+ if (num < 0) num = 0;
+ var altNums = {
+ "rotomfan": 699,
+ "rotomfrost": 700,
+ "rotomheat": 701,
+ "rotommow": 702,
+ "rotomwash": 703,
+ "giratinaorigin": 705,
+ "shayminsky": 707,
+ "basculinbluestriped": 709,
+ "darmanitanzen": 712,
+ "deoxysattack": 683,
+ "deoxysdefense": 684,
+ "deoxysspeed": 686,
+ "wormadamsandy": 691,
+ "wormadamtrash": 692,
+ "cherrimsunshine": 694,
+ "castformrainy": 680,
+ "castformsnowy": 681,
+ "castformsunny": 682,
+ "meloettapirouette": 724,
+ "tornadustherian": 736,
+ "thundurustherian": 737,
+ "landorustherian": 738,
+ "kyuremblack": 739,
+ "kyuremwhite": 740,
+ "keldeoresolute": 741,
+ "syclant": 752+0,
+ "revenankh": 752+1,
+ "pyroak": 752+2,
+ "fidgit": 752+3,
+ "stratagem": 752+4,
+ "arghonaut": 752+5,
+ "kitsunoh": 752+6,
+ "cyclohm": 752+7,
+ "colossoil": 752+8,
+ "krilowatt": 752+9,
+ "voodoom": 752+10,
+ "tomohawk": 752+11,
+ "necturna": 752+12,
+ "mollux": 752+13,
+ "aurumoth": 752+14
+ };
+ if (altNums[id]) {
+ num = altNums[id];
+ }
+ if (pokemon && pokemon.gender === 'F') {
+ if (id === 'unfezant') num = 708;
+ else if (id === 'frillish') num = 721;
+ else if (id === 'jellicent') num = 722;
+ }
+
+ var top = 8 + Math.floor(num / 16) * 32;
+ var left = (num % 16) * 32;
+ var fainted = (pokemon && pokemon.fainted?';opacity:.4':'');
+ return 'background:transparent url(/sprites/bwicons-sheet.png?v0.7.18) no-repeat scroll -' + left + 'px -' + top + 'px' + fainted;
+ },
+
+ getTeambuilderSprite: function(pokemon) {
+ if (!pokemon) return '';
+ var id = toId(pokemon);
+ if (pokemon.spriteid) id = pokemon.spriteid;
+ if (pokemon.species && !id) {
+ var template = Tools.getTemplate(pokemon.species);
+ if (template.spriteid) {
+ id = template.spriteid;
+ } else {
+ id = toId(pokemon.species);
+ }
+ }
+ var shiny = (pokemon.shiny?'-shiny':'');
+ if (BattlePokemonSprites && BattlePokemonSprites[id] && BattlePokemonSprites[id].front && BattlePokemonSprites[id].front.anif && pokemon.gender === 'F') {
+ id+='-f';
+ }
+ return 'background-image:url(/sprites/bw'+shiny+'/'+id+'.png)';
+ },
+
+ getItemIcon: function(item) {
+ var num = 0;
+ if (typeof item === 'string' && exports.BattleItems) item = exports.BattleItems[toId(item)];
+ if (item && item.spritenum) num = item.spritenum;
+
+ var top = Math.floor(num / 16) * 24;
+ var left = (num % 16) * 24;
+ return 'background:transparent url(/sprites/itemicons-sheet.png) no-repeat scroll -' + left + 'px -' + top + 'px';
+ },
+
+ getTypeIcon: function(type, b) { // b is just for utilichart.js
+ sanitizedType = type.replace(/\?/g,'%3f');
+ return ' ';
+ }
+};
diff --git a/js/jquery-1.7.min.js b/js/jquery-1.7.min.js
new file mode 100644
index 0000000000..d2424e6528
--- /dev/null
+++ b/js/jquery-1.7.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.7 jquery.com | jquery.org/license */
+(function(a,b){function cA(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cx(a){if(!cm[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cn||(cn=c.createElement("iframe"),cn.frameBorder=cn.width=cn.height=0),b.appendChild(cn);if(!co||!cn.createElement)co=(cn.contentWindow||cn.contentDocument).document,co.write((c.compatMode==="CSS1Compat"?"":"")+""),co.close();d=co.createElement(a),co.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cn)}cm[a]=e}return cm[a]}function cw(a,b){var c={};f.each(cs.concat.apply([],cs.slice(0,b)),function(){c[this]=a});return c}function cv(){ct=b}function cu(){setTimeout(cv,0);return ct=f.now()}function cl(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ck(){try{return new a.XMLHttpRequest}catch(b){}}function ce(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bB(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function br(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bi,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bq(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bp(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bp)}function bp(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bo(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bn(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bm(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(){return!0}function M(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.add(a);return this},eq:function(a){return 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(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return a!=null&&m.test(a)&&!isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;ca ",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,unknownElems:!!a.getElementsByTagName("nav").length,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",enctype:!!c.createElement("form").enctype,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.lastChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-999px",top:"-999px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;f(function(){var a,b,d,e,g,h,i=1,j="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",l="visibility:hidden;border:0;",n="style='"+j+"border:5px solid #000;padding:0;'",p=""+"";m=c.getElementsByTagName("body")[0];!m||(a=c.createElement("div"),a.style.cssText=l+"width:0;height:0;position:static;top:0;margin-top:"+i+"px",m.insertBefore(a,m.firstChild),o=c.createElement("div"),o.style.cssText=j+l,o.innerHTML=p,a.appendChild(o),b=o.firstChild,d=b.firstChild,g=b.nextSibling.firstChild.firstChild,h={doesNotAddBorder:d.offsetTop!==5,doesAddBorderForTableAndCells:g.offsetTop===5},d.style.position="fixed",d.style.top="20px",h.fixedPosition=d.offsetTop===20||d.offsetTop===15,d.style.position=d.style.top="",b.style.overflow="hidden",b.style.position="relative",h.subtractsBorderForOverflowNotVisible=d.offsetTop===-5,h.doesNotIncludeMarginInBodyOffset=m.offsetTop!==i,m.removeChild(a),o=a=null,f.extend(k,h))}),o.innerHTML="",n.removeChild(o),o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[f.expando]:a[f.expando]&&f.expando,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[f.expando]=n=++f.uuid:n=f.expando),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[f.expando]:f.expando;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)?b=b:b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" "));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];if(!arguments.length){if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}return b}e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.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,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!a||j===3||j===8||j===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g},removeAttr:function(a,b){var c,d,e,g,h=0;if(a.nodeType===1){d=(b||"").split(p),g=d.length;for(;h=0}})});var z=/\.(.*)$/,A=/^(?:textarea|input|select)$/i,B=/\./g,C=/ /g,D=/[^\w\s.|`]/g,E=/^([^\.]*)?(?:\.(.+))?$/,F=/\bhover(\.\S+)?/,G=/^key/,H=/^(?:mouse|contextmenu)|click/,I=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,J=function(a){var b=I.exec(a);b&&
+(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},K=function(a,b){return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||a.id===b[2])&&(!b[3]||b[3].test(a.className))},L=function(a){return f.event.special.hover?a:a.replace(F,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=L(c).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"",(g||!e)&&c.preventDefault();if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,n=null;for(m=e.parentNode;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l=0:t===b&&(t=o[s]=r.quick?K(m,r.quick):f(m).is(s)),t&&q.push(r);q.length&&j.push({elem:m,matches:q})}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),G.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),H.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c ",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML=" ",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="
";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var Y="abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",Z=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,_=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,ba=/<([\w:]+)/,bb=/",""],legend:[1,""," "],thead:[1,""],tr:[2,""],td:[3,""],col:[2,""],area:[1,""," "],_default:[0,"",""]},bk=X(c);bj.optgroup=bj.option,bj.tbody=bj.tfoot=bj.colgroup=bj.caption=bj.thead,bj.th=bj.td,f.support.htmlSerialize||(bj._default=[1,"div","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(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){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after"
+,arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Z,""):null;if(typeof a=="string"&&!bd.test(a)&&(f.support.leadingWhitespace||!$.test(a))&&!bj[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(_,"<$1>$2>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bn(a,d),e=bo(a),g=bo(d);for(h=0;e[h];++h)g[h]&&bn(e[h],g[h])}if(b){bm(a,d);if(c){e=bo(a),g=bo(d);for(h=0;e[h];++h)bm(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!bc.test(k))k=b.createTextNode(k);else{k=k.replace(_,"<$1>$2>");var l=(ba.exec(k)||["",""])[1].toLowerCase(),m=bj[l]||bj._default,n=m[0],o=b.createElement("div");b===c?bk.appendChild(o):X(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=bb.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&$.test(k)&&o.insertBefore(b.createTextNode($.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bt.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bs,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bs.test(g)?g.replace(bs,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bB(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bC=function(a,c){var d,e,g;c=c.replace(bu,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bD=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bv.test(f)&&bw.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bB=bC||bD,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bF=/%20/g,bG=/\[\]$/,bH=/\r?\n/g,bI=/#.*$/,bJ=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bK=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bL=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bM=/^(?:GET|HEAD)$/,bN=/^\/\//,bO=/\?/,bP=/
+
+
+
+
+
+
+
+
+
+
+
+
+
Initializing... Surprise, surprise, this requires JavaScript
+
+
+
+ Connecting...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+