<commit_before>$('document').ready(function() {
	requirejs([
		'lavender/masonry',
		'lavender/imagesLoaded',
	], function(Masonry, imagesLoaded) {
		var fixed = localStorage.getItem('fixed') || 0,
			masonry;

		function doMasonry() {
			if($('.home').length) {
				masonry = new Masonry('.row.home > div', {
					itemSelector: '.category-item',
					columnWidth: '.category-item',
					transitionDuration: 0,
					isInitLayout: false
				});

				$('.row.home > div p img').imagesLoaded(function() {
					masonry.layout();
				});

				var saved = JSON.parse(localStorage.getItem('masonry:layout'));
				if (saved) {
					for (var cid in saved) {
						if (saved.hasOwnProperty(cid)) {
							var category = saved[cid];

							$('.category-item[data-cid="' + cid + '"]').css({
								left: category.left,
								top: category.top,
								position: 'absolute'
							});
						}
					}
				}

				masonry.on('layoutComplete', function() {
					var saved = {};

					$('.category-item').each(function() {
						var $this = $(this);

						saved[$this.attr('data-cid')] = {
							left: $this.css('left'),
							top: $this.css('top'),
						};
					});

					localStorage.setItem('masonry:layout', JSON.stringify(saved));
				});
			}
		}

		function resize(fixed) {
			fixed = parseInt(fixed, 10);

			var container = fixed ? $('.container-fluid') : $('.container');
			container.toggleClass('container-fluid', fixed !== 1).toggleClass('container', fixed === 1);
			localStorage.setItem('fixed', fixed);
		}

		resize(fixed);

		$(window).on('action:ajaxify.end', function(ev, data) {
			var url = data.url;

			if(!/^admin\//.test(data.url) && !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
				doMasonry();
				if ($('.home').length) {
					$('.category-header .badge i').tooltip();
				}
			}
		});

		if (!$('.admin').length) {
			setupResizer();
		}

		$(window).on('action:posts.loaded', function() {
			doMasonry();
		});

		function setupResizer() {
			var div = $('

');

			div.css({
				position:'fixed',
				bottom: '20px',
				right: '20px'
			}).hide().appendTo(document.body);

			$(window).on('mousemove', function(ev) {
				if (ev.clientX > $(window).width() - 150 && ev.clientY > $(window).height() - 150) {
					div.fadeIn();
				} else {
					div.stop(true, true).fadeOut();
				}
			});

			div.find('.resizer').on('click', function() {
				fixed = parseInt(fixed, 10) === 1 ? 0 : 1;
				resize(fixed);
				doMasonry();
			});
		}
	});

	(function() {
		// loading animation
		var refreshTitle = app.refreshTitle,
			loadingBar = $('.loading-bar');

		$(window).on('action:ajaxify.start', function(data) {
			loadingBar.fadeIn(0).removeClass('reset');
		});

		$(window).on('action:ajaxify.loadingTemplates', function() {
			loadingBar.css('width', '90%');
		});

		app.refreshTitle = function(url) {
			loadingBar.css('width', '100%');
			setTimeout(function() {
				loadingBar.fadeOut(250);

				setTimeout(function() {
					loadingBar.addClass('reset').css('width', '0%');
				}, 250);
			}, 750);

			return refreshTitle(url);
		};
	}());
});<commit_msg>fixes https://github.com/NodeBB/nodebb-theme-lavender/issues/44<commit_after>$('document').ready(function() {
	requirejs([
		'lavender/masonry',
		'lavender/imagesLoaded',
	], function(Masonry, imagesLoaded) {
		var fixed = localStorage.getItem('fixed') || 0,
			masonry;

		function doMasonry() {
			if($('.home').length) {
				masonry = new Masonry('.row.home > div', {
					itemSelector: '.category-item',
					columnWidth: '.category-item:not(.col-lg-12)',
					transitionDuration: 0,
					isInitLayout: false
				});

				$('.row.home > div p img').imagesLoaded(function() {
					masonry.layout();
				});

				var saved = JSON.parse(localStorage.getItem('masonry:layout'));
				if (saved) {
					for (var cid in saved) {
						if (saved.hasOwnProperty(cid)) {
							var category = saved[cid];

							$('.category-item[data-cid="' + cid + '"]').css({
								left: category.left,
								top: category.top,
								position: 'absolute'
							});
						}
					}
				}

				masonry.on('layoutComplete', function() {
					var saved = {};

					$('.category-item').each(function() {
						var $this = $(this);

						saved[$this.attr('data-cid')] = {
							left: $this.css('left'),
							top: $this.css('top'),
						};
					});

					localStorage.setItem('masonry:layout', JSON.stringify(saved));
				});
			}
		}

		function resize(fixed) {
			fixed = parseInt(fixed, 10);

			var container = fixed ? $('.container-fluid') : $('.container');
			container.toggleClass('container-fluid', fixed !== 1).toggleClass('container', fixed === 1);
			localStorage.setItem('fixed', fixed);
		}

		resize(fixed);

		$(window).on('action:ajaxify.end', function(ev, data) {
			var url = data.url;

			if(!/^admin\//.test(data.url) && !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
				doMasonry();
				if ($('.home').length) {
					$('.category-header .badge i').tooltip();
				}
			}
		});

		if (!$('.admin').length) {
			setupResizer();
		}

		$(window).on('action:posts.loaded', function() {
			doMasonry();
		});

		function setupResizer() {
			var div = $('

');

			div.css({
				position:'fixed',
				bottom: '20px',
				right: '20px'
			}).hide().appendTo(document.body);

			$(window).on('mousemove', function(ev) {
				if (ev.clientX > $(window).width() - 150 && ev.clientY > $(window).height() - 150) {
					div.fadeIn();
				} else {
					div.stop(true, true).fadeOut();
				}
			});

			div.find('.resizer').on('click', function() {
				fixed = parseInt(fixed, 10) === 1 ? 0 : 1;
				resize(fixed);
				doMasonry();
			});
		}
	});

	(function() {
		// loading animation
		var refreshTitle = app.refreshTitle,
			loadingBar = $('.loading-bar');

		$(window).on('action:ajaxify.start', function(data) {
			loadingBar.fadeIn(0).removeClass('reset');
		});

		$(window).on('action:ajaxify.loadingTemplates', function() {
			loadingBar.css('width', '90%');
		});

		app.refreshTitle = function(url) {
			loadingBar.css('width', '100%');
			setTimeout(function() {
				loadingBar.fadeOut(250);

				setTimeout(function() {
					loadingBar.addClass('reset').css('width', '0%');
				}, 250);
			}, 750);

			return refreshTitle(url);
		};
	}());
});<|endoftext|>


<commit_before>"use strict";

class Pokemon {
	constructor(pokemon) {
		if (!pokemon)
			return
		// if pokemon is a base pokemon
		if (typeof pokemon !== "Pokemon" && !pokemon.base && pokemon.abilities) {
			this.base = pokemon
			this.id = pokemon.id
			this.name = pokemon.name
			this.form = pokemon.form
			return
		}
		var poke = stuff.data.getPokemonFrom(pokemon)
		if (!poke)
			return
		this.base = poke.base
		for (var i in pokemon)
			this[i] = pokemon[i]
		this.id = poke.base.id
		this.name = poke.base.name
		this.form = poke.base.form
	}

	get forms() { return this.base.forms }
	get stats() { return this.base.stats }
	get abilities() { return this.base.abilities }
	get classification() { return this.base.classification }
	get description() { return this.base.description }
	get locations() { return this.base.locations }
	get eggGroups() { return this.base.eggGroups }
	get eggs() { return this.base.eggs }
	get evolvesFrom() { return this.base.evolvesFrom }
	get evolvesTo() { return this.base.evolvesTo }
	get height() { return this.base.height }
	get weight() { return this.base.weight }
	get moves() { return this.base.moves }
	get ratio() { return this.base.ratio }
	get types() { return this.base.types }
}

class PokemonData {
	constructor() {
		this.pokemons = []
		this.moves = {}
		this.abilities = {}
		this.natures = {}
		this.eggGroups = []
		this.types = {}
		this.typeNames = []
		this.typeColors = {
			Bug: "#A8B820",
			Dark: "#705848",
			Dragon: "#7038F8",
			Electric: "#F8D030",
			Fairy: "#EE99AC",
			Fighting: "#C03028",
			Fire: "#F08030",
			Flying: "#A890F0",
			Ghost: "#705898",
			Grass: "#78C850",
			Ground: "#E0C068",
			Ice: "#98D8D8",
			Normal: "#A8A878",
			Poison: "#A040A0",
			Psychic: "#F85888",
			Rock: "#B8A038",
			Steel: "#B8B8D0",
			Water: "#6890F0"
		}
	}

	findPokemon(id, form) {
		var pokemon = new Pokemon()
		pokemon.id = id
		var possiblePokes = this.pokemons.filter(e => id == e.id)
		if (possiblePokes.length == 0)
			return null
		pokemon.base = possiblePokes[0]
		if (possiblePokes[0].forms)
			pokemon.form = this.findBestFormFit(possiblePokes[0].forms, form)
		else
			pokemon.form = "Base"
		if (possiblePokes.length > 1) {
			var possibleForms = possiblePokes.filter(e => e.form == pokemon.form)
			if (possibleForms.length == 1)
				pokemon.base = possibleForms[0]
		}
		pokemon.name = pokemon.base.name
		return pokemon
	}

	findBestFormFit(forms, form) {
		if (!form)
			return forms[0]
		var fits = forms.filter(e => e.toLowerCase() == form.toLowerCase())
		if (fits.length)
			return fits[0]
		fits = []
		var words = form.split(" ")
		var highestCount = 0
		for (var i in forms) {
			var count = 0
			for (var j in words)
				if (forms[i].toLowerCase().indexOf(words[j].toLowerCase()) > -1)
					count++
			if (count > highestCount) {
				fits = [forms[i]]
				highestCount = count
			} else if (count == highestCount)
				fits.push(forms[i])
		}
		if (fits.length)
			return fits[0]
		return forms[0]
	}

	getPokemonFrom(idformthing) {
		if (idformthing > 0)
			return this.findPokemon(+idformthing)
		if (typeof idformthing == "string")
			idformthing = { name: idformthing }
		if (!idformthing.id && idformthing.name) {
			var possiblePokes = this.pokemons.filter(e => idformthing.name.toLowerCase() == e.name.toLowerCase())
			if (possiblePokes.length)
				idformthing.id = possiblePokes[0].id
			else
				return false
		}
		return this.findPokemon(idformthing.id, idformthing.form)
	}

	getFilteredPokemons() {
		var pokes = this.pokemons
		if (stuff.state.currentTab == "mine") {
			pokes = []
			for (var i in stuff.collection.pokemons)
				pokes = pokes.concat(stuff.collection.pokemons[i].pokemons)
		} else if (stuff.state.currentTab == "breedables") {
			pokes = []
			for (var i in stuff.collection.pokemons)
				pokes = pokes.concat(stuff.collection.pokemons[i].pokemons)
			pokes = this.getBreedables(pokes)
		} else if (stuff.state.currentTab == "all") {
			pokes = pokes
		} else if (stuff.state.currentTab)
			pokes = stuff.state.currentTab.pokemons

		pokes = this.getCompletionModePokemon(pokes)

		for (var i in stuff.state.filters)
			pokes = pokes.filter(stuff.state.filters[i])
		if (stuff.state.searchFilter)
			pokes = pokes.filter(stuff.state.searchFilter)
		if (stuff.state.sorting){
			pokes.sort(stuff.state.sorting)
			if(stuff.state.reverseSort)
				pokes.reverse()
		}
		return pokes
	}

	getCompletionModePokemon(pokes) {
		if (stuff.state.completionMode == "normal") return pokes
		var basePokes = []
		if (stuff.state.completionMode == "families") {
			for (var n in this.pokemons) {
				var pokemon = this.pokemons[n]
				if (!pokemon.evolvesFrom && basePokes.filter(e => e.id == pokemon.id).length == 0) {
					var newPoke = new Pokemon(pokemon)
					basePokes.push(newPoke)
					var lineIds = this.getPokemonFamilyIds(pokemon)
					if (pokes.filter(e => lineIds.indexOf(e.id) > -1).length)
						newPoke.got = true
				}
			}
		} else if (stuff.state.completionMode == "pokemons") {
			for (var n in this.pokemons) {
				var pokemon = this.pokemons[n]
				if (!basePokes[pokemon.id - 1]) {
					basePokes[pokemon.id - 1] = new Pokemon(pokemon)
					if (pokes.filter(e => e.id == pokemon.id).length)
						basePokes[pokemon.id - 1].got = true
				}
			}
		} else if (stuff.state.completionMode == "forms") {
			var allForms = this.getAllForms()
			for (var i in allForms) {
				for (var j in allForms[i]) {
					var newPoke = this.getPokemonFrom(allForms[i][j])
					if (newPoke.form.startsWith("Mega") ||
						newPoke.form == "Primal" ||
						newPoke.form == "Meteor Form" ||
						newPoke.name == "Castform" && newPoke.form != "Base" ||
						newPoke.name == "Rotom" && newPoke.form != "Base" ||
						newPoke.name == "Meloetta" && newPoke.form != "Aria Forme" ||
						newPoke.name == "Aegislash" && newPoke.form != "Shield Forme" ||
						newPoke.name == "Wishiwashi" && newPoke.form != "Solo Form" ||
						newPoke.name == "Minior" && newPoke.form == "Meteor Form"
					) continue
					basePokes.push(newPoke)
					if (pokes.filter(e => e.id == newPoke.id && e.form == newPoke.form).length)
						newPoke.got = true
				}
			}
		}
		return basePokes
	}

	getPokemonFamilyIds(pokemon, recursion) {
		if (recursion === undefined)
			recursion = 0
		else
			recursion++
		if (!pokemon || recursion > 3) {
			console.log("error with " + JSON.stringify(pokemon))
			return []
		}
		var ids = [pokemon.id]
		for (var i in pokemon.evolvesTo)
			ids = ids.concat(this.getPokemonFamilyIds(this.getPokemonFrom(pokemon.evolvesTo[i]), recursion))
		return ids
	}

	getAllForms() {
		var forms = []
		for (var n in this.pokemons) {
			var pokemon = this.pokemons[n]
			if (!forms[pokemon.id - 1]) {
				if (!pokemon.forms) {
					forms[pokemon.id - 1] = [{ id: pokemon.id, form: pokemon.form }]
					continue
				}
				forms[pokemon.id - 1] = []
				for (var i in pokemon.forms) {
					forms[pokemon.id - 1].push({ id: pokemon.id, form: pokemon.forms[i] })
				}
			}
		}
		return forms
	}

	getBreedables(parentPokemons) {
		var breedables = []
		for (var n in parentPokemons) {
			var pokemon = parentPokemons[n]
			if (!pokemon.eggs)
				continue
			for (var i in pokemon.eggs) {
				//TODO: minior...
				var egg = pokemon.eggs[i]
				var baby = this.getPokemonFrom(egg)
				baby.ivs = pokemon.ivs
				if (this.nearPerfectIvCount(baby.ivs) < 4)
					continue
				baby.nature = pokemon.nature
				var hidden = pokemon.abilities[2] ? pokemon.abilities[2].toLowerCase() == pokemon.ability.split("(")[0].trim().toLowerCase() : false
				if (hidden)
					baby.ability = baby.abilities[2]
				else
					baby.ability = pokemon.abilities[0] + (pokemon.abilities[1] ? " · " + pokemon.abilities[1] : "")
				baby.learntMoves = pokemon.learntMoves.filter(e => baby.moves.filter(o => e.split("(")[0].trim() == o.name && o.method == "egg").length)
				baby.balls = pokemon.balls.filter(e => e)
				var existing = breedables.filter(e => e.id == baby.id && e.form == baby.form && e.ability == baby.ability && e.nature == baby.nature)[0]
				if (existing) {
					existing.balls = this.uniqueBy(existing.balls.concat(baby.balls), e => e)
					existing.learntMoves = this.uniqueBy(existing.learntMoves.concat(baby.learntMoves), e => e)
				}
				else
					breedables.push(baby)
			}
		}
		return breedables
	}

	uniqueBy(list, key) {
		var seen = {};
		return list.filter(function (item) {
			var k = key(item);
			return seen.hasOwnProperty(k) ? false : (seen[k] = true);
		})
	}

	nearPerfectIvCount(ivs) {
		var count = 0
		for (var i in ivs)
			if (ivs[i] >= 30)
				count++
		return count
	}

	tallyDefense(attackType, pokemon) {
		var defense = 1
		defense *= this.getTypeDefense(attackType, pokemon.types[0])
		if (pokemon.types[1])
			defense *= this.getTypeDefense(attackType, pokemon.types[1])
		return defense
	}

	getTypeDefense(attackType, defenseType) {
		if (this.types[defenseType].weaknesses.indexOf(attackType) > -1)
			return 2
		else if (this.types[defenseType].strengths.indexOf(attackType) > -1)
			return 0.5
		else if (this.types[defenseType].immunities.indexOf(attackType) > -1)
			return 0
		return 1
	}

	getGeneration(pokemon) {
		if (pokemon.id <= 151)
			return 1
		if (pokemon.id <= 251)
			return 2
		if (pokemon.id <= 386)
			return 3
		if (pokemon.id <= 493)
			return 4
		if (pokemon.id <= 649)
			return 5
		if (pokemon.id <= 721)
			return 6
		if (pokemon.id <= 802)
			return 7
		return 8
	}

	getTotalBaseStat(pokemon) {
		var count = 0
		for (var i in pokemon.stats)
			count += pokemon.stats[i]
		return count
	}

	getStatAtLevel(pokemon, stat, level) {
		if(pokemon.id == 292 && stat == "hp")
			return 1
		var base = +pokemon.stats[stat]
		var iv = pokemon.ivs ? +pokemon.ivs[stat] : 0
		iv = iv ? iv : 0
		var ev = pokemon.evs ? +pokemon.evs[stat] : 0
		ev = ev ? ev : 0
		if(stat == "hp")
			return Math.floor((2 * base + iv + ev / 4) * level / 100) + 10 + level
		var nature = PokeText.natureCssClass(stat, pokemon)
		switch(nature){
			case "positive-nature": nature = 1.1; break;
			case "negative-nature": nature = 0.9; break;
			default: nature = 1; break;
		}
		return Math.floor((Math.floor((2 * base + iv + ev / 4) * level / 100) + 5) * nature)
	}
}
<commit_msg>Minor bugfix<commit_after>"use strict";

class Pokemon {
	constructor(pokemon) {
		if (!pokemon)
			return
		// if pokemon is a base pokemon
		if (typeof pokemon !== "Pokemon" && !pokemon.base && pokemon.abilities) {
			this.base = pokemon
			this.id = pokemon.id
			this.name = pokemon.name
			this.form = pokemon.form
			return
		}
		var poke = stuff.data.getPokemonFrom(pokemon)
		if (!poke)
			return
		this.base = poke.base
		if (typeof pokemon != "string")
			for (var i in pokemon)
				this[i] = pokemon[i]
		this.id = poke.base.id
		this.name = poke.base.name
		this.form = poke.base.form
	}

	get forms() { return this.base.forms }
	get stats() { return this.base.stats }
	get abilities() { return this.base.abilities }
	get classification() { return this.base.classification }
	get description() { return this.base.description }
	get locations() { return this.base.locations }
	get eggGroups() { return this.base.eggGroups }
	get eggs() { return this.base.eggs }
	get evolvesFrom() { return this.base.evolvesFrom }
	get evolvesTo() { return this.base.evolvesTo }
	get height() { return this.base.height }
	get weight() { return this.base.weight }
	get moves() { return this.base.moves }
	get ratio() { return this.base.ratio }
	get types() { return this.base.types }
}

class PokemonData {
	constructor() {
		this.pokemons = []
		this.moves = {}
		this.abilities = {}
		this.natures = {}
		this.eggGroups = []
		this.types = {}
		this.typeNames = []
		this.typeColors = {
			Bug: "#A8B820",
			Dark: "#705848",
			Dragon: "#7038F8",
			Electric: "#F8D030",
			Fairy: "#EE99AC",
			Fighting: "#C03028",
			Fire: "#F08030",
			Flying: "#A890F0",
			Ghost: "#705898",
			Grass: "#78C850",
			Ground: "#E0C068",
			Ice: "#98D8D8",
			Normal: "#A8A878",
			Poison: "#A040A0",
			Psychic: "#F85888",
			Rock: "#B8A038",
			Steel: "#B8B8D0",
			Water: "#6890F0"
		}
	}

	findPokemon(id, form) {
		var pokemon = new Pokemon()
		pokemon.id = id
		var possiblePokes = this.pokemons.filter(e => id == e.id)
		if (possiblePokes.length == 0)
			return null
		pokemon.base = possiblePokes[0]
		if (possiblePokes[0].forms)
			pokemon.form = this.findBestFormFit(possiblePokes[0].forms, form)
		else
			pokemon.form = "Base"
		if (possiblePokes.length > 1) {
			var possibleForms = possiblePokes.filter(e => e.form == pokemon.form)
			if (possibleForms.length == 1)
				pokemon.base = possibleForms[0]
		}
		pokemon.name = pokemon.base.name
		return pokemon
	}

	findBestFormFit(forms, form) {
		if (!form)
			return forms[0]
		var fits = forms.filter(e => e.toLowerCase() == form.toLowerCase())
		if (fits.length)
			return fits[0]
		fits = []
		var words = form.split(" ")
		var highestCount = 0
		for (var i in forms) {
			var count = 0
			for (var j in words)
				if (forms[i].toLowerCase().indexOf(words[j].toLowerCase()) > -1)
					count++
			if (count > highestCount) {
				fits = [forms[i]]
				highestCount = count
			} else if (count == highestCount)
				fits.push(forms[i])
		}
		if (fits.length)
			return fits[0]
		return forms[0]
	}

	getPokemonFrom(idformthing) {
		if (idformthing > 0)
			return this.findPokemon(+idformthing)
		if (typeof idformthing == "string")
			idformthing = { name: idformthing }
		if (!idformthing.id && idformthing.name) {
			var possiblePokes = this.pokemons.filter(e => idformthing.name.toLowerCase() == e.name.toLowerCase())
			if (possiblePokes.length)
				idformthing.id = possiblePokes[0].id
			else
				return false
		}
		return this.findPokemon(idformthing.id, idformthing.form)
	}

	getFilteredPokemons() {
		var pokes = this.pokemons
		if (stuff.state.currentTab == "mine") {
			pokes = []
			for (var i in stuff.collection.pokemons)
				pokes = pokes.concat(stuff.collection.pokemons[i].pokemons)
		} else if (stuff.state.currentTab == "breedables") {
			pokes = []
			for (var i in stuff.collection.pokemons)
				pokes = pokes.concat(stuff.collection.pokemons[i].pokemons)
			pokes = this.getBreedables(pokes)
		} else if (stuff.state.currentTab == "all") {
			pokes = pokes
		} else if (stuff.state.currentTab)
			pokes = stuff.state.currentTab.pokemons

		pokes = this.getCompletionModePokemon(pokes)

		for (var i in stuff.state.filters)
			pokes = pokes.filter(stuff.state.filters[i])
		if (stuff.state.searchFilter)
			pokes = pokes.filter(stuff.state.searchFilter)
		if (stuff.state.sorting) {
			pokes.sort(stuff.state.sorting)
			if (stuff.state.reverseSort)
				pokes.reverse()
		}
		return pokes
	}

	getCompletionModePokemon(pokes) {
		if (stuff.state.completionMode == "normal") return pokes
		var basePokes = []
		if (stuff.state.completionMode == "families") {
			for (var n in this.pokemons) {
				var pokemon = this.pokemons[n]
				if (!pokemon.evolvesFrom && basePokes.filter(e => e.id == pokemon.id).length == 0) {
					var newPoke = new Pokemon(pokemon)
					basePokes.push(newPoke)
					var lineIds = this.getPokemonFamilyIds(pokemon)
					if (pokes.filter(e => lineIds.indexOf(e.id) > -1).length)
						newPoke.got = true
				}
			}
		} else if (stuff.state.completionMode == "pokemons") {
			for (var n in this.pokemons) {
				var pokemon = this.pokemons[n]
				if (!basePokes[pokemon.id - 1]) {
					basePokes[pokemon.id - 1] = new Pokemon(pokemon)
					if (pokes.filter(e => e.id == pokemon.id).length)
						basePokes[pokemon.id - 1].got = true
				}
			}
		} else if (stuff.state.completionMode == "forms") {
			var allForms = this.getAllForms()
			for (var i in allForms) {
				for (var j in allForms[i]) {
					var newPoke = this.getPokemonFrom(allForms[i][j])
					if (newPoke.form.startsWith("Mega") ||
						newPoke.form == "Primal" ||
						newPoke.form == "Meteor Form" ||
						newPoke.name == "Castform" && newPoke.form != "Base" ||
						newPoke.name == "Rotom" && newPoke.form != "Base" ||
						newPoke.name == "Meloetta" && newPoke.form != "Aria Forme" ||
						newPoke.name == "Aegislash" && newPoke.form != "Shield Forme" ||
						newPoke.name == "Wishiwashi" && newPoke.form != "Solo Form" ||
						newPoke.name == "Minior" && newPoke.form == "Meteor Form"
					) continue
					basePokes.push(newPoke)
					if (pokes.filter(e => e.id == newPoke.id && e.form == newPoke.form).length)
						newPoke.got = true
				}
			}
		}
		return basePokes
	}

	getPokemonFamilyIds(pokemon, recursion) {
		if (recursion === undefined)
			recursion = 0
		else
			recursion++
		if (!pokemon || recursion > 3) {
			console.log("error with " + JSON.stringify(pokemon))
			return []
		}
		var ids = [pokemon.id]
		for (var i in pokemon.evolvesTo)
			ids = ids.concat(this.getPokemonFamilyIds(this.getPokemonFrom(pokemon.evolvesTo[i]), recursion))
		return ids
	}

	getAllForms() {
		var forms = []
		for (var n in this.pokemons) {
			var pokemon = this.pokemons[n]
			if (!forms[pokemon.id - 1]) {
				if (!pokemon.forms) {
					forms[pokemon.id - 1] = [{ id: pokemon.id, form: pokemon.form }]
					continue
				}
				forms[pokemon.id - 1] = []
				for (var i in pokemon.forms) {
					forms[pokemon.id - 1].push({ id: pokemon.id, form: pokemon.forms[i] })
				}
			}
		}
		return forms
	}

	getBreedables(parentPokemons) {
		var breedables = []
		for (var n in parentPokemons) {
			var pokemon = parentPokemons[n]
			if (!pokemon.eggs)
				continue
			for (var i in pokemon.eggs) {
				//TODO: minior...
				var egg = pokemon.eggs[i]
				var baby = this.getPokemonFrom(egg)
				baby.ivs = pokemon.ivs
				if (this.nearPerfectIvCount(baby.ivs) < 4)
					continue
				baby.nature = pokemon.nature
				var hidden = pokemon.abilities[2] ? pokemon.abilities[2].toLowerCase() == pokemon.ability.split("(")[0].trim().toLowerCase() : false
				if (hidden)
					baby.ability = baby.abilities[2]
				else
					baby.ability = pokemon.abilities[0] + (pokemon.abilities[1] ? " · " + pokemon.abilities[1] : "")
				baby.learntMoves = pokemon.learntMoves.filter(e => baby.moves.filter(o => e.split("(")[0].trim() == o.name && o.method == "egg").length)
				baby.balls = pokemon.balls.filter(e => e)
				var existing = breedables.filter(e => e.id == baby.id && e.form == baby.form && e.ability == baby.ability && e.nature == baby.nature)[0]
				if (existing) {
					existing.balls = this.uniqueBy(existing.balls.concat(baby.balls), e => e)
					existing.learntMoves = this.uniqueBy(existing.learntMoves.concat(baby.learntMoves), e => e)
				}
				else
					breedables.push(baby)
			}
		}
		return breedables
	}

	uniqueBy(list, key) {
		var seen = {};
		return list.filter(function (item) {
			var k = key(item);
			return seen.hasOwnProperty(k) ? false : (seen[k] = true);
		})
	}

	nearPerfectIvCount(ivs) {
		var count = 0
		for (var i in ivs)
			if (ivs[i] >= 30)
				count++
		return count
	}

	tallyDefense(attackType, pokemon) {
		var defense = 1
		defense *= this.getTypeDefense(attackType, pokemon.types[0])
		if (pokemon.types[1])
			defense *= this.getTypeDefense(attackType, pokemon.types[1])
		return defense
	}

	getTypeDefense(attackType, defenseType) {
		if (this.types[defenseType].weaknesses.indexOf(attackType) > -1)
			return 2
		else if (this.types[defenseType].strengths.indexOf(attackType) > -1)
			return 0.5
		else if (this.types[defenseType].immunities.indexOf(attackType) > -1)
			return 0
		return 1
	}

	getGeneration(pokemon) {
		if (pokemon.id <= 151)
			return 1
		if (pokemon.id <= 251)
			return 2
		if (pokemon.id <= 386)
			return 3
		if (pokemon.id <= 493)
			return 4
		if (pokemon.id <= 649)
			return 5
		if (pokemon.id <= 721)
			return 6
		if (pokemon.id <= 802)
			return 7
		return 8
	}

	getTotalBaseStat(pokemon) {
		var count = 0
		for (var i in pokemon.stats)
			count += pokemon.stats[i]
		return count
	}

	getStatAtLevel(pokemon, stat, level) {
		if (pokemon.id == 292 && stat == "hp")
			return 1
		var base = +pokemon.stats[stat]
		var iv = pokemon.ivs ? +pokemon.ivs[stat] : 0
		iv = iv ? iv : 0
		var ev = pokemon.evs ? +pokemon.evs[stat] : 0
		ev = ev ? ev : 0
		if (stat == "hp")
			return Math.floor((2 * base + iv + ev / 4) * level / 100) + 10 + level
		var nature = PokeText.natureCssClass(stat, pokemon)
		switch (nature) {
			case "positive-nature": nature = 1.1; break;
			case "negative-nature": nature = 0.9; break;
			default: nature = 1; break;
		}
		return Math.floor((Math.floor((2 * base + iv + ev / 4) * level / 100) + 5) * nature)
	}
}
<|endoftext|>


<commit_before>'use strict';

var services = angular.module('firenodejs.services');

services.factory('firestep-service', ['$http', 'AlertService',
    function($http, alerts) {
        var available = null;
        var service = {
            model: {},
            count: 0, // command count (changes imply model updated)
            jog: 10,
            isAvailable: function() {
                return available;
            },
            marks: {
                "mark1": {
                    x: 0,
                    y: 0,
                    z: 0
                },
                "mark2": {
                    x: 0,
                    y: 0,
                    z: 0
                },
                "mark3": {
                    x: 0,
                    y: 0,
                    z: 0
                }
            },
            mark: function(name) {
                service.marks[name] = service.marks[name] || {
                    x: 0,
                    y: 0,
                    z: 0
                };
                service.marks[name].x = service.model.mpo.x;
                service.marks[name].y = service.model.mpo.y;
                service.marks[name].z = service.model.mpo.z;
                return service;
            },
            goto: function(name) {
                service.marks[name] = service.marks[name] || {
                    x: 0,
                    y: 0,
                    z: 0
                };
                service.mov(service.marks[name]);
            },
            send: function(data) {
                var sdata = JSON.stringify(data) + "\n";
                alerts.taskBegin();
                $http.post("/firestep", data).success(function(response, status, headers, config) {
                    console.debug("firestep.send(", data, " => ", response);
                    if (response.r.mpo) {
                        service.model.mpo = response.r.mpo;
                    }
                    service.count++;
                    alerts.taskEnd();
                }).error(function(err, status, headers, config) {
                    console.warn("firestep.send(", data, ") failed HTTP" + status);
                    service.count++;
                    alerts.taskEnd();
                });
            },
            hom: function() {
                service.send([{
                    "hom": ""
                }, {
                    "mpo": ""
                }]);
                return service;
            },
            movr: function(pos) {
                var args = {};
                var cmd = [{
                    "mov": args
                }, {
                    "mpo": ""
                }, {
                    "dpyds": 12
                }];
                if (pos.hasOwnProperty("x")) {
                    args.xr = pos.x;
                }
                if (pos.hasOwnProperty("y")) {
                    args.yr = pos.y;
                }
                if (pos.hasOwnProperty("z")) {
                    args.zr = pos.z;
                }
                if (pos.hasOwnProperty("a")) {
                    args.ar = pos.a;
                }
                service.send(cmd);
                return service;
            },
            mov: function(pos) {
                var args = {};
                var cmd = [{
                    "mov": args
                }, {
                    "mpo": ""
                }];
                if (pos.hasOwnProperty("x")) {
                    args.x = pos.x;
                }
                if (pos.hasOwnProperty("y")) {
                    args.y = pos.y;
                }
                if (pos.hasOwnProperty("z")) {
                    args.z = pos.z;
                }
                if (pos.hasOwnProperty("a")) {
                    args.a = pos.a;
                }
                service.send(cmd);
                return service;
            }
        };

        alerts.taskBegin();
        $.ajax({
            url: "/firestep/model",
            success: function(data) {
                available = data && data.available;
                console.log("firestep available:", available);
                service.model = data;
                alerts.taskEnd();
                service.count++;
            },
            error: function(jqXHR, ex) {
                available = false;
                console.warn("firestep not available");
                transmit.end();
                service.count++;
            }
        });
        return service;
    }
]);
<commit_msg>camera light on move<commit_after>'use strict';

var services = angular.module('firenodejs.services');

services.factory('firestep-service', ['$http', 'AlertService',
    function($http, alerts) {
        var available = null;
        var service = {
            model: {},
            count: 0, // command count (changes imply model updated)
            jog: 10,
            isAvailable: function() {
                return available;
            },
            marks: {
                "mark1": {
                    x: 0,
                    y: 0,
                    z: 0
                },
                "mark2": {
                    x: 0,
                    y: 0,
                    z: 0
                },
                "mark3": {
                    x: 0,
                    y: 0,
                    z: 0
                }
            },
            mark: function(name) {
                service.marks[name] = service.marks[name] || {
                    x: 0,
                    y: 0,
                    z: 0
                };
                service.marks[name].x = service.model.mpo.x;
                service.marks[name].y = service.model.mpo.y;
                service.marks[name].z = service.model.mpo.z;
                return service;
            },
            goto: function(name) {
                service.marks[name] = service.marks[name] || {
                    x: 0,
                    y: 0,
                    z: 0
                };
                service.mov(service.marks[name]);
            },
            send: function(data) {
                var sdata = JSON.stringify(data) + "\n";
                alerts.taskBegin();
                $http.post("/firestep", data).success(function(response, status, headers, config) {
                    console.debug("firestep.send(", data, " => ", response);
                    if (response.r.mpo) {
                        service.model.mpo = response.r.mpo;
                    }
                    service.count++;
                    alerts.taskEnd();
                }).error(function(err, status, headers, config) {
                    console.warn("firestep.send(", data, ") failed HTTP" + status);
                    service.count++;
                    alerts.taskEnd();
                });
            },
            hom: function() {
                service.send([{
                    "hom": ""
                }, {
                    "mpo": ""
                }, {
                    "dpyds":12
                }]);
                return service;
            },
            movr: function(pos) {
                var args = {};
                var cmd = [{
                    "mov": args
                }, {
                    "mpo": ""
                }, {
                    "dpyds": 12
                }];
                if (pos.hasOwnProperty("x")) {
                    args.xr = pos.x;
                }
                if (pos.hasOwnProperty("y")) {
                    args.yr = pos.y;
                }
                if (pos.hasOwnProperty("z")) {
                    args.zr = pos.z;
                }
                if (pos.hasOwnProperty("a")) {
                    args.ar = pos.a;
                }
                service.send(cmd);
                return service;
            },
            mov: function(pos) {
                var args = {};
                var cmd = [{
                    "mov": args
                }, {
                    "mpo": ""
                }];
                if (pos.hasOwnProperty("x")) {
                    args.x = pos.x;
                }
                if (pos.hasOwnProperty("y")) {
                    args.y = pos.y;
                }
                if (pos.hasOwnProperty("z")) {
                    args.z = pos.z;
                }
                if (pos.hasOwnProperty("a")) {
                    args.a = pos.a;
                }
                service.send(cmd);
                return service;
            }
        };

        alerts.taskBegin();
        $.ajax({
            url: "/firestep/model",
            success: function(data) {
                available = data && data.available;
                console.log("firestep available:", available);
                service.model = data;
                alerts.taskEnd();
                service.count++;
            },
            error: function(jqXHR, ex) {
                available = false;
                console.warn("firestep not available");
                transmit.end();
                service.count++;
            }
        });
        return service;
    }
]);
<|endoftext|>


<commit_before>Ext.define('Ext.form.field.Color', {
    extend: 'Ext.form.field.Picker',

    constructor: function( config ) {
        Ext.form.field.Color.superclass.constructor.call(this, config);
        this.addEvents("valueChange");
    },

    initComponent: function() {
        Ext.form.field.Color.superclass.initComponent.call(this);

        this.listeners = Ext.applyIf({
            afterRender: function() {
                this.setRawValue(Util.fromJavaRGB(this.value));

                this.inputEl.addKeyMap( {
                    key: Ext.EventObject.ENTER,
                    fn: function() {
                        this.setRawValue(this.getRawValue());
                        this.fireEvent("valueChange");
                    },
                    scope: this
                })
            }, scope: this
        }, this.listeners);
    },

    createPicker: function() {
        return Ext.create('Ext.picker.Color', {
            renderTo: document.body,
            floating: true,
            ownerCt: this.ownerCt,
            pickerOffset: 0,
            height: 150,
            listeners: {
                select: function() {
                    this.onSelect();
                }, scope: this
            }
        });
    },

    alignPicker: function() {
        Ext.form.field.Color.superclass.alignPicker.call(this);
        this.picker.setHeight(100);
    },

    onSelect: function() {
        this.setRawValue(this.picker.getValue());
        this.fireEvent("select", this, this.picker.getValue());
        this.collapse();
    },

    setRawValue: function(v) {
        Ext.form.field.Color.superclass.setRawValue.call(this, v);
        if ( v != null && v != '' && this.inputEl ) {
            this.inputEl.setStyle( {
                'background': 'none',
                'background-color': '#' + v
            });
        }
    },

    rawToValue: function(rawV) {
        return "" + Util.toJavaRGB(rawV);
    }
});<commit_msg>Resolved issue with color picker #7<commit_after>Ext.define('Ext.form.field.Color', {
    extend: 'Ext.form.field.Picker',

    constructor: function( config ) {
        Ext.form.field.Color.superclass.constructor.call(this, config);
        this.addEvents("valueChange");
    },

    initComponent: function() {
        Ext.form.field.Color.superclass.initComponent.call(this);

        this.listeners = Ext.applyIf({
            afterRender: function() {
                this.setRawValue(Util.fromJavaRGB(this.value));

                this.inputEl.addKeyMap( {
                    key: Ext.EventObject.ENTER,
                    fn: function() {
                        this.setRawValue(this.getRawValue());
                        this.fireEvent("valueChange");
                    },
                    scope: this
                })
            }, scope: this
        }, this.listeners);
    },

    createPicker: function() {
        return Ext.create('Ext.picker.Color', {
            renderTo: document.body,
            floating: true,
            ownerCt: this.ownerCt,
            pickerOffset: 0,
            height: 150,
            listeners: {
                select: function() {
                    this.onSelect();
                }, scope: this
            }
        });
    },

    alignPicker: function() {
        Ext.form.field.Color.superclass.alignPicker.call(this);
        this.picker.setHeight(130);
    },

    onSelect: function() {
        this.setRawValue(this.picker.getValue());
        this.fireEvent("select", this, this.picker.getValue());
        this.collapse();
    },

    setRawValue: function(v) {
        Ext.form.field.Color.superclass.setRawValue.call(this, v);
        if ( v != null && v != '' && this.inputEl ) {
            this.inputEl.setStyle( {
                'background': 'none',
                'background-color': '#' + v
            });
        }
    },

    rawToValue: function(rawV) {
        return "" + Util.toJavaRGB(rawV);
    }
});<|endoftext|>


<commit_before>import {
  isNumber,
  isValid,
  isValidIntRange,
  isStringWithComma,
} from '../src/validations'

describe('>>>>> Validator Functions Tests', () => {
  describe('.isNumber', () => {
    it('validates a number', () => {
      const valueToTest = 11

      expect(isNumber(valueToTest)).toBeTruthy()
    })

    it('validates a string with a number', () => {
      const valueToTest = '11'

      expect(isNumber(valueToTest)).toBeTruthy()
    })

    it('don\'t validate an empty string', () => {
      const valueToTest = ''

      expect(isNumber(valueToTest)).toBeFalsy()
    })

    it('don\'t validate a string with characters', () => {
      const valueToTest = 'a11'

      expect(isNumber(valueToTest)).toBeFalsy()
    })

    it('don\'t validate a boolean', () => {
      const valueToTest = 'false'

      expect(isNumber(valueToTest)).toBeFalsy()
    })
  })

  describe('.isValid', () => {
    it('returns false if input value is null', () => {
      const valueToTest = null

      expect(isValid(valueToTest)).toBeFalsy()
    })

    it('returns false if input value is undefined', () => {
      const valueToTest = undefined

      expect(isValid(valueToTest)).toBeFalsy()
    })

    it('returns false if input value is an empty string', () => {
      const valueToTest = ''

      expect(isValid(valueToTest)).toBeFalsy()
    })

    it('validates a non empty string', () => {
      const valueToTest = 'true value'

      expect(isValid(valueToTest)).toBeTruthy()
    })

    describe('when maxLength is specified', () => {
      it('return false if string has length greater than maxLength', () => {
        const valueToTest = 'true value greater'

        expect(isValid(valueToTest, 10)).toBeFalsy()
      })

      it('validates a non empty string with length equal to maxLength', () => {
        const valueToTest = 'true value'

        expect(isValid(valueToTest, 10)).toBeTruthy()
      })

      it('validates a non empty string with length less than maxLength', () => {
        const valueToTest = 'true val'

        expect(isValid(valueToTest, 10)).toBeTruthy()
      })
    })
  })

  describe('.isValidIntRange', () => {
    it('don\'t validate an empty string', () => {
      const valueToTest = ''

      expect(isValidIntRange(valueToTest)).toBeFalsy()
    })

    it('don\'t validate a range with only one value', () => {
      const valueToTest = '12-'

      expect(isValidIntRange(valueToTest)).toBeFalsy()
    })

    it('don\'t validate a range with characters', () => {
      const valueToTest = '12-1234a'

      expect(isValidIntRange(valueToTest)).toBeFalsy()
    })

    it('don\'t validate a range with the first number greater than the second', () => {
      const valueToTest = '32-16'

      expect(isValidIntRange(valueToTest)).toBeFalsy()
    })

    it('validate a range with two numbers', () => {
      const valueToTest = '1-25'

      expect(isValidIntRange(valueToTest)).toBeTruthy()
    })

    it('don\'t validate a range with unsigned numbers', () => {
      const valueToTest = '-2--1'

      expect(isValidIntRange(valueToTest)).toBeFalsy()
    })
  })

  describe('.isStringWithComma', () => {
    it('validates strings containing at least one comma', () => {
      const oneComma = '1,2'
      const twoCommas = 'a, b,c'
      const allCommas = ',,,,,,'

      expect(isStringWithComma(oneComma)).toBeTruthy()
      expect(isStringWithComma(twoCommas)).toBeTruthy()
      expect(isStringWithComma(allCommas)).toBeTruthy()
    })

    it('returns false if input value has no commas', () => {
      const oneComma = '12'
      const twoCommas = 'a bc'
      const allCommas = ''

      expect(isStringWithComma(oneComma)).toBeFalsy()
      expect(isStringWithComma(twoCommas)).toBeFalsy()
      expect(isStringWithComma(allCommas)).toBeFalsy()
    })

    it('returns false if input value is a number, null, or undefined', () => {
      expect(isStringWithComma(123)).toBeFalsy()
      expect(isStringWithComma(null)).toBeFalsy()
      expect(isStringWithComma(undefined)).toBeFalsy()
    })
  })
})
<commit_msg>Ensure that tests contain only one expect<commit_after>import {
  isNumber,
  isValid,
  isValidIntRange,
  isStringWithComma,
} from '../src/validations'

describe('>>>>> Validator Functions Tests', () => {
  describe('.isNumber', () => {
    it('validates a number', () => {
      const valueToTest = 11

      expect(isNumber(valueToTest)).toBeTruthy()
    })

    it('validates a string with a number', () => {
      const valueToTest = '11'

      expect(isNumber(valueToTest)).toBeTruthy()
    })

    it('don\'t validate an empty string', () => {
      const valueToTest = ''

      expect(isNumber(valueToTest)).toBeFalsy()
    })

    it('don\'t validate a string with characters', () => {
      const valueToTest = 'a11'

      expect(isNumber(valueToTest)).toBeFalsy()
    })

    it('don\'t validate a boolean', () => {
      const valueToTest = 'false'

      expect(isNumber(valueToTest)).toBeFalsy()
    })
  })

  describe('.isValid', () => {
    it('returns false if input value is null', () => {
      const valueToTest = null

      expect(isValid(valueToTest)).toBeFalsy()
    })

    it('returns false if input value is undefined', () => {
      const valueToTest = undefined

      expect(isValid(valueToTest)).toBeFalsy()
    })

    it('returns false if input value is an empty string', () => {
      const valueToTest = ''

      expect(isValid(valueToTest)).toBeFalsy()
    })

    it('validates a non empty string', () => {
      const valueToTest = 'true value'

      expect(isValid(valueToTest)).toBeTruthy()
    })

    describe('when maxLength is specified', () => {
      it('return false if string has length greater than maxLength', () => {
        const valueToTest = 'true value greater'

        expect(isValid(valueToTest, 10)).toBeFalsy()
      })

      it('validates a non empty string with length equal to maxLength', () => {
        const valueToTest = 'true value'

        expect(isValid(valueToTest, 10)).toBeTruthy()
      })

      it('validates a non empty string with length less than maxLength', () => {
        const valueToTest = 'true val'

        expect(isValid(valueToTest, 10)).toBeTruthy()
      })
    })
  })

  describe('.isValidIntRange', () => {
    it('don\'t validate an empty string', () => {
      const valueToTest = ''

      expect(isValidIntRange(valueToTest)).toBeFalsy()
    })

    it('don\'t validate a range with only one value', () => {
      const valueToTest = '12-'

      expect(isValidIntRange(valueToTest)).toBeFalsy()
    })

    it('don\'t validate a range with characters', () => {
      const valueToTest = '12-1234a'

      expect(isValidIntRange(valueToTest)).toBeFalsy()
    })

    it('don\'t validate a range with the first number greater than the second', () => {
      const valueToTest = '32-16'

      expect(isValidIntRange(valueToTest)).toBeFalsy()
    })

    it('validate a range with two numbers', () => {
      const valueToTest = '1-25'

      expect(isValidIntRange(valueToTest)).toBeTruthy()
    })

    it('don\'t validate a range with unsigned numbers', () => {
      const valueToTest = '-2--1'

      expect(isValidIntRange(valueToTest)).toBeFalsy()
    })
  })

  describe('.isStringWithComma', () => {
    it('validates strings containing two comma-separated values', () => {
      const valueToTest = '1,2'

      expect(isStringWithComma(valueToTest)).toBeTruthy()
    })

    it('validates strings containing several comma-separated values', () => {
      const valueToTest = 'a, b,c'

      expect(isStringWithComma(valueToTest)).toBeTruthy()
    })

    it('validates strings containing all commas', () => {
      const valueToTest = ',,,,,,'

      expect(isStringWithComma(valueToTest)).toBeTruthy()
    })

    it('returns false if input value has no commas', () => {
      const valueToTest = 'a bc !def '
      expect(isStringWithComma(valueToTest)).toBeFalsy()
    })

    it('returns false if input value is an empty string', () => {
      const valueToTest = ''

      expect(isStringWithComma(valueToTest)).toBe(false)
    })

    it('returns false if input value is a number', () => {
      const valueToTest = 123

      expect(isStringWithComma(valueToTest)).toBe(false)
    })

    it('returns false if input value is null', () => {
      const valueToTest = null

      expect(isStringWithComma(valueToTest)).toBe(false)
    })

    it('returns false if input value is undefined', () => {
      const valueToTest = undefined

      expect(isStringWithComma(valueToTest)).toBe(false)
    })
  })
})
<|endoftext|>


<commit_before>/*global define*/
define([
        './BoundingSphere',
        './Cartesian3',
        './ComponentDatatype',
        './defaultValue',
        './defined',
        './DeveloperError',
        './Ellipsoid',
        './Geometry',
        './GeometryAttribute',
        './GeometryAttributes',
        './IndexDatatype',
        './Math',
        './PrimitiveType'
    ], function(
        BoundingSphere,
        Cartesian3,
        ComponentDatatype,
        defaultValue,
        defined,
        DeveloperError,
        Ellipsoid,
        Geometry,
        GeometryAttribute,
        GeometryAttributes,
        IndexDatatype,
        CesiumMath,
        PrimitiveType) {
    "use strict";

    var defaultRadii = new Cartesian3(1.0, 1.0, 1.0);
    var cos = Math.cos;
    var sin = Math.sin;

    /**
     * A description of the outline of an ellipsoid centered at the origin.
     *
     * @alias EllipsoidOutlineGeometry
     * @constructor
     *
     * @param {Object} [options] Object with the following properties:
     * @param {Cartesian3} [options.radii=Cartesian3(1.0, 1.0, 1.0)] The radii of the ellipsoid in the x, y, and z directions.
     * @param {Number} [options.stackPartitions=10] The count of stacks for the ellipsoid (1 greater than the number of parallel lines).
     * @param {Number} [options.slicePartitions=8] The count of slices for the ellipsoid (Equal to the number of radial lines).
     * @param {Number} [options.subdivisions=128] The number of points per line, determining the granularity of the curvature .
     *
     * @exception {DeveloperError} options.stackPartitions must be greater than or equal to one.
     * @exception {DeveloperError} options.slicePartitions must be greater than or equal to zero.
     * @exception {DeveloperError} options.subdivisions must be greater than or equal to zero.
     *
     * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Ellipsoid%20Outline.html|Cesium Sandcastle Ellipsoid Outline Demo}
     *
     * @example
     * var ellipsoid = new Cesium.EllipsoidOutlineGeometry({
     *   radii : new Cesium.Cartesian3(1000000.0, 500000.0, 500000.0),
     *   stackPartitions: 6,
     *   slicePartitions: 5
     * });
     * var geometry = Cesium.EllipsoidOutlineGeometry.createGeometry(ellipsoid);
     */
    function EllipsoidOutlineGeometry(options) {
        options = defaultValue(options, defaultValue.EMPTY_OBJECT);

        var radii = defaultValue(options.radii, defaultRadii);
        var stackPartitions = defaultValue(options.stackPartitions, 10);
        var slicePartitions = defaultValue(options.slicePartitions, 8);
        var subdivisions = defaultValue(options.subdivisions, 128);

        //>>includeStart('debug', pragmas.debug);
        if (stackPartitions < 1) {
            throw new DeveloperError('options.stackPartitions cannot be less than 1');
        }
        if (slicePartitions < 0) {
            throw new DeveloperError('options.slicePartitions cannot be less than 0');
        }
        if (subdivisions < 0) {
            throw new DeveloperError('options.subdivisions must be greater than or equal to zero.');
        }
        //>>includeEnd('debug');

        this._radii = Cartesian3.clone(radii);
        this._stackPartitions = stackPartitions;
        this._slicePartitions = slicePartitions;
        this._subdivisions = subdivisions;
        this._workerName = 'createEllipsoidOutlineGeometry';
    }

    /**
     * The number of elements used to pack the object into an array.
     * @type {Number}
     */
    EllipsoidOutlineGeometry.packedLength = Cartesian3.packedLength + 3;

    /**
     * Stores the provided instance into the provided array.
     * @function
     *
     * @param {EllipsoidOutlineGeometry} value The value to pack.
     * @param {Number[]} array The array to pack into.
     * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
     */
    EllipsoidOutlineGeometry.pack = function(value, array, startingIndex) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(value)) {
            throw new DeveloperError('value is required');
        }
        if (!defined(array)) {
            throw new DeveloperError('array is required');
        }
        //>>includeEnd('debug');

        startingIndex = defaultValue(startingIndex, 0);

        Cartesian3.pack(value._radii, array, startingIndex);
        startingIndex += Cartesian3.packedLength;

        array[startingIndex++] = value._stackPartitions;
        array[startingIndex++] = value._slicePartitions;
        array[startingIndex]   = value._subdivisions;
    };

    var scratchRadii = new Cartesian3();
    var scratchOptions = {
        radii : scratchRadii,
        stackPartitions : undefined,
        slicePartitions : undefined,
        subdivisions : undefined
    };

    /**
     * Retrieves an instance from a packed array.
     *
     * @param {Number[]} array The packed array.
     * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
     * @param {EllipsoidOutlineGeometry} [result] The object into which to store the result.
     * @returns {EllipsoidOutlineGeometry} The modified result parameter or a new EllipsoidOutlineGeometry instance if one was not provided.
     */
    EllipsoidOutlineGeometry.unpack = function(array, startingIndex, result) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(array)) {
            throw new DeveloperError('array is required');
        }
        //>>includeEnd('debug');

        startingIndex = defaultValue(startingIndex, 0);

        var radii = Cartesian3.unpack(array, startingIndex, scratchRadii);
        startingIndex += Cartesian3.packedLength;

        var stackPartitions = array[startingIndex++];
        var slicePartitions = array[startingIndex++];
        var subdivisions = array[startingIndex++];

        if (!defined(result)) {
            scratchOptions.stackPartitions = stackPartitions;
            scratchOptions.slicePartitions = slicePartitions;
            scratchOptions.subdivisions = subdivisions;
            return new EllipsoidOutlineGeometry(scratchOptions);
        }

        result._radii = Cartesian3.clone(radii, result._radii);
        result._stackPartitions = stackPartitions;
        result._slicePartitions = slicePartitions;
        result._subdivisions = subdivisions;

        return result;
    };

    /**
     * Computes the geometric representation of an outline of an ellipsoid, including its vertices, indices, and a bounding sphere.
     *
     * @param {EllipsoidOutlineGeometry} ellipsoidGeometry A description of the ellipsoid outline.
     * @returns {Geometry} The computed vertices and indices.
     */
    EllipsoidOutlineGeometry.createGeometry = function(ellipsoidGeometry) {
        var radii = ellipsoidGeometry._radii;
        var ellipsoid = Ellipsoid.fromCartesian3(radii);
        var stackPartitions = ellipsoidGeometry._stackPartitions;
        var slicePartitions = ellipsoidGeometry._slicePartitions;
        var subdivisions = ellipsoidGeometry._subdivisions;

        var indicesSize = subdivisions * (stackPartitions + slicePartitions - 1);
        var positionSize = indicesSize - slicePartitions + 2;
        var positions = new Float64Array(positionSize * 3);
        var indices = IndexDatatype.createTypedArray(positionSize, indicesSize * 2);

        var i;
        var j;
        var theta;
        var phi;
        var cosPhi;
        var sinPhi;
        var index = 0;

        var cosTheta = new Array(subdivisions);
        var sinTheta = new Array(subdivisions);
        for (i = 0; i < subdivisions; i++) {
            theta = CesiumMath.TWO_PI * i / subdivisions;
            cosTheta[i] = cos(theta);
            sinTheta[i] = sin(theta);
        }

        for (i = 1; i < stackPartitions; i++) {
            phi = Math.PI * i / stackPartitions;
            cosPhi = cos(phi);
            sinPhi = sin(phi);

            for (j = 0; j < subdivisions; j++) {
                positions[index++] = radii.x * cosTheta[j] * sinPhi;
                positions[index++] = radii.y * sinTheta[j] * sinPhi;
                positions[index++] = radii.z * cosPhi;
            }
        }

        cosTheta.length = slicePartitions;
        sinTheta.length = slicePartitions;
        for (i = 0; i < slicePartitions; i++) {
            theta = CesiumMath.TWO_PI * i / slicePartitions;
            cosTheta[i] = cos(theta);
            sinTheta[i] = sin(theta);
        }

        positions[index++] = 0;
        positions[index++] = 0;
        positions[index++] = radii.z;

        for (i = 1; i < subdivisions; i++) {
            phi = Math.PI * i / subdivisions;
            cosPhi = cos(phi);
            sinPhi = sin(phi);

            for (j = 0; j < slicePartitions; j++) {
                positions[index++] = radii.x * cosTheta[j] * sinPhi;
                positions[index++] = radii.y * sinTheta[j] * sinPhi;
                positions[index++] = radii.z * cosPhi;
            }
        }

        positions[index++] = 0;
        positions[index++] = 0;
        positions[index++] = -radii.z;

        index = 0;
        for (i = 0; i < stackPartitions - 1; ++i) {
            var topRowOffset = (i * subdivisions);
            for (j = 0; j < subdivisions - 1; ++j) {
                indices[index++] = topRowOffset + j;
                indices[index++] = topRowOffset + j + 1;
            }

            indices[index++] = topRowOffset + subdivisions - 1;
            indices[index++] = topRowOffset;
        }

        var sliceOffset = subdivisions * (stackPartitions - 1);
        for (j = 1; j < slicePartitions + 1; ++j) {
            indices[index++] = sliceOffset;
            indices[index++] = sliceOffset + j;
        }

        for (i = 0; i < subdivisions - 2; ++i) {
            var topOffset = (i * slicePartitions) + 1 + sliceOffset;
            var bottomOffset = ((i + 1) * slicePartitions) + 1 + sliceOffset;

            for (j = 0; j < slicePartitions - 1; ++j) {
                indices[index++] = bottomOffset + j;
                indices[index++] = topOffset + j;
            }

            indices[index++] = bottomOffset + slicePartitions - 1;
            indices[index++] = topOffset + slicePartitions - 1;
        }

        var lastPosition = positions.length / 3 - 1;
        for (j = lastPosition - 1; j > lastPosition - slicePartitions - 1; --j) {
            indices[index++] = lastPosition;
            indices[index++] = j;
        }

        var attributes = new GeometryAttributes({
            position: new GeometryAttribute({
                componentDatatype : ComponentDatatype.DOUBLE,
                componentsPerAttribute : 3,
                values : positions
            })
        });

        return new Geometry({
            attributes : attributes,
            indices : indices,
            primitiveType : PrimitiveType.LINES,
            boundingSphere : BoundingSphere.fromEllipsoid(ellipsoid)
        });
    };

    return EllipsoidOutlineGeometry;
});
<commit_msg>Update EllipsoidOutlineGeometry.js<commit_after>/*global define*/
define([
        './BoundingSphere',
        './Cartesian3',
        './ComponentDatatype',
        './defaultValue',
        './defined',
        './DeveloperError',
        './Ellipsoid',
        './Geometry',
        './GeometryAttribute',
        './GeometryAttributes',
        './IndexDatatype',
        './Math',
        './PrimitiveType'
    ], function(
        BoundingSphere,
        Cartesian3,
        ComponentDatatype,
        defaultValue,
        defined,
        DeveloperError,
        Ellipsoid,
        Geometry,
        GeometryAttribute,
        GeometryAttributes,
        IndexDatatype,
        CesiumMath,
        PrimitiveType) {
    "use strict";

    var defaultRadii = new Cartesian3(1.0, 1.0, 1.0);
    var cos = Math.cos;
    var sin = Math.sin;

    /**
     * A description of the outline of an ellipsoid centered at the origin.
     *
     * @alias EllipsoidOutlineGeometry
     * @constructor
     *
     * @param {Object} [options] Object with the following properties:
     * @param {Cartesian3} [options.radii=Cartesian3(1.0, 1.0, 1.0)] The radii of the ellipsoid in the x, y, and z directions.
     * @param {Number} [options.stackPartitions=10] The count of stacks for the ellipsoid (1 greater than the number of parallel lines).
     * @param {Number} [options.slicePartitions=8] The count of slices for the ellipsoid (Equal to the number of radial lines).
     * @param {Number} [options.subdivisions=128] The number of points per line, determining the granularity of the curvature .
     *
     * @exception {DeveloperError} options.stackPartitions must be greater than or equal to one.
     * @exception {DeveloperError} options.slicePartitions must be greater than or equal to zero.
     * @exception {DeveloperError} options.subdivisions must be greater than or equal to zero.
     *
     * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Ellipsoid%20Outline.html|Cesium Sandcastle Ellipsoid Outline Demo}
     *
     * @example
     * var ellipsoid = new Cesium.EllipsoidOutlineGeometry({
     *   radii : new Cesium.Cartesian3(1000000.0, 500000.0, 500000.0),
     *   stackPartitions: 6,
     *   slicePartitions: 5
     * });
     * var geometry = Cesium.EllipsoidOutlineGeometry.createGeometry(ellipsoid);
     */
    function EllipsoidOutlineGeometry(options) {
        options = defaultValue(options, defaultValue.EMPTY_OBJECT);

        var radii = defaultValue(options.radii, defaultRadii);
        var stackPartitions = defaultValue(options.stackPartitions, 10);
        var slicePartitions = defaultValue(options.slicePartitions, 8);
        var subdivisions = defaultValue(options.subdivisions, 128);

        //>>includeStart('debug', pragmas.debug);
        if (stackPartitions < 1) {
            throw new DeveloperError('options.stackPartitions cannot be less than 1');
        }
        if (slicePartitions < 0) {
            throw new DeveloperError('options.slicePartitions cannot be less than 0');
        }
        if (subdivisions < 0) {
            throw new DeveloperError('options.subdivisions must be greater than or equal to zero.');
        }
        //>>includeEnd('debug');

        this._radii = Cartesian3.clone(radii);
        this._stackPartitions = stackPartitions;
        this._slicePartitions = slicePartitions;
        this._subdivisions = subdivisions;
        this._workerName = 'createEllipsoidOutlineGeometry';
    }

    /**
     * The number of elements used to pack the object into an array.
     * @type {Number}
     */
    EllipsoidOutlineGeometry.packedLength = Cartesian3.packedLength + 3;

    /**
     * Stores the provided instance into the provided array.
     *
     * @param {EllipsoidOutlineGeometry} value The value to pack.
     * @param {Number[]} array The array to pack into.
     * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
     */
    EllipsoidOutlineGeometry.pack = function(value, array, startingIndex) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(value)) {
            throw new DeveloperError('value is required');
        }
        if (!defined(array)) {
            throw new DeveloperError('array is required');
        }
        //>>includeEnd('debug');

        startingIndex = defaultValue(startingIndex, 0);

        Cartesian3.pack(value._radii, array, startingIndex);
        startingIndex += Cartesian3.packedLength;

        array[startingIndex++] = value._stackPartitions;
        array[startingIndex++] = value._slicePartitions;
        array[startingIndex]   = value._subdivisions;
    };

    var scratchRadii = new Cartesian3();
    var scratchOptions = {
        radii : scratchRadii,
        stackPartitions : undefined,
        slicePartitions : undefined,
        subdivisions : undefined
    };

    /**
     * Retrieves an instance from a packed array.
     *
     * @param {Number[]} array The packed array.
     * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
     * @param {EllipsoidOutlineGeometry} [result] The object into which to store the result.
     * @returns {EllipsoidOutlineGeometry} The modified result parameter or a new EllipsoidOutlineGeometry instance if one was not provided.
     */
    EllipsoidOutlineGeometry.unpack = function(array, startingIndex, result) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(array)) {
            throw new DeveloperError('array is required');
        }
        //>>includeEnd('debug');

        startingIndex = defaultValue(startingIndex, 0);

        var radii = Cartesian3.unpack(array, startingIndex, scratchRadii);
        startingIndex += Cartesian3.packedLength;

        var stackPartitions = array[startingIndex++];
        var slicePartitions = array[startingIndex++];
        var subdivisions = array[startingIndex++];

        if (!defined(result)) {
            scratchOptions.stackPartitions = stackPartitions;
            scratchOptions.slicePartitions = slicePartitions;
            scratchOptions.subdivisions = subdivisions;
            return new EllipsoidOutlineGeometry(scratchOptions);
        }

        result._radii = Cartesian3.clone(radii, result._radii);
        result._stackPartitions = stackPartitions;
        result._slicePartitions = slicePartitions;
        result._subdivisions = subdivisions;

        return result;
    };

    /**
     * Computes the geometric representation of an outline of an ellipsoid, including its vertices, indices, and a bounding sphere.
     *
     * @param {EllipsoidOutlineGeometry} ellipsoidGeometry A description of the ellipsoid outline.
     * @returns {Geometry} The computed vertices and indices.
     */
    EllipsoidOutlineGeometry.createGeometry = function(ellipsoidGeometry) {
        var radii = ellipsoidGeometry._radii;
        var ellipsoid = Ellipsoid.fromCartesian3(radii);
        var stackPartitions = ellipsoidGeometry._stackPartitions;
        var slicePartitions = ellipsoidGeometry._slicePartitions;
        var subdivisions = ellipsoidGeometry._subdivisions;

        var indicesSize = subdivisions * (stackPartitions + slicePartitions - 1);
        var positionSize = indicesSize - slicePartitions + 2;
        var positions = new Float64Array(positionSize * 3);
        var indices = IndexDatatype.createTypedArray(positionSize, indicesSize * 2);

        var i;
        var j;
        var theta;
        var phi;
        var cosPhi;
        var sinPhi;
        var index = 0;

        var cosTheta = new Array(subdivisions);
        var sinTheta = new Array(subdivisions);
        for (i = 0; i < subdivisions; i++) {
            theta = CesiumMath.TWO_PI * i / subdivisions;
            cosTheta[i] = cos(theta);
            sinTheta[i] = sin(theta);
        }

        for (i = 1; i < stackPartitions; i++) {
            phi = Math.PI * i / stackPartitions;
            cosPhi = cos(phi);
            sinPhi = sin(phi);

            for (j = 0; j < subdivisions; j++) {
                positions[index++] = radii.x * cosTheta[j] * sinPhi;
                positions[index++] = radii.y * sinTheta[j] * sinPhi;
                positions[index++] = radii.z * cosPhi;
            }
        }

        cosTheta.length = slicePartitions;
        sinTheta.length = slicePartitions;
        for (i = 0; i < slicePartitions; i++) {
            theta = CesiumMath.TWO_PI * i / slicePartitions;
            cosTheta[i] = cos(theta);
            sinTheta[i] = sin(theta);
        }

        positions[index++] = 0;
        positions[index++] = 0;
        positions[index++] = radii.z;

        for (i = 1; i < subdivisions; i++) {
            phi = Math.PI * i / subdivisions;
            cosPhi = cos(phi);
            sinPhi = sin(phi);

            for (j = 0; j < slicePartitions; j++) {
                positions[index++] = radii.x * cosTheta[j] * sinPhi;
                positions[index++] = radii.y * sinTheta[j] * sinPhi;
                positions[index++] = radii.z * cosPhi;
            }
        }

        positions[index++] = 0;
        positions[index++] = 0;
        positions[index++] = -radii.z;

        index = 0;
        for (i = 0; i < stackPartitions - 1; ++i) {
            var topRowOffset = (i * subdivisions);
            for (j = 0; j < subdivisions - 1; ++j) {
                indices[index++] = topRowOffset + j;
                indices[index++] = topRowOffset + j + 1;
            }

            indices[index++] = topRowOffset + subdivisions - 1;
            indices[index++] = topRowOffset;
        }

        var sliceOffset = subdivisions * (stackPartitions - 1);
        for (j = 1; j < slicePartitions + 1; ++j) {
            indices[index++] = sliceOffset;
            indices[index++] = sliceOffset + j;
        }

        for (i = 0; i < subdivisions - 2; ++i) {
            var topOffset = (i * slicePartitions) + 1 + sliceOffset;
            var bottomOffset = ((i + 1) * slicePartitions) + 1 + sliceOffset;

            for (j = 0; j < slicePartitions - 1; ++j) {
                indices[index++] = bottomOffset + j;
                indices[index++] = topOffset + j;
            }

            indices[index++] = bottomOffset + slicePartitions - 1;
            indices[index++] = topOffset + slicePartitions - 1;
        }

        var lastPosition = positions.length / 3 - 1;
        for (j = lastPosition - 1; j > lastPosition - slicePartitions - 1; --j) {
            indices[index++] = lastPosition;
            indices[index++] = j;
        }

        var attributes = new GeometryAttributes({
            position: new GeometryAttribute({
                componentDatatype : ComponentDatatype.DOUBLE,
                componentsPerAttribute : 3,
                values : positions
            })
        });

        return new Geometry({
            attributes : attributes,
            indices : indices,
            primitiveType : PrimitiveType.LINES,
            boundingSphere : BoundingSphere.fromEllipsoid(ellipsoid)
        });
    };

    return EllipsoidOutlineGeometry;
});
<|endoftext|>


<commit_before>$(document).ready(function() {
    'use strict';

    var MAX_NAME_LENGTH = 50;
    var BANNER_HEIGHT = 160;

    // Prep templates located in the HTML
    var name_tmpl = $('#name_tmpl').html();
    var progress_tmpl = $('#progress_tmpl').html();
    var progress_container_tmpl = $('#progress_container_tmpl').html();
    var progress_popover_tmpl = $('#progress_popover_tmpl').html();

    // Compile templates for speedup
    Mustache.parse(name_tmpl);
    Mustache.parse(progress_tmpl);
    Mustache.parse(progress_container_tmpl);
    Mustache.parse(progress_popover_tmpl);

    // Handle vertical resizing of the table
    function calcHeight() {
        return $(window).height() - BANNER_HEIGHT;
    }

    $(window).on('resize', function() {
        // The joy of fitting vertically!
        $('.dataTables_scrollBody').height(calcHeight()).css('max-height', 'inherit');
    });

    // Cluster status table.
    var cluster_table = $("#yarn_status").DataTable({
        ajax: YARNITOR_BASE_URL+"/api/cluster",
        paging: false,
        searching: false,
        ordering: false,
        dom: 't',
        columns: [
            {
                data: "totalNodes",
                title: "Nodes",
                render: function(data, type, row) {
                    return (row['activeNodes']) + ' / ' + data;
                }
            },
            {
                data: "totalVirtualCores",
                title: "VCPUs",
                render: function(data, type, row) {
                    return row['availableVirtualCores'] + ' / ' + data;
                }
            },
            {
               data: "totalMB",
               title: "RAM (GB)",
               render: function(data, type, row) {
                    return Math.round(row['availableMB'] / 1024) + ' / ' + Math.round(data / 1024);
               }
            }
        ]
    });

    // Main applications table
    var table = $('#yarn_applications').DataTable({
        ajax: YARNITOR_BASE_URL+"/api/applications",
        rowId: "id",
        scrollX: true,
        scrollY: calcHeight(),
        paging: false,
        colReorder: true,
        stateSave: true,
        order: [[4, 'desc']],
        buttons: [
            {
                extend: 'colvis',
                className: 'btn-sm'
            }
        ],
        language: {
            "search": "",
            "searchPlaceholder": "Filter records",
            "buttons": {
                "colvis": ''
            }
        },
        dom: ("<'row'<'col-xs-8'l><'col-xs-4 dataTables_controls'Bf>>" +
             "<'row'<'col-xs-12'tr>>" +
             "<'row'<'col-xs-6'i><'col-xs-6 dataTables_refreshed'>>"),
        columns: [
            {
                data: "name",
                title: "Name",
                render: function(data, type, row, meta) {
                    if(data.length > MAX_NAME_LENGTH) {
                        data = data.substr(0, MAX_NAME_LENGTH) + '...';
                    }
                    var html = Mustache.render(name_tmpl, {
                        name: data,
                        trackingUrl: row.trackingUrl,
                        id: row.id
                    });
                    return html;
                }
            },
            {data: "user", title: "User"},
            {data: "state", title: "State"},
            {
                title: "Progress",
                render: function(data, type, row, meta) {
                    // progress bars
                    var bar_htmls = row.progress.map(function(progress) {
                        var total = progress.completed + progress.running + progress.failed;
                        total = (progress.total > total) ? progress.total : total;
                        var args = {
                            completed: progress.completed,
                            completed_ratio: progress.completed / progress.total * 100,
                            running: progress.running,
                            running_ratio: progress.running / progress.total * 100,
                            failed: progress.failed,
                            failed_ratio: progress.failed / progress.total * 100,
                            total: progress.total
                        };

                        return Mustache.render(progress_tmpl, args);
                    });

                    return Mustache.render(progress_container_tmpl, {
                        progress_html: bar_htmls.join('\n'),
                        popover_html : Mustache.render(progress_popover_tmpl, row)
                    });
                }
            },
            {data: "allocatedVCores", title: "VCPUs"},
            {
                data: "vcoreSeconds",
                title: "VCPU-Hours",
                render: function(data, type, row, meta) {
                    return (row.vcoreSeconds / 3600).toFixed(2);
                }
            },
            {
                data: "allocatedMB",
                title: "RAM (GB)",
                render: function(data) {
                    return Math.round(data / 1024);
                }
            },
            {
                data: "memorySeconds",
                title: "RAM (GB)-Hours",
                render: function(data, type, row, meta) {
                    return (row.memorySeconds / 1024 / 3600).toFixed(2);
                }
            },
            {
              title: "RAM/VCPU Ratio",
              render: function(data, type, row, meta) {
                return (row.allocatedMB / row.allocatedVCores / 1024).toFixed(2);
              }
            },
            {"data": "applicationType", "title": "Job Type"},
            {"data": "queue", "title": "Queue"},
            {
                "data": "startedTime",
                "type": "date",
                "title": "Local Start Time",
                "render": function(data, type, row, meta) {
                    return (new Date(data)).toLocaleString();
                }
            },
            {
                "data": "startedTime",
                "sortable": false,
                "title": "Uptime",
                "render": function(data, type, row, meta) {
                    return moment.duration(moment.utc() - moment(data)).humanize();
                }
            },
            {"data": "id", "title": "Application ID", "visible": false},
        ]
    });

    var pageScrollPos = 0;

    table.on('search.dt', function() {
        history.replaceState(undefined, undefined, '#'+table.search());
    });

    table.on('draw.dt', function() {
        console.log('yarnitor:draw.dt');
        // Remove shown popovers
        $('.popover').remove();
        $('[data-toggle="popover"]').popover();
        // rescroll
        $('div.dataTables_scrollBody').scrollTop(pageScrollPos);
    });

    table.on('xhr.dt', function() {
        console.log('yarnitor:xhr.dt');
        // destroy the popovers before the draw phase kicks in.
        $('[data-toggle="popover"]').popover("destroy");
        pageScrollPos = $('div.dataTables_scrollBody').scrollTop();
    });

    var reloadDatetime = function() {
        $.get({
            url: YARNITOR_BASE_URL+"/api/status",
            dataType: 'json'
        }).done(function(data) {
            // Show datetime data was last refreshed from the YARN API
            // if that information is available, else leave the display alone
            if(data.refresh_datetime) {
                var d = (new Date(data.refresh_datetime)).toLocaleString();
                $('.dataTables_refreshed').text('Showing data from ' + d);
            }
        });
    }

    setInterval(function() {
        console.log('yarnitor:refresh');
        table.ajax.reload();
        cluster_table.ajax.reload();
        reloadDatetime();
    }, YARNITOR_REFRESH_INTERVAL_S * 1000);

    // Throw exceptions in the console, not in alert dialogs
    $.fn.dataTable.ext.errMode = 'throw';
    // Immediately try to fetch datetime of last data refresh
    reloadDatetime();
    // Set the initial filter text by pulling it from the URL hash
    table.search(window.location.hash.substr(1));

    console.log('yarnitor:dom-ready');
});
<commit_msg>Distinguish render for display from other uses<commit_after>$(document).ready(function() {
    'use strict';

    var MAX_NAME_LENGTH = 50;
    var BANNER_HEIGHT = 160;

    // Prep templates located in the HTML
    var name_tmpl = $('#name_tmpl').html();
    var progress_tmpl = $('#progress_tmpl').html();
    var progress_container_tmpl = $('#progress_container_tmpl').html();
    var progress_popover_tmpl = $('#progress_popover_tmpl').html();

    // Compile templates for speedup
    Mustache.parse(name_tmpl);
    Mustache.parse(progress_tmpl);
    Mustache.parse(progress_container_tmpl);
    Mustache.parse(progress_popover_tmpl);

    // Handle vertical resizing of the table
    function calcHeight() {
        return $(window).height() - BANNER_HEIGHT;
    }

    $(window).on('resize', function() {
        // The joy of fitting vertically!
        $('.dataTables_scrollBody').height(calcHeight()).css('max-height', 'inherit');
    });

    // Cluster status table.
    var cluster_table = $("#yarn_status").DataTable({
        ajax: YARNITOR_BASE_URL+"/api/cluster",
        paging: false,
        searching: false,
        ordering: false,
        dom: 't',
        columns: [
            {
                data: "totalNodes",
                title: "Nodes",
                render: function(data, type, row) {
                    return (row['activeNodes']) + ' / ' + data;
                }
            },
            {
                data: "totalVirtualCores",
                title: "VCPUs",
                render: function(data, type, row) {
                    return row['availableVirtualCores'] + ' / ' + data;
                }
            },
            {
               data: "totalMB",
               title: "RAM (GB)",
               render: function(data, type, row) {
                    return Math.round(row['availableMB'] / 1024) + ' / ' + Math.round(data / 1024);
               }
            }
        ]
    });

    // Main applications table
    var table = $('#yarn_applications').DataTable({
        ajax: YARNITOR_BASE_URL+"/api/applications",
        rowId: "id",
        scrollX: true,
        scrollY: calcHeight(),
        paging: false,
        colReorder: true,
        stateSave: true,
        order: [[4, 'desc']],
        buttons: [
            {
                extend: 'colvis',
                className: 'btn-sm'
            }
        ],
        language: {
            "search": "",
            "searchPlaceholder": "Filter records",
            "buttons": {
                "colvis": ''
            }
        },
        dom: ("<'row'<'col-xs-8'l><'col-xs-4 dataTables_controls'Bf>>" +
             "<'row'<'col-xs-12'tr>>" +
             "<'row'<'col-xs-6'i><'col-xs-6 dataTables_refreshed'>>"),
        columns: [
            {
                data: "name",
                title: "Name",
                render: function(data, type, row, meta) {
                    if(type === 'display') {
                        if(data.length > MAX_NAME_LENGTH) {
                            // Abbreviate the name for display, preserving a prefix and suffix
                            data = data.substr(0, MAX_NAME_LENGTH/2) + '...' + data.substr(-MAX_NAME_LENGTH/2);
                        }
                        var html = Mustache.render(name_tmpl, {
                            name: data,
                            trackingUrl: row.trackingUrl,
                            id: row.id
                        });
                        return html;
                    } else {
                        // Return the raw name for sorting, filtering, etc.
                        return data;
                    }
                }
            },
            {data: "user", title: "User"},
            {data: "state", title: "State"},
            {
                title: "Progress",
                sortable: false,
                searchable: false,
                render: function(data, type, row, meta) {
                    if(type === 'display') {
                        // progress bars
                        var bar_htmls = row.progress.map(function(progress) {
                            var total = progress.completed + progress.running + progress.failed;
                            total = (progress.total > total) ? progress.total : total;
                            var args = {
                                completed: progress.completed,
                                completed_ratio: progress.completed / progress.total * 100,
                                running: progress.running,
                                running_ratio: progress.running / progress.total * 100,
                                failed: progress.failed,
                                failed_ratio: progress.failed / progress.total * 100,
                                total: progress.total
                            };

                            return Mustache.render(progress_tmpl, args);
                        });

                        return Mustache.render(progress_container_tmpl, {
                            progress_html: bar_htmls.join('\n'),
                            popover_html : Mustache.render(progress_popover_tmpl, row)
                        });
                    } else {
                        // Return a string sentinel for type requests
                        return '';
                    }
                }
            },
            {data: "allocatedVCores", title: "VCPUs"},
            {
                data: "vcoreSeconds",
                title: "VCPU-Hours",
                render: function(data, type, row, meta) {
                    return (row.vcoreSeconds / 3600).toFixed(2);
                }
            },
            {
                data: "allocatedMB",
                title: "RAM (GB)",
                render: function(data) {
                    return Math.round(data / 1024);
                }
            },
            {
                data: "memorySeconds",
                title: "RAM (GB)-Hours",
                render: function(data, type, row, meta) {
                    return (row.memorySeconds / 1024 / 3600).toFixed(2);
                }
            },
            {
              title: "RAM/VCPU Ratio",
              render: function(data, type, row, meta) {
                return (row.allocatedMB / row.allocatedVCores / 1024).toFixed(2);
              }
            },
            {"data": "applicationType", "title": "Job Type"},
            {"data": "queue", "title": "Queue"},
            {
                "data": "startedTime",
                "type": "date",
                "title": "Local Start Time",
                "render": function(data, type, row, meta) {
                    return (new Date(data)).toLocaleString();
                }
            },
            {
                "data": "startedTime",
                "title": "Uptime",
                "render": function(data, type, row, meta) {
                    if(type === 'display' || type === 'filter') {
                        return moment.duration(moment.utc() - moment(data)).humanize();
                    } else {
                        return (new Date(data)).getTime();
                    }
                }
            },
            {"data": "id", "title": "Application ID", "visible": false},
        ]
    });

    var pageScrollPos = 0;

    table.on('search.dt', function() {
        history.replaceState(undefined, undefined, '#'+table.search());
    });

    table.on('draw.dt', function() {
        console.log('yarnitor:draw.dt');
        // Remove shown popovers
        $('.popover').remove();
        $('[data-toggle="popover"]').popover();
        // rescroll
        $('div.dataTables_scrollBody').scrollTop(pageScrollPos);
    });

    table.on('xhr.dt', function() {
        console.log('yarnitor:xhr.dt');
        // destroy the popovers before the draw phase kicks in.
        $('[data-toggle="popover"]').popover("destroy");
        pageScrollPos = $('div.dataTables_scrollBody').scrollTop();
    });

    var reloadDatetime = function() {
        $.get({
            url: YARNITOR_BASE_URL+"/api/status",
            dataType: 'json'
        }).done(function(data) {
            // Show datetime data was last refreshed from the YARN API
            // if that information is available, else leave the display alone
            if(data.refresh_datetime) {
                var d = (new Date(data.refresh_datetime)).toLocaleString();
                $('.dataTables_refreshed').text('Showing data from ' + d);
            }
        });
    }

    setInterval(function() {
        console.log('yarnitor:refresh');
        table.ajax.reload();
        cluster_table.ajax.reload();
        reloadDatetime();
    }, YARNITOR_REFRESH_INTERVAL_S * 1000);

    // Throw exceptions in the console, not in alert dialogs
    $.fn.dataTable.ext.errMode = 'throw';
    // Immediately try to fetch datetime of last data refresh
    reloadDatetime();
    // Set the initial filter text by pulling it from the URL hash
    table.search(window.location.hash.substr(1));

    console.log('yarnitor:dom-ready');
});
<|endoftext|>


<commit_before>/*
 ---

 name: WindowForm

 script: windowform.js

 description: Create a window from a form.

 copyright: (c) 2011 Contributors in (/AUTHORS.txt).

 license: MIT-style license in (/MIT-LICENSE.txt).

 note:
 This documentation is taken directly from the javascript source files. It is built using Natural Docs.

 requires:
 - Core/Element
 - Core/Class
 - Core/Options
 - Core/Events
 - MUI
 - MUI.Core

 provides: [MUI.WindowForm]

 ...
 */

MUI.WindowForm = new NamedClass('MUI.WindowForm', {

	Implements: [Events, Options],

	options: {
		id: null,
		title: 'New Window',
		loadMethod: 'html',
		content: '',
		contentURL: 'pages/lipsum.html',
		type: 'window',
		width: 300,
		height: 125,
		scrollbars: true,
		x: null,
		y: null
	},

	initialize: function(options){
		this.setOptions(options);
		this.options.id = 'win' + (++MUI.idCount);
		this.options.title = $('newWindowHeaderTitle').value;

		if ($('htmlLoadMethod').checked){
			this.options.loadMethod = 'html';
		}
		if ($('iframeLoadMethod').checked){
			this.options.loadMethod = 'iframe';
		}
		this.options.content = $('newWindowContent').value;

		// Remove eval(), javascript:, and script from User Provided Markup
		this.options.content = this.options.content.replace(/\<(.*)script(.*)\<\/(.*)script(.*)\>/g, "");
		this.options.content = this.options.content.replace(/[\"\'][\s]*javascript:(.*)[\"\']/g, "\"\"");
		this.options.content = this.options.content.replace(/eval\((.*)\)/g, "");

		if ($('newWindowContentURL').value){
			this.options.contentURL = $('newWindowContentURL').value;
		}

		if ($('newWindowModal').checked){
			this.options.type = 'modal';
		}

		this.options.width = $('newWindowWidth').value.toInt();
		this.options.height = $('newWindowHeight').value.toInt();
		this.options.x = $('newWindowX').value.toInt();
		this.options.y = $('newWindowY').value.toInt();
		new MUI.Window(this.options);
	}

});
<commit_msg>just keep each section using their own .id prefixes: happened everywhere except this one which used 'win' like window.js; not really a problem, just me being pedantic about it.<commit_after>/*
 ---

 name: WindowForm

 script: windowform.js

 description: Create a window from a form.

 copyright: (c) 2011 Contributors in (/AUTHORS.txt).

 license: MIT-style license in (/MIT-LICENSE.txt).

 note:
 This documentation is taken directly from the javascript source files. It is built using Natural Docs.

 requires:
 - Core/Element
 - Core/Class
 - Core/Options
 - Core/Events
 - MUI
 - MUI.Core

 provides: [MUI.WindowForm]

 ...
 */

MUI.WindowForm = new NamedClass('MUI.WindowForm', {

	Implements: [Events, Options],

	options: {
		id: null,
		title: 'New Window',
		loadMethod: 'html',
		content: '',
		contentURL: 'pages/lipsum.html',
		type: 'window',
		width: 300,
		height: 125,
		scrollbars: true,
		x: null,
		y: null
	},

	initialize: function(options){
		this.setOptions(options);
		this.options.id = 'windowform' + (++MUI.idCount);
		this.options.title = $('newWindowHeaderTitle').value;

		if ($('htmlLoadMethod').checked){
			this.options.loadMethod = 'html';
		}
		if ($('iframeLoadMethod').checked){
			this.options.loadMethod = 'iframe';
		}
		this.options.content = $('newWindowContent').value;

		// Remove eval(), javascript:, and script from User Provided Markup
		this.options.content = this.options.content.replace(/\<(.*)script(.*)\<\/(.*)script(.*)\>/g, "");
		this.options.content = this.options.content.replace(/[\"\'][\s]*javascript:(.*)[\"\']/g, "\"\"");
		this.options.content = this.options.content.replace(/eval\((.*)\)/g, "");

		if ($('newWindowContentURL').value){
			this.options.contentURL = $('newWindowContentURL').value;
		}

		if ($('newWindowModal').checked){
			this.options.type = 'modal';
		}

		this.options.width = $('newWindowWidth').value.toInt();
		this.options.height = $('newWindowHeight').value.toInt();
		this.options.x = $('newWindowX').value.toInt();
		this.options.y = $('newWindowY').value.toInt();
		new MUI.Window(this.options);
	}

});
<|endoftext|>