<commit_before>	function fight() {}

fight.prototype = {
  create: function() {
  	console.log(game.state.current)

  	// Enemy Bullets
    enemyBullets = game.add.group();
    enemyBullets.enableBody = true;
    enemyBullets.physicsBodyType = Phaser.Physics.ARCADE;
    enemyBullets.createMultiple(30, 'enemyBullet');
    enemyBullets.setAll('anchor.x', 0.5);
    enemyBullets.setAll('anchor.y', 1);
    enemyBullets.setAll('outOfBoundsKill', true);
    enemyBullets.setAll('checkWorldBounds', true);

  	// Logic to only scatter aliens once, called in fight - update loop
  	gameUI.alienScatterEnabled = true

	  game.physics.startSystem(Phaser.Physics.ARCADE)

	  // scrolling tile sprite
	  starfieldBackground.create(game)

	  // Ceiling visible line and collision detector
	  gameUI.gameAreaCeilingLine = new Phaser.Rectangle(0,200, 1200, 1)
	  gameUI.gameAreaCeiling = game.add.sprite(0,200,null)
	  game.physics.enable(gameUI.gameAreaCeiling, Phaser.Physics.ARCADE)
	  gameUI.gameAreaCeiling.body.setSize(1200, 1, 0, 0)
	  gameUI.gameAreaCeiling.body.immovable = true

	  // rain
	  rain.create(game)

	  // playerBullets
	  playerBullets = gameState.groups.playerBullets = game.add.group()
	  playerBullets.enableBody = true
	  playerBullets.physicsBodyType = Phaser.Physics.ARCADE
	   // All 100 of them
	  playerBullets.createMultiple(250, 'bullet')

	  playerBullets.setAll('anchor.x', 0.5)
	  playerBullets.setAll('anchor.y', 0.5)
	  playerBullets.setAll('damage', 5)

	  bossAlienBullets = gameState.groups.bossAlienBullets = game.add.group()
	  bossAlienBullets.enableBody = true
	  bossAlienBullets.physicsBodyType = Phaser.Physics.ARCADE
	   // All 100 of them
	  bossAlienBullets.createMultiple(250, 'bullet')

	  bossAlienBullets.setAll('anchor.x', 0.5)
	  bossAlienBullets.setAll('anchor.y', 0.5)
	  bossAlienBullets.setAll('damage', 50)

	  // create player object
	  var player = gameState.player = game.add.sprite(32, game.world.height - 150, 'dude')
	  game.physics.arcade.enable(player)
	  player.body.bounce.y = 0.2
	  player.body.collideWorldBounds = true
	  player.health = 100
	  gameUI.upgradeGun(gameState.questionsCorrect)

	  // create explosions
	  var explosions = gameState.groups.explosions = game.add.group()
    explosions.createMultiple(21, 'explosion')
    explosions.forEach(setUpExplosion)

    function setUpExplosion(explode){
    	explode.animations.add('explosion')
    }

	  // create regular aliens
	  aliens = gameState.groups.aliens = game.add.group()
	  aliens.enableBody = true
	  aliens.physicsBodyType = Phaser.Physics.ARCADE

	  // create boss alien
	  bossAlien = gameState.bossAlien = game.add.sprite(1500, 350, 'diamond')
	  game.physics.arcade.enable(bossAlien)
	  bossAlien.enableBody = true
	  bossAlien.physicsBodyType = Phaser.Physics.ARCADE
	  bossAlien.body.bounce.x = .9
	  bossAlien.body.bounce.y = .9
	  var scale = gameUI.alienBossScale(gameState.questionsCorrect)
	  bossAlien.scale.setTo(scale,scale)
	  bossAlien.anchor.x = 0.5
	  bossAlien.anchor.y = 0.5

	  // create keyboard listeners
	  gameState.cursors = game.input.keyboard.createCursorKeys()

	  // create text fields ------------------------------------------------
	  gameUI.scoreObject = game.add.text(
	    32, 32, // x coord, y coord
	    'Score: ' + gameUI.score, // text field
	    {fontSize: '32px', fill: '#ffffff'} // text styling
	    )

	  gameUI.spawnAliens()
  },
  update: function() {
  	 	var player = gameState.player
		  var cursors = gameState.cursors
		  var shootThePlayerGun = false
		  var shootTheBossAlienGun = false

		  // Player cannot pass through the game boundaries
		  game.physics.arcade.collide(player, gameUI.gameAreaCeiling)
		  // Player cannot pass through the game boundaries
		  game.physics.arcade.collide(gameState.bossAlien, gameUI.gameAreaCeiling)
		  // aliens cannot pass through game boundaries
		  game.physics.arcade.collide(gameState.groups.aliens, gameUI.gameAreaCeiling)
		  // boss alien cannot pass through game boundaries
		  game.physics.arcade.collide(gameState.bossAlien, gameUI.gameAreaCeiling)
		  // aliens bounce off of each other
		  game.physics.arcade.collide(gameState.groups.aliens, gameState.groups.aliens)
		  // aliens bounce off of boss alien
		  game.physics.arcade.collide(gameState.groups.aliens, gameState.bossAlien)

		  // Bullets cause damage to aliens and then disappear
		  game.physics.arcade.overlap(gameState.groups.playerBullets, gameState.groups.aliens, gameUI.hitAlien , null, this)
		  // Bullets cause the boss alien to shrink
		  game.physics.arcade.overlap(gameState.groups.playerBullets, gameState.bossAlien, gameUI.shrinkBoss , null, this)
		  // Aliens damage the player when they touch
		  game.physics.arcade.overlap(player, gameState.groups.aliens, gameUI.hitPlayer, null, this)
		  // Boss alien bullets damage player
		  game.physics.arcade.overlap(player, gameState.groups.bossAlienBullets, gameUI.hitPlayer, null, this)

		  // set scroll speed of background
		  // starfield.tilePosition.x -= 1
		  starfieldBackground.update()

		    if (cursors.left.isDown) {
		      // player UP
		      player.body.velocity.y = -250;
		      // player.animations.play('up')
		    } else if (cursors.right.isDown){
		      // player DOWN
		      player.body.velocity.y = 250;
		      // player.animations.play('down')
		    } else {
		      // player stand still
		      player.animations.stop()
		      player.frame = 4
		      player.body.velocity.y = 0
		    }

		  // fire!
		  gameUI.firePlayerGunCounter += 1
		  if (gameUI.firePlayerGunCounter >= gameUI.firePlayerGunRate){
		    shootThePlayerGun = true
		    gameUI.firePlayerGunCounter = 0
		  }
		  if (shootThePlayerGun) {
		    gameUI.firePlayerBullet()
		  }

		  gameState.bossAlien.rotation = game.physics.arcade.angleBetween(gameState.bossAlien, player)
		  console.log("rotation" + gameState.bossAlien.rotation)
		  console.log("angle" + gameState.bossAlien.angle)
		  gameUI.fireBossAlienGunCounter += 1
		  if (gameUI.fireBossAlienGunCounter >= gameUI.fireBossAlienGunRate){
		    shootTheBossAlienGun = true
		    gameUI.fireBossAlienGunCounter = 0
		  }

		  if (shootTheBossAlienGun && gameState.bossAlien.alive) {
		    gameUI.fireBossAlienBullet()
		  }

		  if (gameUI.aliensDead()) {
		    gameState.currentLevel++
		    gameState.firstTimeOnLevel = true
		    game.state.start('level_intro')
		  }

		  if (gameUI.playerDead(gameState.player)){
		  	gameState.lifes -= 1
		  	if (gameState.lifes <= 0){
		  		console.log('game over')
		  		// gameState.firstTimeOnLevel = false
		  		// game.state.start('game_over')
		  	} else {
		  		gameState.firstTimeOnLevel = false
		    	game.state.start('level_intro')
		  	}
		  }

		  if (gameState.groups.aliens.x < 850){
		    if (gameUI.alienScatterEnabled) {
		    	gameUI.scatterAliens()
		    	gameUI.sendBossAlien()
		    }
		  }

		  if (gameState.bossAlien.x < 800 ){
		  	gameUI.bossInGameArea = true
		  	gameState.bossAlien.body.collideWorldBounds = true
		  	gameState.bossAlien.body.velocity.x = 30
		  	gameState.bossAlien.body.velocity.y = gameUI.getRandomInt(0, 30)
		  }

		  gameState.groups.aliens.forEach(function(alien){
		  	if (alien.body.x === 0) {
		  		alien.body.velocity.x = 50}
		  })

		  gameState.groups.aliens.forEach(function(alien){
		  	if (alien.body.x  < 100.5 & alien.body.x  > 99.5  ) {
		  		alien.body.velocity.x = 0}
		  })

		  gameState.groups.aliens.forEach(function(alien){
		  	if (alien.body.x <101 && alien.body.x >99 ) gameUI.kamikazeCounter++
		  	// if (alien.body.x <= 10  &&  alien.body.velocity.x > 0) alien.velocity.x = 200
		  })

		  if (gameUI.kamikazeCounter > 1) {
		  	gameState.groups.aliens.forEach(function(alien){
		  		if (alien.body.x <101 && alien.body.x >99)  {
		  			alien.body.velocity.x = -300
		  			gameUI.kamikazeCounter = 0
		  		}
		  	})

		  	console.log("kamikaze")
		  }
		  gameUI.kamikazeCounter = 0

  },
  render: function() {
    game.debug.geom(gameUI.gameAreaCeilingLine,'#FFFFFF')
  },
}
<commit_msg>remove logs<commit_after>	function fight() {}

fight.prototype = {
  create: function() {
  	console.log(game.state.current)

  	// Enemy Bullets
    enemyBullets = game.add.group();
    enemyBullets.enableBody = true;
    enemyBullets.physicsBodyType = Phaser.Physics.ARCADE;
    enemyBullets.createMultiple(30, 'enemyBullet');
    enemyBullets.setAll('anchor.x', 0.5);
    enemyBullets.setAll('anchor.y', 1);
    enemyBullets.setAll('outOfBoundsKill', true);
    enemyBullets.setAll('checkWorldBounds', true);

  	// Logic to only scatter aliens once, called in fight - update loop
  	gameUI.alienScatterEnabled = true

	  game.physics.startSystem(Phaser.Physics.ARCADE)

	  // scrolling tile sprite
	  starfieldBackground.create(game)

	  // Ceiling visible line and collision detector
	  gameUI.gameAreaCeilingLine = new Phaser.Rectangle(0,200, 1200, 1)
	  gameUI.gameAreaCeiling = game.add.sprite(0,200,null)
	  game.physics.enable(gameUI.gameAreaCeiling, Phaser.Physics.ARCADE)
	  gameUI.gameAreaCeiling.body.setSize(1200, 1, 0, 0)
	  gameUI.gameAreaCeiling.body.immovable = true

	  // rain
	  rain.create(game)

	  // playerBullets
	  playerBullets = gameState.groups.playerBullets = game.add.group()
	  playerBullets.enableBody = true
	  playerBullets.physicsBodyType = Phaser.Physics.ARCADE
	   // All 100 of them
	  playerBullets.createMultiple(250, 'bullet')

	  playerBullets.setAll('anchor.x', 0.5)
	  playerBullets.setAll('anchor.y', 0.5)
	  playerBullets.setAll('damage', 5)

	  bossAlienBullets = gameState.groups.bossAlienBullets = game.add.group()
	  bossAlienBullets.enableBody = true
	  bossAlienBullets.physicsBodyType = Phaser.Physics.ARCADE
	   // All 100 of them
	  bossAlienBullets.createMultiple(250, 'bullet')

	  bossAlienBullets.setAll('anchor.x', 0.5)
	  bossAlienBullets.setAll('anchor.y', 0.5)
	  bossAlienBullets.setAll('damage', 50)

	  // create player object
	  var player = gameState.player = game.add.sprite(32, game.world.height - 150, 'dude')
	  game.physics.arcade.enable(player)
	  player.body.bounce.y = 0.2
	  player.body.collideWorldBounds = true
	  player.health = 100
	  gameUI.upgradeGun(gameState.questionsCorrect)

	  // create explosions
	  var explosions = gameState.groups.explosions = game.add.group()
    explosions.createMultiple(21, 'explosion')
    explosions.forEach(setUpExplosion)

    function setUpExplosion(explode){
    	explode.animations.add('explosion')
    }

	  // create regular aliens
	  aliens = gameState.groups.aliens = game.add.group()
	  aliens.enableBody = true
	  aliens.physicsBodyType = Phaser.Physics.ARCADE

	  // create boss alien
	  bossAlien = gameState.bossAlien = game.add.sprite(1500, 350, 'diamond')
	  game.physics.arcade.enable(bossAlien)
	  bossAlien.enableBody = true
	  bossAlien.physicsBodyType = Phaser.Physics.ARCADE
	  bossAlien.body.bounce.x = .9
	  bossAlien.body.bounce.y = .9
	  var scale = gameUI.alienBossScale(gameState.questionsCorrect)
	  bossAlien.scale.setTo(scale,scale)
	  bossAlien.anchor.x = 0.5
	  bossAlien.anchor.y = 0.5

	  // create keyboard listeners
	  gameState.cursors = game.input.keyboard.createCursorKeys()

	  // create text fields ------------------------------------------------
	  gameUI.scoreObject = game.add.text(
	    32, 32, // x coord, y coord
	    'Score: ' + gameUI.score, // text field
	    {fontSize: '32px', fill: '#ffffff'} // text styling
	    )

	  gameUI.spawnAliens()
  },
  update: function() {
  	 	var player = gameState.player
		  var cursors = gameState.cursors
		  var shootThePlayerGun = false
		  var shootTheBossAlienGun = false

		  // Player cannot pass through the game boundaries
		  game.physics.arcade.collide(player, gameUI.gameAreaCeiling)
		  // Player cannot pass through the game boundaries
		  game.physics.arcade.collide(gameState.bossAlien, gameUI.gameAreaCeiling)
		  // aliens cannot pass through game boundaries
		  game.physics.arcade.collide(gameState.groups.aliens, gameUI.gameAreaCeiling)
		  // boss alien cannot pass through game boundaries
		  game.physics.arcade.collide(gameState.bossAlien, gameUI.gameAreaCeiling)
		  // aliens bounce off of each other
		  game.physics.arcade.collide(gameState.groups.aliens, gameState.groups.aliens)
		  // aliens bounce off of boss alien
		  game.physics.arcade.collide(gameState.groups.aliens, gameState.bossAlien)

		  // Bullets cause damage to aliens and then disappear
		  game.physics.arcade.overlap(gameState.groups.playerBullets, gameState.groups.aliens, gameUI.hitAlien , null, this)
		  // Bullets cause the boss alien to shrink
		  game.physics.arcade.overlap(gameState.groups.playerBullets, gameState.bossAlien, gameUI.shrinkBoss , null, this)
		  // Aliens damage the player when they touch
		  game.physics.arcade.overlap(player, gameState.groups.aliens, gameUI.hitPlayer, null, this)
		  // Boss alien bullets damage player
		  game.physics.arcade.overlap(player, gameState.groups.bossAlienBullets, gameUI.hitPlayer, null, this)

		  // set scroll speed of background
		  // starfield.tilePosition.x -= 1
		  starfieldBackground.update()

		    if (cursors.left.isDown) {
		      // player UP
		      player.body.velocity.y = -250;
		      // player.animations.play('up')
		    } else if (cursors.right.isDown){
		      // player DOWN
		      player.body.velocity.y = 250;
		      // player.animations.play('down')
		    } else {
		      // player stand still
		      player.animations.stop()
		      player.frame = 4
		      player.body.velocity.y = 0
		    }

		  // fire!
		  gameUI.firePlayerGunCounter += 1
		  if (gameUI.firePlayerGunCounter >= gameUI.firePlayerGunRate){
		    shootThePlayerGun = true
		    gameUI.firePlayerGunCounter = 0
		  }
		  if (shootThePlayerGun) {
		    gameUI.firePlayerBullet()
		  }

		  gameUI.fireBossAlienGunCounter += 1
		  if (gameUI.fireBossAlienGunCounter >= gameUI.fireBossAlienGunRate){
		    shootTheBossAlienGun = true
		    gameUI.fireBossAlienGunCounter = 0
		  }

		  if (shootTheBossAlienGun && gameState.bossAlien.alive) {
		    gameUI.fireBossAlienBullet()
		  }

		  if (gameUI.aliensDead()) {
		    gameState.currentLevel++
		    gameState.firstTimeOnLevel = true
		    game.state.start('level_intro')
		  }

		  if (gameUI.playerDead(gameState.player)){
		  	gameState.lifes -= 1
		  	if (gameState.lifes <= 0){
		  		console.log('game over')
		  		// gameState.firstTimeOnLevel = false
		  		// game.state.start('game_over')
		  	} else {
		  		gameState.firstTimeOnLevel = false
		    	game.state.start('level_intro')
		  	}
		  }

		  if (gameState.groups.aliens.x < 850){
		    if (gameUI.alienScatterEnabled) {
		    	gameUI.scatterAliens()
		    	gameUI.sendBossAlien()
		    }
		  }

		  if (gameState.bossAlien.x < 800 ){
		  	gameUI.bossInGameArea = true
		  	gameState.bossAlien.body.collideWorldBounds = true
		  	gameState.bossAlien.body.velocity.x = 30
		  	gameState.bossAlien.body.velocity.y = gameUI.getRandomInt(0, 30)
		  }

		  gameState.groups.aliens.forEach(function(alien){
		  	if (alien.body.x === 0) {
		  		alien.body.velocity.x = 50}
		  })

		  gameState.groups.aliens.forEach(function(alien){
		  	if (alien.body.x  < 100.5 & alien.body.x  > 99.5  ) {
		  		alien.body.velocity.x = 0}
		  })

		  gameState.groups.aliens.forEach(function(alien){
		  	if (alien.body.x <101 && alien.body.x >99 ) gameUI.kamikazeCounter++
		  	// if (alien.body.x <= 10  &&  alien.body.velocity.x > 0) alien.velocity.x = 200
		  })

		  if (gameUI.kamikazeCounter > 1) {
		  	gameState.groups.aliens.forEach(function(alien){
		  		if (alien.body.x <101 && alien.body.x >99)  {
		  			alien.body.velocity.x = -300
		  			gameUI.kamikazeCounter = 0
		  		}
		  	})

		  	console.log("kamikaze")
		  }
		  gameUI.kamikazeCounter = 0

  },
  render: function() {
    game.debug.geom(gameUI.gameAreaCeilingLine,'#FFFFFF')
  },
}
<|endoftext|>


<commit_before>/*
 TaskOnFly allows you easy manage your tasks and task lists on the fly from your mobile or desktop device.
 Copyright (C) 2014-2015  Valerii Zinchenko

 This file is part of TaskOnFly.

 TaskOnFly is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 TaskOnFly is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with TaskOnFly.  If not, see <http://www.gnu.org/licenses/>.

 All source files are available at: http://github.com/valerii-zinchenko/TaskOnFly
*/

/**
 * @file #Router - simple hash router.
 *
 * @see HashRouter
 *
 * @author Valerii Zinchenko
 *
 * @version 1.0.0
 */

'use strict';

/**
 * #Router
 * This is simple hash router. He behaves as singleton.
 * Route can be defined by using named parts like ":name", or by using RegExp with captured groups like "(\\w+)". Remember to allways escape "\" character and use round braces to capture variable parts of route.
 * Please note, that appropriate methods will be executed only on first matched route. So plan your routes by importance in descending order.
 *
 * @example {"user/:id": ["load", "display"]}
 * @example {"user/(\\w+)": ["load", "display"], "(.*)": "404"}
 *
 * @throws {Error} Type of routingMap input argument expected to be an Object
 * @throws {Error} Type of context input argument expected to be an Object
 *
 * @constructor
 * @param {Object} routingMap - Map of routes and methods name
 * @param {Object} context - Context object wich has methods used in routingMap
 * @param {String} [fallbackRoute] - Fallback route. It will be used for cases when the visiting history is empty and application tries to go back
 */
var HashRouter = new SingletonClass(/** @lends HashRouter# */{
	/**
	 * RegExp to match the hash from the URL.
	 *
	 * @type {RegExp}
	 */
	hashRegExp: /(?:(\#.*)(?=\?))|(\#.*)/,

	/**
	 * RegExp to match the query from the URL.
	 *
	 * @type {RegExp}
	 */
	queryRegExp: /(?:(\?.*)(?=\#))|(\?.*)/,

	/**
	 * Map of converted routes in RegExp and array of method names.
	 * @example {/^#user/([\w\-\+\.]+)$/: ['load', 'display']}
	 *
	 * @type {Object}
	 */
	_routingMap: {},

	/**
	 * Context object with methods.
	 *
	 * @type {Object}
	 */
	_context: null,

	/**
	 * Fallback route. Is used when visiting history doesn't have any items.
	 *
	 * @type {String}
	 */
	_fallbackRoute: '',

	/**
	 * Array of visiting routes.
	 *
	 * @type {Array}
	 */
	_history: [],

	// constructor
	initialize: function(routingMap, context, fallbackRoute) {
		if (!utils.isObject(routingMap)) {
			throw new Error('Type of routingMap input argument expected to be an Object');
		}
		if (!utils.isObject(context)) {
			throw new Error('Type of context input argument expected to be an Object');
		}

		this._context = context;
		this._fallbackRoute = fallbackRoute;

		if (!this._context.prefix) {
			this._context.prefix = '';
		}

		var methods;
		for (var route in routingMap) {
			methods = routingMap[route];
			if (_.isString(methods)) {
				methods = [methods];
			}

			this._routingMap[route] = {
				regExp: new RegExp(this._preprocessRouteName(route, this._context.prefix)),
				methods: methods
			};
		}
	},

	/**
	 * Start the router.
	 *
	 * @param {String} [route] - Start point for router.
	 */
	start: function(route) {
		var _this = this;
		window.onhashchange = function(ev) {
			_this._hashChange(_this._getHash(ev.newURL), _this._getQuery(ev.newURL));
		};

		if (route) {
			this._hashChange(this._getHash(route), this._getQuery(route));
		}
	},

	/**
	 * Route to the new path.
	 *
	 * @param {String} route - New route.
	 * @param {String} [queries] - Optional parameters.
	 */
	routeTo: function(route, queries) {
		if (utils.isObject(queries)) {
			route += this.object2Query(queries);
		}

		location.hash = route;
	},

	/**
	 * Go back;
	 */
	back: function() {
		this._history.pop();

		if (this._history.length === 0 && this._fallbackRoute) {
			this.routeTo(this._context.prefix + this._fallbackRoute);

			return;
		}

		window.history.back();
	},

	/**
	 * Execute approptiate method(s) by changing hash to the new route.
	 *
	 * @param {String} hash - New route (should begin with '#').
	 * @param {String | Object} [queries] - Optional parameters (should begin with '?').
	 */
	_hashChange: function(route, queries) {
		var args;
		var methods;

		// Detect if user moves backward by using browser back button.
		if (this._history[this._history.length-2] === route) {
			this._history.pop();
		} else {
			this._history.push(route);
		}

		var map;
		for (var routeMap in this._routingMap) {
			map = this._routingMap[routeMap];

			if (map.regExp.test(route)) {
				args = map.regExp.exec(route);
				methods = map.methods;

				break;
			}
		}

		if (!methods || methods.length === 0) {
			return;
		}

		args = args.slice(1);
		args.push(this.query2Object(queries));
		_.forEach(methods, function(methodName) {
			var method = this[methodName];

			if (method) {
				method.apply(this, args);
			}
		}, this._context);
	},

	/**
	 * Convert query string into object.
	 * For example "?key1=value1&key2=value2" will be converted to {"key1": "value1", "key2": "value2"}
	 *
	 * @param {String} query - Query string.
	 * @return {Object}
	 */
	query2Object: function(query) {
		if (!query || query[0] !== '?' || !query[1]) {
			return {};
		}

		query = '{"' + query;
		query = query.replace('?', '');
		query = query.replace(/=/g, '":"');
		query = query.replace(/&/g, '","');
		query += '"}';

		return JSON.parse(query);
	},

	/**
	 * Convert object into query string .
	 * For example {"key1": "value1", "key2": "value2"} will be converted to "?key1=value1&key2=value2"
	 *
	 * @param {String} obj - Object that will be converted into query string.
	 * @return {Object}
	 */
	object2Query: function(obj) {
		var queries = [];
		_.forEach(obj, function(value, key) {
			if (value) {
				queries.push(key + '=' + value);
			}
		});

		return queries.length === 0 ? '' : '?' + queries.join('&');
	},

	/**
	 * Convert human readable route like "path/:part" into RegExp undestandable part "path/(\w+)"
	 *
	 * @param {String} route - Route, that should be converted
	 */
	_preprocessRouteName: function(route, prefix) {
		if (prefix) {
			prefix = '(?:' + prefix + ')?';
		} else {
			prefix = '';
		}

		route = route.replace(/\:[\w\-\.]+/g, '([\\w\\-\\.]+\/?)');

		return '^#' + prefix + route + '/?$';
	},

	/**
	 * Get hash part of the URL.
	 *
	 * @param {String} url - URL.
	 * @return {String}
	 */
	_getHash: function(url) {
		var match = this.hashRegExp.exec(url) || [];

		return match[1] || match[2] || '#';
	},

	/**
	 * Get query part of the URL.
	 *
	 * @param {String} url - URL.
	 * @return {String|undefined}
	 */
	_getQuery: function(url) {
		var match = this.queryRegExp.exec(url) || [];

		return match[1] || match[2];
	}
});
<commit_msg>extract hard and soft queries from URL in HashRouter<commit_after>/*
 TaskOnFly allows you easy manage your tasks and task lists on the fly from your mobile or desktop device.
 Copyright (C) 2014-2015  Valerii Zinchenko

 This file is part of TaskOnFly.

 TaskOnFly is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 TaskOnFly is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with TaskOnFly.  If not, see <http://www.gnu.org/licenses/>.

 All source files are available at: http://github.com/valerii-zinchenko/TaskOnFly
*/

/**
 * @file #Router - simple hash router.
 *
 * @see HashRouter
 *
 * @author Valerii Zinchenko
 *
 * @version 1.0.0
 */

'use strict';

/**
 * #Router
 * This is simple hash router. He behaves as singleton.
 * Route can be defined by using named parts like ":name", or by using RegExp with captured groups like "(\\w+)". Remember to allways escape "\" character and use round braces to capture variable parts of route.
 * Please note, that appropriate methods will be executed only on first matched route. So plan your routes by importance in descending order.
 *
 * @example {"user/:id": ["load", "display"]}
 * @example {"user/(\\w+)": ["load", "display"], "(.*)": "404"}
 *
 * @throws {Error} Type of routingMap input argument expected to be an Object
 * @throws {Error} Type of context input argument expected to be an Object
 *
 * @constructor
 * @param {Object} routingMap - Map of routes and methods name
 * @param {Object} context - Context object wich has methods used in routingMap
 * @param {String} [fallbackRoute] - Fallback route. It will be used for cases when the visiting history is empty and application tries to go back
 */
var HashRouter = new SingletonClass(/** @lends HashRouter# */{
	/**
	 * RegExp to match the hash from the URL.
	 *
	 * @type {RegExp}
	 */
	hashRegExp: /(?:(\#.*)(?=\?))|(\#.*)/,

	/**
	 * RegExp to match the hard (URL search query) and soft (query after fragment) query from the URL.
	 *
	 * @type {RegExp}
	 */
	queryRegExp: /(\?.*)(?=\#)(?:\#.*(\?.*))?|(\?.*)+?/,

	/**
	 * Map of converted routes in RegExp and array of method names.
	 * @example {/^#user/([\w\-\+\.]+)$/: ['load', 'display']}
	 *
	 * @type {Object}
	 */
	_routingMap: {},

	/**
	 * Context object with methods.
	 *
	 * @type {Object}
	 */
	_context: null,

	/**
	 * Fallback route. Is used when visiting history doesn't have any items.
	 *
	 * @type {String}
	 */
	_fallbackRoute: '',

	/**
	 * Array of visiting routes.
	 *
	 * @type {Array}
	 */
	_history: [],

	// constructor
	initialize: function(routingMap, context, fallbackRoute) {
		if (!utils.isObject(routingMap)) {
			throw new Error('Type of routingMap input argument expected to be an Object');
		}
		if (!utils.isObject(context)) {
			throw new Error('Type of context input argument expected to be an Object');
		}

		this._context = context;
		this._fallbackRoute = fallbackRoute;

		if (!this._context.prefix) {
			this._context.prefix = '';
		}

		var methods;
		for (var route in routingMap) {
			methods = routingMap[route];
			if (_.isString(methods)) {
				methods = [methods];
			}

			this._routingMap[route] = {
				regExp: new RegExp(this._preprocessRouteName(route, this._context.prefix)),
				methods: methods
			};
		}
	},

	/**
	 * Start the router.
	 *
	 * @param {String} [route] - Start point for router.
	 */
	start: function(route) {
		var _this = this;
		window.onhashchange = function(ev) {
			_this._hashChange(_this._getHash(ev.newURL), _this._getQuery(ev.newURL));
		};

		if (route) {
			this._hashChange(this._getHash(route), this._getQuery(route));
		}
	},

	/**
	 * Route to the new path.
	 *
	 * @param {String} route - New route.
	 * @param {String} [queries] - Optional parameters.
	 */
	routeTo: function(route, queries) {
		if (utils.isObject(queries)) {
			route += this.object2Query(queries);
		}

		location.hash = route;
	},

	/**
	 * Go back;
	 */
	back: function() {
		this._history.pop();

		if (this._history.length === 0 && this._fallbackRoute) {
			this.routeTo(this._context.prefix + this._fallbackRoute);

			return;
		}

		window.history.back();
	},

	/**
	 * Execute approptiate method(s) by changing hash to the new route.
	 *
	 * @param {String} hash - New route (should begin with '#').
	 * @param {String | Object} [queries] - Optional parameters (should begin with '?').
	 */
	_hashChange: function(route, queries) {
		var args;
		var methods;

		// Detect if user moves backward by using browser back button.
		if (this._history[this._history.length-2] === route) {
			this._history.pop();
		} else {
			this._history.push(route);
		}

		var map;
		for (var routeMap in this._routingMap) {
			map = this._routingMap[routeMap];

			if (map.regExp.test(route)) {
				args = map.regExp.exec(route);
				methods = map.methods;

				break;
			}
		}

		if (!methods || methods.length === 0) {
			return;
		}

		args = args.slice(1);
		args.push(this.query2Object(queries));
		_.forEach(methods, function(methodName) {
			var method = this[methodName];

			if (method) {
				method.apply(this, args);
			}
		}, this._context);
	},

	/**
	 * Convert query string into object.
	 * For example "?key1=value1&key2=value2" will be converted to {"key1": "value1", "key2": "value2"}
	 *
	 * @param {String} query - Query string.
	 * @return {Object}
	 */
	query2Object: function(query) {
		if (!query || query[0] !== '?' || !query[1]) {
			return {};
		}

		query = '{"' + query;
		query = query.replace('?', '');
		query = query.replace(/=/g, '":"');
		query = query.replace(/&/g, '","');
		query += '"}';

		return JSON.parse(query);
	},

	/**
	 * Convert object into query string .
	 * For example {"key1": "value1", "key2": "value2"} will be converted to "?key1=value1&key2=value2"
	 *
	 * @param {String} obj - Object that will be converted into query string.
	 * @return {Object}
	 */
	object2Query: function(obj) {
		var queries = [];
		_.forEach(obj, function(value, key) {
			if (value) {
				queries.push(key + '=' + value);
			}
		});

		return queries.length === 0 ? '' : '?' + queries.join('&');
	},

	/**
	 * Convert human readable route like "path/:part" into RegExp undestandable part "path/(\w+)"
	 *
	 * @param {String} route - Route, that should be converted
	 */
	_preprocessRouteName: function(route, prefix) {
		if (prefix) {
			prefix = '(?:' + prefix + ')?';
		} else {
			prefix = '';
		}

		route = route.replace(/\:[\w\-\.]+/g, '([\\w\\-\\.]+\/?)');

		return '^#' + prefix + route + '/?$';
	},

	/**
	 * Get hash part of the URL.
	 *
	 * @param {String} url - URL.
	 * @return {String}
	 */
	_getHash: function(url) {
		var match = this.hashRegExp.exec(url) || [];

		return match[1] || match[2] || '#';
	},

	/**
	 * Get query part of the URL.
	 *
	 * @param {String} url - URL.
	 * @return {String|undefined}
	 */
	_getQuery: function(url) {
		var result;
		var match = this.queryRegExp.exec(url) || [];

		if (match[1]) {
			result = match[1];

			if (match[2]) {
				result += '&' + (match[2]).slice(1);
			}
		} else if (match[3]) {
			result = match[3];
		}

		return result;
	}
});
<|endoftext|>


<commit_before>import sortBy from 'lodash/sortBy';
import filter from 'lodash/filter';

export function orderAZ(runs) {
    return sortBy(runs, (o) => {
        return o.job.name;
    });
}

export function orderZA(runs) {
    return sortBy(runs, (o) => {
        return o.job.name;
    }).reverse();
}

export function orderOldest(runs) {
    return sortBy(runs, (o) => {
        return o.started_at;
    });
}

export function orderNewest(runs) {
    return sortBy(runs, (o) => {
        return o.started_at;
    }).reverse();
}

export function myDataPacksOnly(runs, username) {
    const myDataPacks = filter(runs, (o) => {
        return o.user == username
    });
    return myDataPacks;
}

export function search(searchText, runs) {
    const query = searchText.toUpperCase();
    let searched = filter(runs, function(o) {
        if(o.job.name.toUpperCase().includes(query)) { return true}
        if(o.job.description.toUpperCase().includes(query)) {return true}
        if(o.job.event.toUpperCase().includes(query)) {return true}
    });
    return searched;
}
<commit_msg>dont be case sensitive in sort<commit_after>import sortBy from 'lodash/sortBy';
import filter from 'lodash/filter';

export function orderAZ(runs) {
    return sortBy(runs, (o) => {
        return o.job.name.toUpperCase();
    });
}

export function orderZA(runs) {
    return sortBy(runs, (o) => {
        return o.job.name.toUpperCase();
    }).reverse();
}

export function orderOldest(runs) {
    return sortBy(runs, (o) => {
        return o.started_at;
    });
}

export function orderNewest(runs) {
    return sortBy(runs, (o) => {
        return o.started_at;
    }).reverse();
}

export function myDataPacksOnly(runs, username) {
    const myDataPacks = filter(runs, (o) => {
        return o.user == username
    });
    return myDataPacks;
}

export function search(searchText, runs) {
    const query = searchText.toUpperCase();
    let searched = filter(runs, function(o) {
        if(o.job.name.toUpperCase().includes(query)) { return true}
        if(o.job.description.toUpperCase().includes(query)) {return true}
        if(o.job.event.toUpperCase().includes(query)) {return true}
    });
    return searched;
}
<|endoftext|>


<commit_before>const dir = require(`${global.baseDir}/global-dirs`)
let configCustom = {}
try {
	configCustom = require(`${dir.configs}config`)
} catch (e) {
	// Do Nothing
}

const configDefaults = {
	env: 'production',        // Can be 'development' or 'production'.

	//- Server (use this in your browser)
	protocol: 'http',         // Using `https` requires valid certificates.
	hostname: '0.0.0.0',      // Can be 0.0.0.0 for binding to all ports.
	port: 3000,               // Port of webserver.

	apiToken: '',             // LIFX HTTP API Key (https://api.developer.lifx.com/)
}

const configEnv = {
	env: process.env.NODE_ENV,

	protocol: process.env.PROTOCOL,
	hostname: process.env.HOSTNAME,
	port: process.env.PORT,

	apiToken: process.env.API_TOKEN,
}

Object.keys(configEnv)
.forEach(key => typeof configEnv[key] === 'undefined' && delete configEnv[key])

const config = Object.assign({}, configDefaults, configEnv, configCustom)
config.port = Number(config.port)

module.exports = {
	isSecure: () => config.protocol === 'https',
	isDev: () => config.env === 'development',
	isProd: () => config.env === 'production',

	getEnv: () => config.env,

	getProtocol: () => config.protocol,
	getHostname: () => config.hostname,
	getPort: () => config.port,

	getSafeUrl: portFunc => portFunc().replace('0.0.0.0', 'localhost'),
	getServerUrl: () => `${config.protocol}://${config.hostname}:${config.port}`,

	getApiToken: () => config.apiToken,
}
<commit_msg>Removed unnecessary comment from config-settings<commit_after>const dir = require(`${global.baseDir}/global-dirs`)
let configCustom = {}
try {
	configCustom = require(`${dir.configs}config`)
} catch (e) {
	// Do Nothing
}

const configDefaults = {
	env: 'production',        // Can be 'development' or 'production'.

	protocol: 'http',         // Using `https` requires valid certificates.
	hostname: '0.0.0.0',      // Can be 0.0.0.0 for binding to all ports.
	port: 3000,               // Port of webserver.

	apiToken: '',             // LIFX HTTP API Key (https://api.developer.lifx.com/)
}

const configEnv = {
	env: process.env.NODE_ENV,

	protocol: process.env.PROTOCOL,
	hostname: process.env.HOSTNAME,
	port: process.env.PORT,

	apiToken: process.env.API_TOKEN,
}

Object.keys(configEnv)
.forEach(key => typeof configEnv[key] === 'undefined' && delete configEnv[key])

const config = Object.assign({}, configDefaults, configEnv, configCustom)
config.port = Number(config.port)

module.exports = {
	isSecure: () => config.protocol === 'https',
	isDev: () => config.env === 'development',
	isProd: () => config.env === 'production',

	getEnv: () => config.env,

	getProtocol: () => config.protocol,
	getHostname: () => config.hostname,
	getPort: () => config.port,

	getSafeUrl: portFunc => portFunc().replace('0.0.0.0', 'localhost'),
	getServerUrl: () => `${config.protocol}://${config.hostname}:${config.port}`,

	getApiToken: () => config.apiToken,
}
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Fri Dec 04 2015 17:29:55 GMT-0800 (PST)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha', 'fixture', 'chai'],

    // list of files / patterns to load in the browser
    files: [
      'bliss.js',
      'tests/**/*.js',
      'tests/fixtures/**/*.html'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      '**/*.html'   : ['html2js']
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS', 'Chrome'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultanous
    concurrency: Infinity
  })
}
<commit_msg>Removing Chrome from karma config<commit_after>// Karma configuration
// Generated on Fri Dec 04 2015 17:29:55 GMT-0800 (PST)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha', 'fixture', 'chai'],

    // list of files / patterns to load in the browser
    files: [
      'bliss.js',
      'tests/**/*.js',
      'tests/fixtures/**/*.html'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      '**/*.html'   : ['html2js']
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultanous
    concurrency: Infinity
  })
}
<|endoftext|>


<commit_before>(function () {
    'use strict';

    /**
     * @ngdoc service
     * @name data-prep.services.folder.service:FolderService
     * @description Folder service. This service provide the entry point to the Folder service.
     * @requires data-prep.services.folder.service:FolderRestService
     */
    function FolderService(FolderRestService,StateService,state,DatasetService) {

        return {
            // folder operations
            create: createFolder,
            delete: deleteFolder,
            folders: listFolderChilds,

            // folder entry operations
            createFolderEntry: createFolderEntry,
            deleteFolderEntry: deleteFolderEntry,
            listFolderEntries: listFolderEntries,

            // shared folder ui mngt
            buidStackFromId: buidStackFromId,
            loadFolders: loadFolders,
            cleanupPathFolderArray: cleanupPathFolderArray,
            populateChilds: populateChilds,
            goToFolder: goToFolder,
            populateMenuChilds: populateMenuChilds
        };

        //----------------------------------------------
        //   folders
        //----------------------------------------------
        /**
         * @ngdoc method
         * @name deleteFolder
         * @methodOf data-prep.services.folder.service:FolderService
         * @description Delete the folder
         * @param {string} path the path to delete
         * @returns {Promise} The DELETE promise
         */
        function deleteFolder(path) {
            return FolderRestService.delete(path);
        }

        /**
         * @ngdoc method
         * @name createFolder
         * @methodOf data-prep.services.folder.service:FolderService
         * @description Create a folder
         * @param {string} path the path to create
         * @returns {Promise} The PUT promise
         */
        function createFolder(path){
            return FolderRestService.create(path);
        }

        /**
         * @ngdoc method
         * @name listFolderChilds
         * @methodOf data-prep.services.folder.service:FolderService
         * @description List the childs of a folder (or child of root folder)
         * @param {string} path optional path to list childs
         * @returns {Promise} The GET promise
         */
        function listFolderChilds(path){
            return FolderRestService.folders(path);
        }

        //----------------------------------------------
        //   folder entries
        //----------------------------------------------
        /**
         * @ngdoc method
         * @name deleteFolderEntry
         * @methodOf data-prep.services.folder.service:FolderService
         * @description Delete the folder entry
         * @param {string} contentType the content type
         * @param {string} contentId the content id
         * @param {string} path the path to delete
         * @returns {Promise} The DELETE promise
         */
        function deleteFolderEntry(contentType, contentId, path) {
            return FolderRestService.deleteFolderEntry(contentType, contentId, path);
        }

        /**
         * @ngdoc method
         * @name createFolderEntry
         * @methodOf data-prep.services.folder.service:FolderRestService
         * @description Create a folder
         * @param {string} path the path to create
         * @returns {Promise} The PUT promise
         */
        function createFolderEntry(contentType, contentId, path){
            return FolderRestService.createFolderEntry(contentType, contentId, path);
        }

        /**
         * @ngdoc method
         * @name listFolderChilds
         * @methodOf data-prep.services.folder.service:FolderService
         * @description List the childs of a folder (or child of root folder)
         * @param {string} path optional path to list childs
         * @returns {Promise} The GET promise
         */
        function listFolderEntries(contentType,path){
            return FolderRestService.listFolderEntries(contentType, path);
        }

        //----------------------------------------------
        //   shared ui management
        //----------------------------------------------

        function buidStackFromId(folderId){

            // folder.id can be:
            // foo/bar
            // foo
            // foo/
            // so parse that to generate the stack

            // TODO root folder as a constant
            var foldersStack = [];
            foldersStack.push({id:'',path:'All files'});

            if(folderId) {
                var paths = folderId.split('/');
                for(var i = 0;i<=paths.length;i++){
                    if(paths[i]) {
                        if ( i > 0 ) {
                            foldersStack.push( {id: foldersStack[i - 1].path + '/' + paths[i], path: paths[i]} );
                        } else {
                            foldersStack.push( {id: paths[i], path: paths[i]} );
                        }
                    }
                }
            }

            StateService.setFoldersStack(foldersStack);
        }

        function loadFolders(folder,loadController){
            FolderRestService.folders(state.folder.currentFolder.id)
                .then(function(folders){
                    // do not configure childs if it's the first loading
                    if(!folder) {
                        StateService.setCurrentChilds( cleanupPathFolderArray( folders.data, '' ));
                    }
                    // special case for root and first time loading
                    if(!state.folder.currentFolder.id && loadController){
                        var foldersStack = [];
                        foldersStack.push(state.folder.currentFolder);
                        StateService.setFoldersStack(foldersStack);
                    }
                });
        }

        function cleanupPathFolderArray(folders,path){
            _.forEach(folders,function(folder){
                if (folder.path){
                    folder.path = cleanupPath(folder.path.substring(path.length,folder.path.length));
                }

            });
            return folders;
        }

        /**
         * @ngdoc method
         * @name cleanupPath
         * @methodOf data-prep.folder.controller:FolderCtrl
         * @param {string} str - the path to clean
         * @description remove / character
         */
        function cleanupPath(str){
            return str.split('/').join('');
        }

        /**
         * @ngdoc method
         * @name populateChilds
         * @methodOf data-prep.folder.controller:FolderCtrl
         * @description build the child list of the part part given by the index parameter
         */
        function populateChilds(folder){
            // special for root folder
            console.log('populateChilds:'+folder.id);
            var currentPath = folder.id?folder.path:'';
            var promise = FolderRestService.folders(folder.id);

            promise.then(function(response){
                    var foundChilds = cleanupPathFolderArray(response.data,currentPath);
                    StateService.setCurrentChilds(foundChilds);
                });

            return promise;
        }

        /**
         * @ngdoc method
         * @name populateMenuChilds
         * @methodOf data-prep.folder.controller:FolderCtrl
         * @description build the child list of the part part given by the index parameter
         */
        function populateMenuChilds(folder){
            // special for root folder
            console.log('initMenuChilds:'+folder.id);
            var currentPath = folder.id?folder.path:'';
            var promise = FolderRestService.folders(folder.id);

            promise.then(function(response){
                var foundChilds = cleanupPathFolderArray(response.data,currentPath);
                StateService.setMenuChilds(foundChilds);
            });

            return promise;
        }

        /**
         * @ngdoc method
         * @name goToFolder
         * @methodOf data-prep.folder.controller:FolderCtrl
         * @param {object} folder - the folder to go
         */
        function goToFolder(folder){
            buidStackFromId(folder.id);
            StateService.setCurrentFolder(folder);
            loadFolders(folder);
            // loading folder entries
            if (folder.id){
                listFolderEntries( 'dataset', folder.id )
                    .then(function(response){
                        DatasetService.filterDatasets(response.data);
                    })
                    .then(populateChilds(folder,true));
            } else {
                DatasetService.filterDatasets();
                populateChilds(folder);
            }

        }

    }

    angular.module('data-prep.services.folder')
        .service('FolderService', FolderService);
})();<commit_msg>[TDP-401] fix parameter<commit_after>(function () {
    'use strict';

    /**
     * @ngdoc service
     * @name data-prep.services.folder.service:FolderService
     * @description Folder service. This service provide the entry point to the Folder service.
     * @requires data-prep.services.folder.service:FolderRestService
     */
    function FolderService(FolderRestService,StateService,state,DatasetService) {

        return {
            // folder operations
            create: createFolder,
            delete: deleteFolder,
            folders: listFolderChilds,

            // folder entry operations
            createFolderEntry: createFolderEntry,
            deleteFolderEntry: deleteFolderEntry,
            listFolderEntries: listFolderEntries,

            // shared folder ui mngt
            buidStackFromId: buidStackFromId,
            loadFolders: loadFolders,
            cleanupPathFolderArray: cleanupPathFolderArray,
            populateChilds: populateChilds,
            goToFolder: goToFolder,
            populateMenuChilds: populateMenuChilds
        };

        //----------------------------------------------
        //   folders
        //----------------------------------------------
        /**
         * @ngdoc method
         * @name deleteFolder
         * @methodOf data-prep.services.folder.service:FolderService
         * @description Delete the folder
         * @param {string} path the path to delete
         * @returns {Promise} The DELETE promise
         */
        function deleteFolder(path) {
            return FolderRestService.delete(path);
        }

        /**
         * @ngdoc method
         * @name createFolder
         * @methodOf data-prep.services.folder.service:FolderService
         * @description Create a folder
         * @param {string} path the path to create
         * @returns {Promise} The PUT promise
         */
        function createFolder(path){
            return FolderRestService.create(path);
        }

        /**
         * @ngdoc method
         * @name listFolderChilds
         * @methodOf data-prep.services.folder.service:FolderService
         * @description List the childs of a folder (or child of root folder)
         * @param {string} path optional path to list childs
         * @returns {Promise} The GET promise
         */
        function listFolderChilds(path){
            return FolderRestService.folders(path);
        }

        //----------------------------------------------
        //   folder entries
        //----------------------------------------------
        /**
         * @ngdoc method
         * @name deleteFolderEntry
         * @methodOf data-prep.services.folder.service:FolderService
         * @description Delete the folder entry
         * @param {string} contentType the content type
         * @param {string} contentId the content id
         * @param {string} path the path to delete
         * @returns {Promise} The DELETE promise
         */
        function deleteFolderEntry(contentType, contentId, path) {
            return FolderRestService.deleteFolderEntry(contentType, contentId, path);
        }

        /**
         * @ngdoc method
         * @name createFolderEntry
         * @methodOf data-prep.services.folder.service:FolderRestService
         * @description Create a folder
         * @param contentType the entry content type
         * @param contentId the id of the entry content type
         * @param {object} Folder the folder to create the entry
         * @returns {Promise} The PUT promise
         */
        function createFolderEntry(contentType, contentId, folder){
            return FolderRestService.createFolderEntry(contentType, contentId, folder.id);
        }

        /**
         * @ngdoc method
         * @name listFolderChilds
         * @methodOf data-prep.services.folder.service:FolderService
         * @description List the childs of a folder (or child of root folder)
         * @param {object} Folder the folder to create the entry
         * @returns {Promise} The GET promise
         */
        function listFolderEntries(contentType,folder){
            return FolderRestService.listFolderEntries(contentType, folder.id);
        }

        //----------------------------------------------
        //   shared ui management
        //----------------------------------------------

        function buidStackFromId(folderId){

            // folder.id can be:
            // foo/bar
            // foo
            // foo/
            // so parse that to generate the stack

            // TODO root folder as a constant
            var foldersStack = [];
            foldersStack.push({id:'',path:'All files'});

            if(folderId) {
                var paths = folderId.split('/');
                for(var i = 0;i<=paths.length;i++){
                    if(paths[i]) {
                        if ( i > 0 ) {
                            foldersStack.push( {id: foldersStack[i - 1].path + '/' + paths[i], path: paths[i]} );
                        } else {
                            foldersStack.push( {id: paths[i], path: paths[i]} );
                        }
                    }
                }
            }

            StateService.setFoldersStack(foldersStack);
        }

        function loadFolders(folder,loadController){
            FolderRestService.folders(state.folder.currentFolder.id)
                .then(function(folders){
                    // do not configure childs if it's the first loading
                    if(!folder) {
                        StateService.setCurrentChilds( cleanupPathFolderArray( folders.data, '' ));
                    }
                    // special case for root and first time loading
                    if(!state.folder.currentFolder.id && loadController){
                        var foldersStack = [];
                        foldersStack.push(state.folder.currentFolder);
                        StateService.setFoldersStack(foldersStack);
                    }
                });
        }

        function cleanupPathFolderArray(folders,path){
            _.forEach(folders,function(folder){
                if (folder.path){
                    folder.path = cleanupPath(folder.path.substring(path.length,folder.path.length));
                }

            });
            return folders;
        }

        /**
         * @ngdoc method
         * @name cleanupPath
         * @methodOf data-prep.folder.controller:FolderCtrl
         * @param {string} str - the path to clean
         * @description remove / character
         */
        function cleanupPath(str){
            return str.split('/').join('');
        }

        /**
         * @ngdoc method
         * @name populateChilds
         * @methodOf data-prep.folder.controller:FolderCtrl
         * @description build the child list of the part part given by the index parameter
         */
        function populateChilds(folder){
            // special for root folder
            var currentPath = folder.id?folder.path:'';
            var promise = FolderRestService.folders(folder.id);

            promise.then(function(response){
                    var foundChilds = cleanupPathFolderArray(response.data,currentPath);
                    StateService.setCurrentChilds(foundChilds);
                });

            return promise;
        }

        /**
         * @ngdoc method
         * @name populateMenuChilds
         * @methodOf data-prep.folder.controller:FolderCtrl
         * @description build the child list of the part part given by the index parameter
         */
        function populateMenuChilds(folder){
            // special for root folder
            var currentPath = folder.id?folder.path:'';
            var promise = FolderRestService.folders(folder.id);

            promise.then(function(response){
                var foundChilds = cleanupPathFolderArray(response.data,currentPath);
                StateService.setMenuChilds(foundChilds);
            });

            return promise;
        }

        /**
         * @ngdoc method
         * @name goToFolder
         * @methodOf data-prep.folder.controller:FolderCtrl
         * @param {object} folder - the folder to go
         */
        function goToFolder(folder){
            buidStackFromId(folder.id);
            StateService.setCurrentFolder(folder);
            loadFolders(folder);
            // loading folder entries
            if (folder.id){
                listFolderEntries( 'dataset', folder )
                    .then(function(response){
                        DatasetService.filterDatasets(response.data);
                    })
                    .then(populateChilds(folder,true));
            } else {
                DatasetService.filterDatasets();
                populateChilds(folder);
            }

        }

    }

    angular.module('data-prep.services.folder')
        .service('FolderService', FolderService);
})();<|endoftext|>


<commit_before>import expect from 'expect';

import Link from '../../lib/reducer/link';
import {Store} from '../../lib/reducer/store';

describe('Store', () => {
  it('Starts an empty db object', () => {
    const store = new Store();
    expect(store.db).toEqual({});
  });

  const store = new Store();

  it('Adds a single node', () => {
    store.updateNodes({
      a: {
        _id: 'a',
        title: 'something'
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'something'
      }
    });
  });

  it('Adds more nodes', () => {
    store.updateNodes({
      b: {
        _id: 'b',
        title: 'something B'
      },
      c: {
        _id: 'c',
        title: 'something C'
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'something'
      },
      b: {
        _id: 'b',
        title: 'something B'
      },
      c: {
        _id: 'c',
        title: 'something C'
      }
    });
  });

  it('Makes changes to nodes', () => {
    store.updateNodes({
      b: {
        _id: 'b',
        title: 'something about B'
      },
      c: {
        _id: 'c',
        title: 'something about C'
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'something'
      },
      b: {
        _id: 'b',
        title: 'something about B'
      },
      c: {
        _id: 'c',
        title: 'something about C'
      }
    });
  });

  it('Adds nodes with nested structures', () => {
    store.updateNodes({
      d: {
        _id: 'd',
        title: 'something about D',
        nested: {
          something: 'nice'
        }
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'something'
      },
      b: {
        _id: 'b',
        title: 'something about B'
      },
      c: {
        _id: 'c',
        title: 'something about C'
      },
      d: {
        _id: 'd',
        title: 'something about D',
        nested: {
          something: 'nice'
        }
      }
    });
  });

  it('Updates nodes with nested structures', () => {
    store.updateNodes({
      d: {
        _id: 'd',
        nested: {
          changing: 'cool'
        }
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'something'
      },
      b: {
        _id: 'b',
        title: 'something about B'
      },
      c: {
        _id: 'c',
        title: 'something about C'
      },
      d: {
        _id: 'd',
        title: 'something about D',
        nested: {
          something: 'nice',
          changing: 'cool'
        }
      }
    });
  });

  it('Gets single node data', () => {
    const data = store.getData('a');
    expect(data).toEqual({
      _id: 'a',
      title: 'something'
    });
  });

  it('Gets array of nodes', () => {
    const data = store.getData(['a', 'b']);
    expect(data).toEqual([
      {
        _id: 'a',
        title: 'something'
      },
      {
        _id: 'b',
        title: 'something about B'
      }
    ]);
  });

  it('Gets nested node', () => {
    const data = store.getData({item: 'a'});
    expect(data).toEqual({
      item: {
        _id: 'a',
        title: 'something'
      }
    });
  });

  it('Gets nested array of node', () => {
    const data = store.getData({item: ['a', 'b']});
    expect(data).toEqual({
      item: [
        {
          _id: 'a',
          title: 'something'
        },
        {
          _id: 'b',
          title: 'something about B'
        }
      ]
    });
  });

  it('Adds nodes with Link nodes', () => {
    // Clean up
    store.db = {};

    store.updateNodes({
      a: {
        _id: 'a',
        title: 'A'
      },
      b: {
        _id: 'b',
        title: 'B',
        linked: new Link('a')
      },
      c: {
        _id: 'c',
        title: 'C',
        linked: new Link(['a', 'b'])
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'A'
      },
      b: {
        _id: 'b',
        title: 'B',
        linked: new Link('a')
      },
      c: {
        _id: 'c',
        title: 'C',
        linked: new Link(['a', 'b'])
      }
    });
  });

  it('Gets data node with a Link', () => {
    const data = store.getData('b');
    expect(data).toEqual({
      _id: 'b',
      title: 'B',
      linked: {
        _id: 'a',
        title: 'A'
      }
    });
  });

  it('Gets data node with array of Links', () => {
    const data = store.getData('c');
    expect(data).toEqual({
      _id: 'c',
      title: 'C',
      linked: [
        {
          _id: 'a',
          title: 'A'
        },
        {
          _id: 'b',
          title: 'B',
          linked: {
            _id: 'a',
            title: 'A'
          }
        }
      ]
    });
  });
});
<commit_msg>store remove node test<commit_after>import expect from 'expect';

import Link from '../../lib/reducer/link';
import {Store} from '../../lib/reducer/store';

describe('Store', () => {
  it('Starts an empty db object', () => {
    const store = new Store();
    expect(store.db).toEqual({});
  });

  const store = new Store();

  it('Adds a single node', () => {
    store.updateNodes({
      a: {
        _id: 'a',
        title: 'something'
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'something'
      }
    });
  });

  it('Adds more nodes', () => {
    store.updateNodes({
      b: {
        _id: 'b',
        title: 'something B'
      },
      c: {
        _id: 'c',
        title: 'something C'
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'something'
      },
      b: {
        _id: 'b',
        title: 'something B'
      },
      c: {
        _id: 'c',
        title: 'something C'
      }
    });
  });

  it('Makes changes to nodes', () => {
    store.updateNodes({
      b: {
        _id: 'b',
        title: 'something about B'
      },
      c: {
        _id: 'c',
        title: 'something about C'
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'something'
      },
      b: {
        _id: 'b',
        title: 'something about B'
      },
      c: {
        _id: 'c',
        title: 'something about C'
      }
    });
  });

  it('Adds nodes with nested structures', () => {
    store.updateNodes({
      d: {
        _id: 'd',
        title: 'something about D',
        nested: {
          something: 'nice'
        }
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'something'
      },
      b: {
        _id: 'b',
        title: 'something about B'
      },
      c: {
        _id: 'c',
        title: 'something about C'
      },
      d: {
        _id: 'd',
        title: 'something about D',
        nested: {
          something: 'nice'
        }
      }
    });
  });

  it('Updates nodes with nested structures', () => {
    store.updateNodes({
      d: {
        _id: 'd',
        nested: {
          changing: 'cool'
        }
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'something'
      },
      b: {
        _id: 'b',
        title: 'something about B'
      },
      c: {
        _id: 'c',
        title: 'something about C'
      },
      d: {
        _id: 'd',
        title: 'something about D',
        nested: {
          something: 'nice',
          changing: 'cool'
        }
      }
    });
  });

  it('Gets single node data', () => {
    const data = store.getData('a');
    expect(data).toEqual({
      _id: 'a',
      title: 'something'
    });
  });

  it('Gets array of nodes', () => {
    const data = store.getData(['a', 'b']);
    expect(data).toEqual([
      {
        _id: 'a',
        title: 'something'
      },
      {
        _id: 'b',
        title: 'something about B'
      }
    ]);
  });

  it('Gets nested node', () => {
    const data = store.getData({item: 'a'});
    expect(data).toEqual({
      item: {
        _id: 'a',
        title: 'something'
      }
    });
  });

  it('Gets nested array of node', () => {
    const data = store.getData({item: ['a', 'b']});
    expect(data).toEqual({
      item: [
        {
          _id: 'a',
          title: 'something'
        },
        {
          _id: 'b',
          title: 'something about B'
        }
      ]
    });
  });

  it('Adds nodes with Link nodes', () => {
    // Clean up
    store.db = {};

    store.updateNodes({
      a: {
        _id: 'a',
        title: 'A'
      },
      b: {
        _id: 'b',
        title: 'B',
        linked: new Link('a')
      },
      c: {
        _id: 'c',
        title: 'C',
        linked: new Link(['a', 'b'])
      }
    });
    expect(store.db).toEqual({
      a: {
        _id: 'a',
        title: 'A'
      },
      b: {
        _id: 'b',
        title: 'B',
        linked: new Link('a')
      },
      c: {
        _id: 'c',
        title: 'C',
        linked: new Link(['a', 'b'])
      }
    });
  });

  it('Gets data node with a Link', () => {
    const data = store.getData('b');
    expect(data).toEqual({
      _id: 'b',
      title: 'B',
      linked: {
        _id: 'a',
        title: 'A'
      }
    });
  });

  it('Gets data node with array of Links', () => {
    const data = store.getData('c');
    expect(data).toEqual({
      _id: 'c',
      title: 'C',
      linked: [
        {
          _id: 'a',
          title: 'A'
        },
        {
          _id: 'b',
          title: 'B',
          linked: {
            _id: 'a',
            title: 'A'
          }
        }
      ]
    });
  });

  it('Removes node', () => {
    // Clean up
    store.db = {};

    store.updateNodes({
      a: {
        _id: 'a',
        title: 'A'
      },
      b: {
        _id: 'b',
        title: 'B',
        linked: new Link('a')
      },
      c: {
        _id: 'c',
        title: 'C',
        linked: new Link(['a', 'b'])
      }
    });
    store.removeNode('a');
    expect(store.db).toEqual({
      b: {
        _id: 'b',
        title: 'B',
        linked: new Link('a')
      },
      c: {
        _id: 'c',
        title: 'C',
        linked: new Link(['a', 'b'])
      }
    });
    store.removeNode('b');
    expect(store.db).toEqual({
      c: {
        _id: 'c',
        title: 'C',
        linked: new Link(['a', 'b'])
      }
    });
  });
});
<|endoftext|>


<commit_before><commit_msg>Fixed redirects on auth and logout.<commit_after><|endoftext|>


<commit_before>'use strict';

/**
 * Here is the problem: http://bugs.jquery.com/ticket/7292
 * basically jQuery treats change event on some browsers (IE) as a
 * special event and changes it form 'change' to 'click/keydown' and
 * few others. This horrible hack removes the special treatment
 */
if (window._jQuery) _jQuery.event.special.change = undefined;

if (window.bindJQuery) bindJQuery();

beforeEach(function() {
  // all this stuff is not needed for module tests, where jqlite and publishExternalAPI and jqLite are not global vars
  if (window.publishExternalAPI) {
    publishExternalAPI(angular);

    // workaround for IE bug https://plus.google.com/104744871076396904202/posts/Kqjuj6RSbbT
    // IE overwrite window.jQuery with undefined because of empty jQuery var statement, so we have to
    // correct this, but only if we are not running in jqLite mode
    if (!_jqLiteMode && _jQuery !== jQuery) {
      jQuery = _jQuery;
    }

    // This resets global id counter;
    uid = ['0', '0', '0'];

    // reset to jQuery or default to us.
    bindJQuery();
  }

  angular.element(document.body).html('').removeData();
});

afterEach(function() {
  if (this.$injector) {
    var $rootScope = this.$injector.get('$rootScope');
    var $rootElement = this.$injector.get('$rootElement');
    var $log = this.$injector.get('$log');
    // release the injector
    dealoc($rootScope);
    dealoc($rootElement);

    // check $log mock
    $log.assertEmpty && $log.assertEmpty();
  }

  // complain about uncleared jqCache references
  var count = 0;

  // This line should be enabled as soon as this bug is fixed: http://bugs.jquery.com/ticket/11775
  //var cache = jqLite.cache;
  var cache = angular.element.cache;

  forEachSorted(cache, function(expando, key){
    angular.forEach(expando.data, function(value, key){
      count ++;
      if (value.$element) {
        dump('LEAK', key, value.$id, sortedHtml(value.$element));
      } else {
        dump('LEAK', key, angular.toJson(value));
      }
    });
  });
  if (count) {
    throw new Error('Found jqCache references that were not deallocated! count: ' + count);
  }

  // copied from Angular.js
  // we need these two methods here so that we can run module tests with wrapped angular.js
  function sortedKeys(obj) {
    var keys = [];
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        keys.push(key);
      }
    }
    return keys.sort();
  }

  function forEachSorted(obj, iterator, context) {
    var keys = sortedKeys(obj);
    for ( var i = 0; i < keys.length; i++) {
      iterator.call(context, obj[keys[i]], keys[i]);
    }
    return keys;
  }
});

function dealoc(obj) {
  var jqCache = angular.element.cache;
  if (obj) {
    if (angular.isElement(obj)) {
      cleanup(angular.element(obj));
    } else {
      for(var key in jqCache) {
        var value = jqCache[key];
        if (value.data && value.data.$scope == obj) {
          delete jqCache[key];
        }
      }
    }
  }

  function cleanup(element) {
    element.unbind().removeData();
    for ( var i = 0, children = element.contents() || []; i < children.length; i++) {
      cleanup(angular.element(children[i]));
    }
  }
}

/**
 * @param {DOMElement} element
 * @param {boolean=} showNgClass
 */
function sortedHtml(element, showNgClass) {
  var html = "";
  forEach(jqLite(element), function toString(node) {

    if (node.nodeName == "#text") {
      html += node.nodeValue.
        replace(/&(\w+[&;\W])?/g, function(match, entity){return entity?match:'&';}).
        replace(/</g, '<').
        replace(/>/g, '>');
    } else if (node.nodeName == "#comment") {
      html += '<!--' + node.nodeValue + '-->';
    } else {
      html += '<' + (node.nodeName || '?NOT_A_NODE?').toLowerCase();
      var attributes = node.attributes || [];
      var attrs = [];
      var className = node.className || '';
      if (!showNgClass) {
        className = className.replace(/ng-[\w-]+\s*/g, '');
      }
      className = trim(className);
      if (className) {
        attrs.push(' class="' + className + '"');
      }
      for(var i=0; i<attributes.length; i++) {
        if (i>0 && attributes[i] == attributes[i-1])
          continue; //IE9 creates dupes. Ignore them!

        var attr = attributes[i];
        if(attr.name.match(/^ng[\:\-]/) ||
            (attr.value || attr.value == '') &&
            attr.value !='null' &&
            attr.value !='auto' &&
            attr.value !='false' &&
            attr.value !='inherit' &&
            (attr.value !='0' || attr.name =='value') &&
            attr.name !='loop' &&
            attr.name !='complete' &&
            attr.name !='maxLength' &&
            attr.name !='size' &&
            attr.name !='class' &&
            attr.name !='start' &&
            attr.name !='tabIndex' &&
            attr.name !='style' &&
            attr.name.substr(0, 6) != 'jQuery') {
          // in IE we need to check for all of these.
          if (!/ng-\d+/.exec(attr.name) &&
              attr.name != 'getElementById' &&
              // IE7 has `selected` in attributes
              attr.name !='selected' &&
              // IE7 adds `value` attribute to all LI tags
              (node.nodeName != 'LI' || attr.name != 'value'))
            attrs.push(' ' + attr.name + '="' + attr.value + '"');
        }
      }
      attrs.sort();
      html += attrs.join('');
      if (node.style) {
        var style = [];
        if (node.style.cssText) {
          forEach(node.style.cssText.split(';'), function(value){
            value = trim(value);
            if (value) {
              style.push(lowercase(value));
            }
          });
        }
        for(var css in node.style){
          var value = node.style[css];
          if (isString(value) && isString(css) && css != 'cssText' && value && (1*css != css)) {
            var text = lowercase(css + ': ' + value);
            if (value != 'false' && indexOf(style, text) == -1) {
              style.push(text);
            }
          }
        }
        style.sort();
        var tmp = style;
        style = [];
        forEach(tmp, function(value){
          if (!value.match(/^max[^\-]/))
            style.push(value);
        });
        if (style.length) {
          html += ' style="' + style.join('; ') + ';"';
        }
      }
      html += '>';
      var children = node.childNodes;
      for(var j=0; j<children.length; j++) {
        toString(children[j]);
      }
      html += '</' + node.nodeName.toLowerCase() + '>';
    }
  });
  return html;
}

// TODO(vojta): migrate these helpers into jasmine matchers
/**a
 * This method is a cheap way of testing if css for a given node is not set to 'none'. It doesn't
 * actually test if an element is displayed by the browser. Be aware!!!
 */
function isCssVisible(node) {
  var display = node.css('display');
  return display != 'none';
}

function assertHidden(node) {
  if (isCssVisible(node)) {
    throw new Error('Node should be hidden but was visible: ' + angular.module.ngMock.dump(node));
  }
}

function assertVisible(node) {
  if (!isCssVisible(node)) {
    throw new Error('Node should be visible but was hidden: ' + angular.module.ngMock.dump(node));
  }
}

function provideLog($provide) {
  $provide.factory('log', function() {
      var messages = [];

      function log(msg) {
        messages.push(msg);
        return msg;
      }

      log.toString = function() {
        return messages.join('; ');
      }

      log.toArray = function() {
        return messages;
      }

      log.reset = function() {
        messages = [];
      }

      log.fn = function(msg) {
        return function() {
          log(msg);
        }
      }

      log.$$log = true;

      return log;
    });
}

function pending() {
  dump('PENDING');
};

function trace(name) {
  dump(new Error(name).stack);
}
<commit_msg>test(sortedHtml): ignore bogus rowspan=1 and colspan=1 in IE<commit_after>'use strict';

/**
 * Here is the problem: http://bugs.jquery.com/ticket/7292
 * basically jQuery treats change event on some browsers (IE) as a
 * special event and changes it form 'change' to 'click/keydown' and
 * few others. This horrible hack removes the special treatment
 */
if (window._jQuery) _jQuery.event.special.change = undefined;

if (window.bindJQuery) bindJQuery();

beforeEach(function() {
  // all this stuff is not needed for module tests, where jqlite and publishExternalAPI and jqLite are not global vars
  if (window.publishExternalAPI) {
    publishExternalAPI(angular);

    // workaround for IE bug https://plus.google.com/104744871076396904202/posts/Kqjuj6RSbbT
    // IE overwrite window.jQuery with undefined because of empty jQuery var statement, so we have to
    // correct this, but only if we are not running in jqLite mode
    if (!_jqLiteMode && _jQuery !== jQuery) {
      jQuery = _jQuery;
    }

    // This resets global id counter;
    uid = ['0', '0', '0'];

    // reset to jQuery or default to us.
    bindJQuery();
  }

  angular.element(document.body).html('').removeData();
});

afterEach(function() {
  if (this.$injector) {
    var $rootScope = this.$injector.get('$rootScope');
    var $rootElement = this.$injector.get('$rootElement');
    var $log = this.$injector.get('$log');
    // release the injector
    dealoc($rootScope);
    dealoc($rootElement);

    // check $log mock
    $log.assertEmpty && $log.assertEmpty();
  }

  // complain about uncleared jqCache references
  var count = 0;

  // This line should be enabled as soon as this bug is fixed: http://bugs.jquery.com/ticket/11775
  //var cache = jqLite.cache;
  var cache = angular.element.cache;

  forEachSorted(cache, function(expando, key){
    angular.forEach(expando.data, function(value, key){
      count ++;
      if (value.$element) {
        dump('LEAK', key, value.$id, sortedHtml(value.$element));
      } else {
        dump('LEAK', key, angular.toJson(value));
      }
    });
  });
  if (count) {
    throw new Error('Found jqCache references that were not deallocated! count: ' + count);
  }

  // copied from Angular.js
  // we need these two methods here so that we can run module tests with wrapped angular.js
  function sortedKeys(obj) {
    var keys = [];
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        keys.push(key);
      }
    }
    return keys.sort();
  }

  function forEachSorted(obj, iterator, context) {
    var keys = sortedKeys(obj);
    for ( var i = 0; i < keys.length; i++) {
      iterator.call(context, obj[keys[i]], keys[i]);
    }
    return keys;
  }
});

function dealoc(obj) {
  var jqCache = angular.element.cache;
  if (obj) {
    if (angular.isElement(obj)) {
      cleanup(angular.element(obj));
    } else {
      for(var key in jqCache) {
        var value = jqCache[key];
        if (value.data && value.data.$scope == obj) {
          delete jqCache[key];
        }
      }
    }
  }

  function cleanup(element) {
    element.unbind().removeData();
    for ( var i = 0, children = element.contents() || []; i < children.length; i++) {
      cleanup(angular.element(children[i]));
    }
  }
}

/**
 * @param {DOMElement} element
 * @param {boolean=} showNgClass
 */
function sortedHtml(element, showNgClass) {
  var html = "";
  forEach(jqLite(element), function toString(node) {

    if (node.nodeName == "#text") {
      html += node.nodeValue.
        replace(/&(\w+[&;\W])?/g, function(match, entity){return entity?match:'&';}).
        replace(/</g, '<').
        replace(/>/g, '>');
    } else if (node.nodeName == "#comment") {
      html += '<!--' + node.nodeValue + '-->';
    } else {
      html += '<' + (node.nodeName || '?NOT_A_NODE?').toLowerCase();
      var attributes = node.attributes || [];
      var attrs = [];
      var className = node.className || '';
      if (!showNgClass) {
        className = className.replace(/ng-[\w-]+\s*/g, '');
      }
      className = trim(className);
      if (className) {
        attrs.push(' class="' + className + '"');
      }
      for(var i=0; i<attributes.length; i++) {
        if (i>0 && attributes[i] == attributes[i-1])
          continue; //IE9 creates dupes. Ignore them!

        var attr = attributes[i];
        if(attr.name.match(/^ng[\:\-]/) ||
            (attr.value || attr.value == '') &&
            attr.value !='null' &&
            attr.value !='auto' &&
            attr.value !='false' &&
            attr.value !='inherit' &&
            (attr.value !='0' || attr.name =='value') &&
            attr.name !='loop' &&
            attr.name !='complete' &&
            attr.name !='maxLength' &&
            attr.name !='size' &&
            attr.name !='class' &&
            attr.name !='start' &&
            attr.name !='tabIndex' &&
            attr.name !='style' &&
            attr.name.substr(0, 6) != 'jQuery') {
          // in IE we need to check for all of these.
          if (/ng-\d+/.exec(attr.name) ||
              attr.name == 'getElementById' ||
              // IE7 has `selected` in attributes
              attr.name == 'selected' ||
              // IE7 adds `value` attribute to all LI tags
              (node.nodeName == 'LI' && attr.name == 'value') ||
              // IE8 adds bogus rowspan=1 and colspan=1 to TD elements
              (node.nodeName == 'TD' && attr.name == 'rowSpan' && attr.value == '1') ||
              (node.nodeName == 'TD' && attr.name == 'colSpan' && attr.value == '1')) {
            continue;
          }

          attrs.push(' ' + attr.name + '="' + attr.value + '"');
        }
      }
      attrs.sort();
      html += attrs.join('');
      if (node.style) {
        var style = [];
        if (node.style.cssText) {
          forEach(node.style.cssText.split(';'), function(value){
            value = trim(value);
            if (value) {
              style.push(lowercase(value));
            }
          });
        }
        for(var css in node.style){
          var value = node.style[css];
          if (isString(value) && isString(css) && css != 'cssText' && value && (1*css != css)) {
            var text = lowercase(css + ': ' + value);
            if (value != 'false' && indexOf(style, text) == -1) {
              style.push(text);
            }
          }
        }
        style.sort();
        var tmp = style;
        style = [];
        forEach(tmp, function(value){
          if (!value.match(/^max[^\-]/))
            style.push(value);
        });
        if (style.length) {
          html += ' style="' + style.join('; ') + ';"';
        }
      }
      html += '>';
      var children = node.childNodes;
      for(var j=0; j<children.length; j++) {
        toString(children[j]);
      }
      html += '</' + node.nodeName.toLowerCase() + '>';
    }
  });
  return html;
}

// TODO(vojta): migrate these helpers into jasmine matchers
/**a
 * This method is a cheap way of testing if css for a given node is not set to 'none'. It doesn't
 * actually test if an element is displayed by the browser. Be aware!!!
 */
function isCssVisible(node) {
  var display = node.css('display');
  return display != 'none';
}

function assertHidden(node) {
  if (isCssVisible(node)) {
    throw new Error('Node should be hidden but was visible: ' + angular.module.ngMock.dump(node));
  }
}

function assertVisible(node) {
  if (!isCssVisible(node)) {
    throw new Error('Node should be visible but was hidden: ' + angular.module.ngMock.dump(node));
  }
}

function provideLog($provide) {
  $provide.factory('log', function() {
      var messages = [];

      function log(msg) {
        messages.push(msg);
        return msg;
      }

      log.toString = function() {
        return messages.join('; ');
      }

      log.toArray = function() {
        return messages;
      }

      log.reset = function() {
        messages = [];
      }

      log.fn = function(msg) {
        return function() {
          log(msg);
        }
      }

      log.$$log = true;

      return log;
    });
}

function pending() {
  dump('PENDING');
};

function trace(name) {
  dump(new Error(name).stack);
}
<|endoftext|>


<commit_before>// Generated by CoffeeScript 1.12.2
(function() {
  var Airbud, fs, request, retry,
    slice = [].slice;

  request = require("request");

  fs = require("fs");

  retry = require("retry");

  Airbud = (function() {
    Airbud._defaults = {
      operationTimeout: 30000,
      retries: 4,
      factor: 2.99294,
      minInterval: 5 * 1000,
      maxInterval: 2e308,
      randomize: true,
      parseJson: null,
      fetchResponseObj: false,
      expectedKey: null,
      expectedStatus: "20x",
      headers: []
    };

    Airbud.getDefaults = function() {
      return Airbud._defaults;
    };

    Airbud.setDefaults = function(options) {
      var key, results, val;
      results = [];
      for (key in options) {
        val = options[key];
        results.push(Airbud._defaults[key] = val);
      }
      return results;
    };

    Airbud.json = function(options, cb) {
      var airbud;
      airbud = new Airbud(options, {
        parseJson: true
      });
      return Airbud.retrieve(airbud, cb);
    };

    Airbud.retrieve = function(options, cb) {
      var airbud, err;
      if (options instanceof Airbud) {
        airbud = options;
      } else {
        airbud = new Airbud(options);
      }
      try {
        return airbud.fetch(cb);
      } catch (error) {
        err = error;
        err.message = "Got an error while retrieving " + airbud.url + ". " + err;
        return cb(err);
      }
    };

    function Airbud() {
      var i, key, len, optionSets, options, val;
      optionSets = 1 <= arguments.length ? slice.call(arguments, 0) : [];
      optionSets.unshift(Airbud.getDefaults());
      for (i = 0, len = optionSets.length; i < len; i++) {
        options = optionSets[i];
        if (typeof options === "string") {
          options = {
            url: options
          };
        }
        for (key in options) {
          val = options[key];
          this[key] = val;
        }
      }
      if ((this.expectedStatus != null) && !(this.expectedStatus instanceof RegExp)) {
        if (!(this.expectedStatus instanceof Array)) {
          this.expectedStatus = [this.expectedStatus];
        }
        this.expectedStatus = this.expectedStatus.join("|").replace(/x/g, "\\d");
        this.expectedStatus = new RegExp("^" + this.expectedStatus + "$");
      }
    }

    Airbud.prototype.fetch = function(mainCb) {
      var calledCallbacks, cb, cbOperationTimeout, operation, operationDurations, operationStart, timeoutErr, totalStart;
      operation = retry.operation({
        retries: this.retries,
        factor: this.factor,
        minTimeout: this.minInterval,
        maxTimeout: this.maxInterval,
        randomize: this.randomize
      });
      cbOperationTimeout = null;
      timeoutErr = null;
      operationStart = null;
      calledCallbacks = {};
      cb = (function(_this) {
        return function(err, data, res) {
          var meta, returnErr, totalDuration;
          if (calledCallbacks[operationStart]) {
            return;
          }
          calledCallbacks[operationStart] = true;
          operationDurations += +(new Date) - operationStart;
          if (operation.retry(err)) {
            return;
          }
          totalDuration = +(new Date) - totalStart;
          meta = {
            statusCode: res != null ? res.statusCode : void 0,
            errors: operation.errors(),
            attempts: operation.attempts(),
            totalDuration: totalDuration,
            operationDuration: Math.floor(operationDurations / operation.attempts())
          };
          returnErr = err ? operation.mainError() : null;
          if (_this.fetchResponseObj) {
            meta.responseObj = res;
          }
          return mainCb(returnErr, data, meta);
        };
      })(this);
      if (this.operationTimeout != null) {
        cbOperationTimeout = {
          timeout: this.operationTimeout,
          cb: (function(_this) {
            return function() {
              var msg;
              msg = "Operation timeout of " + _this.operationTimeout + "ms reached.";
              timeoutErr = new Error(msg);
              return cb(timeoutErr);
            };
          })(this)
        };
      }
      totalStart = +(new Date);
      operationDurations = 0;
      return operation.attempt((function(_this) {
        return function(currentAttempt) {
          operationStart = +(new Date);
          calledCallbacks[operationStart] = false;
          return _this._execute(cb);
        };
      })(this), cbOperationTimeout);
    };

    Airbud.prototype._execute = function(cb) {
      var err, path, reqOpts;
      if (!this.url) {
        err = new Error("You did not specify a url to fetch");
        return cb(err);
      }
      if (this.url.indexOf("file://") === 0) {
        path = this.url.substr(7, this.url.length).split("?")[0];
        fs.readFile(path, "utf8", (function(_this) {
          return function(err, buf) {
            var returnErr;
            if (err) {
              returnErr = new Error("Cannot open '" + path + "'. " + err.message);
              return cb(returnErr);
            }
            return _this._handleData(buf, {}, cb);
          };
        })(this));
        return;
      }
      reqOpts = {
        url: this.url
      };
      if (this.headers != null) {
        reqOpts.headers = this.headers;
      }
      return request.get(reqOpts, (function(_this) {
        return function(err, res, buf) {
          var msg;
          if (err) {
            return cb(err, buf, res);
          }
          if (_this.expectedStatus != null) {
            if (!_this.expectedStatus.test(res.statusCode + "")) {
              msg = "HTTP Status " + res.statusCode + " received when fetching '" + _this.url + "'. ";
              msg += "Expected: " + _this.expectedStatus + ". " + ((buf + "").substr(0, 30)) + "..";
              err = new Error(msg);
              return cb(err, buf, res);
            }
          }
          return _this._handleData(buf, res, cb);
        };
      })(this));
    };

    Airbud.prototype._handleData = function(buf, res, cb) {
      var data, err, msg;
      data = buf;
      if (!this.parseJson) {
        return cb(null, data, res);
      }
      try {
        data = JSON.parse(data);
      } catch (error) {
        err = error;
        err.message = "Got an error while parsing json for " + this.url + ". " + err;
        return cb(err, data, res);
      }
      if ((this.expectedKey != null) && (data[this.expectedKey] == null)) {
        msg = "Invalid body received when fetching '" + this.url + "'. \n";
        msg += "No key: " + this.expectedKey + ". " + buf;
        err = new Error(msg);
        return cb(err, data, res);
      }
      return cb(null, data, res);
    };

    return Airbud;

  })();

  module.exports = Airbud;

}).call(this);
<commit_msg>Update Airbud.js<commit_after>// Generated by CoffeeScript 1.12.2
(function() {
  var Airbud, fs, request, retry,
    slice = [].slice;

  request = require("request");

  fs = require("fs");

  retry = require("retry");

  Airbud = (function() {
    Airbud._defaults = {
      operationTimeout: 30000,
      retries: 4,
      factor: 2.99294,
      minInterval: 5 * 1000,
      maxInterval: 2e308,
      randomize: true,
      parseJson: null,
      fetchResponseObj: false,
      expectedKey: null,
      expectedStatus: "20x",
      headers: [],
      auth: {}
    };

    Airbud.getDefaults = function() {
      return Airbud._defaults;
    };

    Airbud.setDefaults = function(options) {
      var key, results, val;
      results = [];
      for (key in options) {
        val = options[key];
        results.push(Airbud._defaults[key] = val);
      }
      return results;
    };

    Airbud.json = function(options, cb) {
      var airbud;
      airbud = new Airbud(options, {
        parseJson: true
      });
      return Airbud.retrieve(airbud, cb);
    };

    Airbud.retrieve = function(options, cb) {
      var airbud, err;
      if (options instanceof Airbud) {
        airbud = options;
      } else {
        airbud = new Airbud(options);
      }
      try {
        return airbud.fetch(cb);
      } catch (error) {
        err = error;
        err.message = "Got an error while retrieving " + airbud.url + ". " + err;
        return cb(err);
      }
    };

    function Airbud() {
      var i, key, len, optionSets, options, val;
      optionSets = 1 <= arguments.length ? slice.call(arguments, 0) : [];
      optionSets.unshift(Airbud.getDefaults());
      for (i = 0, len = optionSets.length; i < len; i++) {
        options = optionSets[i];
        if (typeof options === "string") {
          options = {
            url: options
          };
        }
        for (key in options) {
          val = options[key];
          this[key] = val;
        }
      }
      if ((this.expectedStatus != null) && !(this.expectedStatus instanceof RegExp)) {
        if (!(this.expectedStatus instanceof Array)) {
          this.expectedStatus = [this.expectedStatus];
        }
        this.expectedStatus = this.expectedStatus.join("|").replace(/x/g, "\\d");
        this.expectedStatus = new RegExp("^" + this.expectedStatus + "$");
      }
    }

    Airbud.prototype.fetch = function(mainCb) {
      var calledCallbacks, cb, cbOperationTimeout, operation, operationDurations, operationStart, timeoutErr, totalStart;
      operation = retry.operation({
        retries: this.retries,
        factor: this.factor,
        minTimeout: this.minInterval,
        maxTimeout: this.maxInterval,
        randomize: this.randomize
      });
      cbOperationTimeout = null;
      timeoutErr = null;
      operationStart = null;
      calledCallbacks = {};
      cb = (function(_this) {
        return function(err, data, res) {
          var meta, returnErr, totalDuration;
          if (calledCallbacks[operationStart]) {
            return;
          }
          calledCallbacks[operationStart] = true;
          operationDurations += +(new Date) - operationStart;
          if (operation.retry(err)) {
            return;
          }
          totalDuration = +(new Date) - totalStart;
          meta = {
            statusCode: res != null ? res.statusCode : void 0,
            errors: operation.errors(),
            attempts: operation.attempts(),
            totalDuration: totalDuration,
            operationDuration: Math.floor(operationDurations / operation.attempts())
          };
          returnErr = err ? operation.mainError() : null;
          if (_this.fetchResponseObj) {
            meta.responseObj = res;
          }
          return mainCb(returnErr, data, meta);
        };
      })(this);
      if (this.operationTimeout != null) {
        cbOperationTimeout = {
          timeout: this.operationTimeout,
          cb: (function(_this) {
            return function() {
              var msg;
              msg = "Operation timeout of " + _this.operationTimeout + "ms reached.";
              timeoutErr = new Error(msg);
              return cb(timeoutErr);
            };
          })(this)
        };
      }
      totalStart = +(new Date);
      operationDurations = 0;
      return operation.attempt((function(_this) {
        return function(currentAttempt) {
          operationStart = +(new Date);
          calledCallbacks[operationStart] = false;
          return _this._execute(cb);
        };
      })(this), cbOperationTimeout);
    };

    Airbud.prototype._execute = function(cb) {
      var err, path, reqOpts;
      if (!this.url) {
        err = new Error("You did not specify a url to fetch");
        return cb(err);
      }
      if (this.url.indexOf("file://") === 0) {
        path = this.url.substr(7, this.url.length).split("?")[0];
        fs.readFile(path, "utf8", (function(_this) {
          return function(err, buf) {
            var returnErr;
            if (err) {
              returnErr = new Error("Cannot open '" + path + "'. " + err.message);
              return cb(returnErr);
            }
            return _this._handleData(buf, {}, cb);
          };
        })(this));
        return;
      }
      reqOpts = {
        url: this.url
      };
      if (this.headers != null) {
        reqOpts.headers = this.headers;
      }
      if (this.auth != null) {
        reqOpts.auth = this.auth;
      }
      return request.get(reqOpts, (function(_this) {
        return function(err, res, buf) {
          var msg;
          if (err) {
            return cb(err, buf, res);
          }
          if (_this.expectedStatus != null) {
            if (!_this.expectedStatus.test(res.statusCode + "")) {
              msg = "HTTP Status " + res.statusCode + " received when fetching '" + _this.url + "'. ";
              msg += "Expected: " + _this.expectedStatus + ". " + ((buf + "").substr(0, 30)) + "..";
              err = new Error(msg);
              return cb(err, buf, res);
            }
          }
          return _this._handleData(buf, res, cb);
        };
      })(this));
    };

    Airbud.prototype._handleData = function(buf, res, cb) {
      var data, err, msg;
      data = buf;
      if (!this.parseJson) {
        return cb(null, data, res);
      }
      try {
        data = JSON.parse(data);
      } catch (error) {
        err = error;
        err.message = "Got an error while parsing json for " + this.url + ". " + err;
        return cb(err, data, res);
      }
      if ((this.expectedKey != null) && (data[this.expectedKey] == null)) {
        msg = "Invalid body received when fetching '" + this.url + "'. \n";
        msg += "No key: " + this.expectedKey + ". " + buf;
        err = new Error(msg);
        return cb(err, data, res);
      }
      return cb(null, data, res);
    };

    return Airbud;

  })();

  module.exports = Airbud;

}).call(this);
<|endoftext|>


<commit_before>$(document).ready(function() {

  module("underscore.object.builders");

  test("", function() {
  });
});
<commit_msg>Added tests for merge<commit_after>$(document).ready(function() {

  module("underscore.object.builders");

  test("merge", function() {
    var o = {'a': 1, 'b': 2};

    deepEqual(_.merge(o), {a: 1, b: 2}, 'should return a copy of the object if given only one');
    deepEqual(_.merge({'a': 1, 'b': 2}, {b: 42}), {'a': 1, b: 42}, 'should merge two objects');
    deepEqual(_.merge({a: 1, b: 2}, {b: 42}, {c: 3}), {a: 1, b: 42, c: 3}, 'should merge three or more objects');
    deepEqual(_.merge({a: 1, b: 2}, {b: 42}, {c: 3}, {c: 4}), {a: 1, b: 42, c: 4}, 'should merge three or more objects');

    var a = {'a': 1, 'b': 2};
    var $ = _.merge(a, {'a': 42});

    deepEqual(a, {'a': 1, 'b': 2}, 'should not modify the original');
  });
});
<|endoftext|>