<commit_before>define(['reqanim', 'grid', 'zepto', 'entityFactory', 'moment', 'canvas', 'projectFactory'],
  function(AnimationFrame, Grid, $, EntityFactory, moment, Canvas, ProjectFactory) {

	/**
	 *
	 *
	 */
	var Game = function() {

    // self
    var self = this;

    // If game is running
    this.isRunning = false;

  	// Sounds
  	this.clicksound = new Audio('audio/click.ogg');
  	this.register = new Audio('audio/register.ogg');
  	this.notifysound = new Audio('audio/notify.ogg');
  	this.slapsound = new Audio('audio/Slap.ogg');
	this.keyboardsound = new Audio('audio/keyboard.ogg');
	this.playKeyboardsound = 0;

    // Projects..
    this.projectFactory = new ProjectFactory();

    // Gameplay related settings
    this.gameplay = {
      money: 30000,
	  losecondition: -10000,
	  progress: 0,
      time: new Date(1970,01,01).getMilliseconds(),
      project: this.projectFactory.getProject(),
      costs: {
        coder: 5000,
        cleaner: 2500,
        manager: 25000,
        cook: 3500,
        buyFloor: 150000
      },
      // our entities holder per office floors
      floors: {
        1: {
          coder: {
          },
          cleaner: {
          },
          manager: {
          },
          cook: {
          }
        }
      },
      // floor player is viewing
      currentFloor: 1,
      selectedEntity: null
    };

    // Entity factory
    this.entityFactory = new EntityFactory(this.gameplay);

    // Canvas
    this.canvas = new Canvas(this.gameplay);

    // Ui elements
    this.ui = {
      // Overall
      money: $('#money'),
      time: $('#time p'),
      project: $('#project'),
      notification: $('#notification'),
      // Persons
      coder: $('#coder'),
      cleaner: $('#cleaner'),
      manager: $('#manager'),
      cook: $('#cook'),
      // Floor
      buyFloor: $('#buy-floor'),
      // Canvas
      canvas: $('#drawable-canvas'),
      // Prices
      coderPrice: $('#coder').find('.price'),
      cleanerPrice: $('#cleaner').find('.price'),
      managerPrice: $('#manager').find('.price'),
      cookPrice: $('#cook').find('.price'),
      buyFloorPrice: $('#buy-floor').find('.price'),
      // Person area of selections
      personArea: $('.person-area'),
      // Screens
      startScreen: $('#start-screen'),
      // Buttons
      slap: $('#slap'),
      toilet: $('#toilet'),
      feed: $('#feed')
    };

    /**
     * Binding click events
     *
     */
    // Professions..
    $(".profession").click(function(e) {

      if(self.isRunning) {

        var type = $(this).attr('id');

        if(type !== "cook" || type !== "cleaner") {

           self.clicksound.currentTime = 0;
          self.clicksound.play();
          self.addEntity(type);

        }

      }

    });

    // Buttons..
    $(".action").click(function(e) {

      if(self.isRunning) {

        var type = $(this).attr('id');

        self.actionClick(type);

      }

    });

    // New floor..
    this.ui.buyFloor.click(function(e) {

      alert("Get early access from steam... seriously, gamejams?");

    });

    // Click canvas
    this.ui.canvas.click(function(e) {

      if(self.isRunning === false) {

        self.ui.startScreen.hide();
        self.isRunning = true;

      }

      if(self.isRunning) {

        var x = Math.floor((e.pageX-$(this).offset().left) / 64),
            y = Math.floor((e.pageY-$(this).offset().top) / 48);

        self.onClick(x, y);

      }

    });

  };

  Game.prototype.actionClick = function(type) {

    if(this.gameplay.selectedEntity != null) {

      var beforeState = this.gameplay.selectedEntity.stateCurrent;

      if(type === "slap") {

        this.gameplay.selectedEntity.slap();

        if(beforeState !== this.gameplay.selectedEntity.stateCurrent) {
          this.slapsound.currentTime = 0;
          this.slapsound.play();
        } else {
          this.clicksound.currentTime = 0;
          this.clicksound.play();
        }

      } else if(type === "feed") {

        this.gameplay.selectedEntity.feed();

        this.clicksound.currentTime = 0;
        this.clicksound.play();

      } else if(type === "toilet") {

        this.gameplay.selectedEntity.toilet();

        this.clicksound.currentTime = 0;
        this.clicksound.play();

      } else if(type === "meet") {

        // we select maximum of 5 people for meeting...
        var selections = [];

        // if at least one need meeting..
        for(var key in this.gameplay.floors[this.gameplay.currentFloor]["coder"]) {

          if(this.gameplay.floors[this.gameplay.currentFloor]["coder"][key].stateCurrent === "talking") {

            selections.push(this.gameplay.floors[this.gameplay.currentFloor]["coder"][key].x + "," + this.gameplay.floors[this.gameplay.currentFloor]["coder"][key].y);

          }

        }

        if(selections.length > 0) {

          if(this.gameplay.selectedEntity.meetings === 0) {
            this.notify("Manager says: My calendar is full for the rest of the year, no more meetings!");
          } else {

            this.gameplay.selectedEntity.meet();

            for(var yy = 0; yy < selections.length; yy++) {

              this.gameplay.floors[this.gameplay.currentFloor]["coder"][selections[yy]].meet();

            }

          }

        }

        this.clicksound.currentTime = 0;
        this.clicksound.play();

      }

      if(beforeState !== this.gameplay.selectedEntity.stateCurrent) {

         // if meeting started...
         if(this.gameplay.selectedEntity.type === "manager") {

          this.notify("Manager says: EVERYBODY, lets have a meeting, im lonely.");

         }

         this.clearSelections();
      }

      return;

    }

    this.clearSelections();

  };

  /**
   * On canvas click...
   *
   */
  Game.prototype.onClick = function(x, y) {

    var isFound = false;

    for(var type in this.gameplay.floors[this.gameplay.currentFloor]) {

      if(type === "coder") {

        // Converting to possible coder coordinates...
        var person = this.gameplay.floors[this.gameplay.currentFloor][type][(x-4) + "," + y];

        if(typeof person !== "undefined" && person.stateCurrent !== "walking") {
          this.selectEntity(this.gameplay.floors[this.gameplay.currentFloor][type][(x-4) + "," + y]);
          isFound = true;
          break;
        }

      } else if(type === "manager") {

        // Converting to possible manager coordinates...
        var manager = this.gameplay.floors[this.gameplay.currentFloor][type][x + "," + (y-9)];

        if(typeof manager !== "undefined") {
          this.selectEntity(this.gameplay.floors[this.gameplay.currentFloor][type][x + "," + (y-9)]);
          isFound = true;
          break;
        }

      }

    }

    if(isFound === false) {
      this.clearSelections();
    }

  };

  /**
   * Called when entity clicked on canvas
   *
   */
  Game.prototype.selectEntity = function(entity) {

    // If selected same again... just go away..
    if(this.gameplay.selectedEntity != null &&
      this.gameplay.selectedEntity.x === entity.x &&
      this.gameplay.selectedEntity.y === entity.y) {
      // Clear selections..
      this.clearSelections();
      return;
    }

    // Clear previous
    this.clearSelections();

    // Show correct view...
    if(entity.type === "coder") {
      $('#person-' + entity.type).find('.person img').attr("src", "/images/" + entity.stateCurrent + ".png");
    }

    $('#person-' + entity.type).removeClass('hidden');
    this.gameplay.selectedEntity = entity;

  };

  /**
   * Called when UI selections needs to be toggled away.. (e.g. floor change)
   *
   */
  Game.prototype.clearSelections = function() {

    // Setting UI to default hidden state
    this.ui.personArea.addClass("hidden");

    if(this.gameplay.selectedEntity != null && this.gameplay.selectedEntity.type === "coder") {
      $('#person-coder').find('.person img').attr("src", "/images/normal.png");
    }

    this.gameplay.selectedEntity = null;

  };

  /**
   *
   *
   */
  Game.prototype.addEntity = function(type) {

    var result = this.entityFactory.getFactory(type).addEntity();

    if(result.error) {

      this.notify(result.error);

      return;

    }

  	// Entity added, play sound!
  	this.register.currentTime = 0;
  	this.register.play();

  };

  /**
   *
   *
   */
  Game.prototype.notify = function(text) {
    $('#notification span').animate({
          opacity: 0
        }, 150, 'linear', function() {
          $(this).text(text).css({ opacity: 1 });
    });
  	this.notifysound.currentTime = 0;
  	this.notifysound.play();
  };

  /**
   *
   *
   */
  Game.prototype.removeEntity = function(type, entity) {
    /* */
  };

	/**
	 *
	 *
	 */
	Game.prototype.init = function() {

		console.log("Game init..");

    var self = this;

    // Updating DOM before waiting rest to be loaded...
    this.ui.coderPrice.text(this.gameplay.costs.coder);
    this.ui.cleanerPrice.text(this.gameplay.costs.cleaner);
    this.ui.managerPrice.text(this.gameplay.costs.manager);
    this.ui.cookPrice.text(this.gameplay.costs.cook);
    this.ui.buyFloorPrice.text(this.gameplay.costs.buyFloor);
    this.refreshUI();

    // Init tile factory... block until finished
    this.entityFactory.init(function(err) {

      if(err) return alert(err);

      // FPS 30
  		var animFrame = new AnimationFrame(30),

  			// Game loop specifics
  			now = 0,
  			then = 0,
  			sub = 0,
  			dt = 0.0;

      // console.log("Testing Grid functionality");

      // self.testGrid();

  		/**
  		 * "The" loop
  		 *
  		 */
  		var loop = function() {

        if(self.isRunning) {

          // delta time (now)
          now = Date.now();
          sub = now - then;
          dt = sub / 1000;

          // draw
          self.draw();

          // update
          self.update(dt);

          // delta time (then)
          then = now;

        }

        // request next frame
        animFrame.request(loop);

  		};

  		loop();

    });

	};

	/**
	 *
	 *
	 */
	Game.prototype.draw = function() {

    this.refreshUI();
    this.canvas.draw();

	};

	/**
	 *
	 *
	 */
	Game.prototype.update = function(dt) {

    this.gameplay.time += 10000;

	//RELATED TO KEYBOARDSOUNDS
	if (this.playKeyboardsound>0) {
		if (typeof this.keyboardsound.loop == 'boolean')
		{
			this.keyboardsound.loop = true;
		}
		else
		{
			this.keyboardsound.addEventListener('ended', function() {
				this.currentTime = 0;
				this.play();
			}, false);
		}
		this.keyboardsound.play();
	} else {
		this.keyboardsound.pause();
	}
	// NO LONGER AT THIS POINT RELATED TO KEYBOARD SOUNDS

    // Update all entities
	this.canvas.update();

	this.gameplay.money -= 1;

	// PLAYING KEYBOARD SOUNDS & UPDATING MONEY + PROGRESS
	for(var type in this.gameplay.floors[this.gameplay.currentFloor]) {

	      if(type === "coder") {

	        for(var key in this.gameplay.floors[this.gameplay.currentFloor][type]) {

	          if (this.gameplay.floors[this.gameplay.currentFloor][type][key].stateCurrent === "normal"){
				this.playKeyboardsound = 1;
				break;
			  } else {
			  this.playKeyboardsound = 0;
			  }

	      }
		   for(var key in this.gameplay.floors[this.gameplay.currentFloor][type]) {
				if (this.gameplay.floors[this.gameplay.currentFloor][type][key].stateCurrent === "normal"){
					this.gameplay.money += 7;
					this.gameplay.progress += 1;
					if (this.gameplay.progress === 5000) {
						this.notify("Project Completed: gained 10000 money!");
						this.gameplay.project= this.projectFactory.getProject();
						this.gameplay.progress = 0;
						this.gameplay.money += 10000;
					}
				}
			}
		  if (Object.keys(this.gameplay.floors[this.gameplay.currentFloor]["coder"]).length>0){
			this.gameplay.money -= (Object.keys(this.gameplay.floors[this.gameplay.currentFloor]["coder"]).length)*5;
			if (this.gameplay.money<this.gameplay.losecondition) {
				this.isRunning = false;
				alert("YOU LOSE! YOU'RE A FAILURE EVEN IN THIS STUPID BUSINESS!");
			}
		  }
	      break;

	    }

		}
	};
	// DONE PLAYING KEYBOARD SOUNDS & UPDATING MONEY + PROGRESS

  /**
   * Method for updating UI element states
   *
   */
  Game.prototype.refreshUI = function() {

    this.ui.money.text(this.gameplay.money);
    this.ui.time.text(moment(new Date(this.gameplay.time)).format('MMMM Do YYYY, h:mm:ss a'));
    this.ui.project.text(this.gameplay.project);

  };

	Game.prototype.testGrid = function() {

		var kentta = new Grid( { size: 5 });
		kentta.testGrid();
	};

	return Game;

});
<commit_msg>bit shorter projects<commit_after>define(['reqanim', 'grid', 'zepto', 'entityFactory', 'moment', 'canvas', 'projectFactory'],
  function(AnimationFrame, Grid, $, EntityFactory, moment, Canvas, ProjectFactory) {

	/**
	 *
	 *
	 */
	var Game = function() {

    // self
    var self = this;

    // If game is running
    this.isRunning = false;

  	// Sounds
  	this.clicksound = new Audio('audio/click.ogg');
  	this.register = new Audio('audio/register.ogg');
  	this.notifysound = new Audio('audio/notify.ogg');
  	this.slapsound = new Audio('audio/Slap.ogg');
	this.keyboardsound = new Audio('audio/keyboard.ogg');
	this.playKeyboardsound = 0;

    // Projects..
    this.projectFactory = new ProjectFactory();

    // Gameplay related settings
    this.gameplay = {
      money: 30000,
	  losecondition: -10000,
	  progress: 0,
      time: new Date(1970,01,01).getMilliseconds(),
      project: this.projectFactory.getProject(),
      costs: {
        coder: 5000,
        cleaner: 2500,
        manager: 25000,
        cook: 3500,
        buyFloor: 150000
      },
      // our entities holder per office floors
      floors: {
        1: {
          coder: {
          },
          cleaner: {
          },
          manager: {
          },
          cook: {
          }
        }
      },
      // floor player is viewing
      currentFloor: 1,
      selectedEntity: null
    };

    // Entity factory
    this.entityFactory = new EntityFactory(this.gameplay);

    // Canvas
    this.canvas = new Canvas(this.gameplay);

    // Ui elements
    this.ui = {
      // Overall
      money: $('#money'),
      time: $('#time p'),
      project: $('#project'),
      notification: $('#notification'),
      // Persons
      coder: $('#coder'),
      cleaner: $('#cleaner'),
      manager: $('#manager'),
      cook: $('#cook'),
      // Floor
      buyFloor: $('#buy-floor'),
      // Canvas
      canvas: $('#drawable-canvas'),
      // Prices
      coderPrice: $('#coder').find('.price'),
      cleanerPrice: $('#cleaner').find('.price'),
      managerPrice: $('#manager').find('.price'),
      cookPrice: $('#cook').find('.price'),
      buyFloorPrice: $('#buy-floor').find('.price'),
      // Person area of selections
      personArea: $('.person-area'),
      // Screens
      startScreen: $('#start-screen'),
      // Buttons
      slap: $('#slap'),
      toilet: $('#toilet'),
      feed: $('#feed')
    };

    /**
     * Binding click events
     *
     */
    // Professions..
    $(".profession").click(function(e) {

      if(self.isRunning) {

        var type = $(this).attr('id');

        if(type !== "cook" || type !== "cleaner") {

           self.clicksound.currentTime = 0;
          self.clicksound.play();
          self.addEntity(type);

        }

      }

    });

    // Buttons..
    $(".action").click(function(e) {

      if(self.isRunning) {

        var type = $(this).attr('id');

        self.actionClick(type);

      }

    });

    // New floor..
    this.ui.buyFloor.click(function(e) {

      alert("Get early access from steam... seriously, gamejams?");

    });

    // Click canvas
    this.ui.canvas.click(function(e) {

      if(self.isRunning === false) {

        self.ui.startScreen.hide();
        self.isRunning = true;

      }

      if(self.isRunning) {

        var x = Math.floor((e.pageX-$(this).offset().left) / 64),
            y = Math.floor((e.pageY-$(this).offset().top) / 48);

        self.onClick(x, y);

      }

    });

  };

  Game.prototype.actionClick = function(type) {

    if(this.gameplay.selectedEntity != null) {

      var beforeState = this.gameplay.selectedEntity.stateCurrent;

      if(type === "slap") {

        this.gameplay.selectedEntity.slap();

        if(beforeState !== this.gameplay.selectedEntity.stateCurrent) {
          this.slapsound.currentTime = 0;
          this.slapsound.play();
        } else {
          this.clicksound.currentTime = 0;
          this.clicksound.play();
        }

      } else if(type === "feed") {

        this.gameplay.selectedEntity.feed();

        this.clicksound.currentTime = 0;
        this.clicksound.play();

      } else if(type === "toilet") {

        this.gameplay.selectedEntity.toilet();

        this.clicksound.currentTime = 0;
        this.clicksound.play();

      } else if(type === "meet") {

        // we select maximum of 5 people for meeting...
        var selections = [];

        // if at least one need meeting..
        for(var key in this.gameplay.floors[this.gameplay.currentFloor]["coder"]) {

          if(this.gameplay.floors[this.gameplay.currentFloor]["coder"][key].stateCurrent === "talking") {

            selections.push(this.gameplay.floors[this.gameplay.currentFloor]["coder"][key].x + "," + this.gameplay.floors[this.gameplay.currentFloor]["coder"][key].y);

          }

        }

        if(selections.length > 0) {

          if(this.gameplay.selectedEntity.meetings === 0) {
            this.notify("Manager says: My calendar is full for the rest of the year, no more meetings!");
          } else {

            this.gameplay.selectedEntity.meet();

            for(var yy = 0; yy < selections.length; yy++) {

              this.gameplay.floors[this.gameplay.currentFloor]["coder"][selections[yy]].meet();

            }

          }

        }

        this.clicksound.currentTime = 0;
        this.clicksound.play();

      }

      if(beforeState !== this.gameplay.selectedEntity.stateCurrent) {

         // if meeting started...
         if(this.gameplay.selectedEntity.type === "manager") {

          this.notify("Manager says: EVERYBODY, lets have a meeting, im lonely.");

         }

         this.clearSelections();
      }

      return;

    }

    this.clearSelections();

  };

  /**
   * On canvas click...
   *
   */
  Game.prototype.onClick = function(x, y) {

    var isFound = false;

    for(var type in this.gameplay.floors[this.gameplay.currentFloor]) {

      if(type === "coder") {

        // Converting to possible coder coordinates...
        var person = this.gameplay.floors[this.gameplay.currentFloor][type][(x-4) + "," + y];

        if(typeof person !== "undefined" && person.stateCurrent !== "walking") {
          this.selectEntity(this.gameplay.floors[this.gameplay.currentFloor][type][(x-4) + "," + y]);
          isFound = true;
          break;
        }

      } else if(type === "manager") {

        // Converting to possible manager coordinates...
        var manager = this.gameplay.floors[this.gameplay.currentFloor][type][x + "," + (y-9)];

        if(typeof manager !== "undefined") {
          this.selectEntity(this.gameplay.floors[this.gameplay.currentFloor][type][x + "," + (y-9)]);
          isFound = true;
          break;
        }

      }

    }

    if(isFound === false) {
      this.clearSelections();
    }

  };

  /**
   * Called when entity clicked on canvas
   *
   */
  Game.prototype.selectEntity = function(entity) {

    // If selected same again... just go away..
    if(this.gameplay.selectedEntity != null &&
      this.gameplay.selectedEntity.x === entity.x &&
      this.gameplay.selectedEntity.y === entity.y) {
      // Clear selections..
      this.clearSelections();
      return;
    }

    // Clear previous
    this.clearSelections();

    // Show correct view...
    if(entity.type === "coder") {
      $('#person-' + entity.type).find('.person img').attr("src", "/images/" + entity.stateCurrent + ".png");
    }

    $('#person-' + entity.type).removeClass('hidden');
    this.gameplay.selectedEntity = entity;

  };

  /**
   * Called when UI selections needs to be toggled away.. (e.g. floor change)
   *
   */
  Game.prototype.clearSelections = function() {

    // Setting UI to default hidden state
    this.ui.personArea.addClass("hidden");

    if(this.gameplay.selectedEntity != null && this.gameplay.selectedEntity.type === "coder") {
      $('#person-coder').find('.person img').attr("src", "/images/normal.png");
    }

    this.gameplay.selectedEntity = null;

  };

  /**
   *
   *
   */
  Game.prototype.addEntity = function(type) {

    var result = this.entityFactory.getFactory(type).addEntity();

    if(result.error) {

      this.notify(result.error);

      return;

    }

  	// Entity added, play sound!
  	this.register.currentTime = 0;
  	this.register.play();

  };

  /**
   *
   *
   */
  Game.prototype.notify = function(text) {
    $('#notification span').animate({
          opacity: 0
        }, 150, 'linear', function() {
          $(this).text(text).css({ opacity: 1 });
    });
  	this.notifysound.currentTime = 0;
  	this.notifysound.play();
  };

  /**
   *
   *
   */
  Game.prototype.removeEntity = function(type, entity) {
    /* */
  };

	/**
	 *
	 *
	 */
	Game.prototype.init = function() {

		console.log("Game init..");

    var self = this;

    // Updating DOM before waiting rest to be loaded...
    this.ui.coderPrice.text(this.gameplay.costs.coder);
    this.ui.cleanerPrice.text(this.gameplay.costs.cleaner);
    this.ui.managerPrice.text(this.gameplay.costs.manager);
    this.ui.cookPrice.text(this.gameplay.costs.cook);
    this.ui.buyFloorPrice.text(this.gameplay.costs.buyFloor);
    this.refreshUI();

    // Init tile factory... block until finished
    this.entityFactory.init(function(err) {

      if(err) return alert(err);

      // FPS 30
  		var animFrame = new AnimationFrame(30),

  			// Game loop specifics
  			now = 0,
  			then = 0,
  			sub = 0,
  			dt = 0.0;

      // console.log("Testing Grid functionality");

      // self.testGrid();

  		/**
  		 * "The" loop
  		 *
  		 */
  		var loop = function() {

        if(self.isRunning) {

          // delta time (now)
          now = Date.now();
          sub = now - then;
          dt = sub / 1000;

          // draw
          self.draw();

          // update
          self.update(dt);

          // delta time (then)
          then = now;

        }

        // request next frame
        animFrame.request(loop);

  		};

  		loop();

    });

	};

	/**
	 *
	 *
	 */
	Game.prototype.draw = function() {

    this.refreshUI();
    this.canvas.draw();

	};

	/**
	 *
	 *
	 */
	Game.prototype.update = function(dt) {

    this.gameplay.time += 10000;

	//RELATED TO KEYBOARDSOUNDS
	if (this.playKeyboardsound>0) {
		if (typeof this.keyboardsound.loop == 'boolean')
		{
			this.keyboardsound.loop = true;
		}
		else
		{
			this.keyboardsound.addEventListener('ended', function() {
				this.currentTime = 0;
				this.play();
			}, false);
		}
		this.keyboardsound.play();
	} else {
		this.keyboardsound.pause();
	}
	// NO LONGER AT THIS POINT RELATED TO KEYBOARD SOUNDS

    // Update all entities
	this.canvas.update();

	this.gameplay.money -= 1;

	// PLAYING KEYBOARD SOUNDS & UPDATING MONEY + PROGRESS
	for(var type in this.gameplay.floors[this.gameplay.currentFloor]) {

	      if(type === "coder") {

	        for(var key in this.gameplay.floors[this.gameplay.currentFloor][type]) {

	          if (this.gameplay.floors[this.gameplay.currentFloor][type][key].stateCurrent === "normal"){
				this.playKeyboardsound = 1;
				break;
			  } else {
			  this.playKeyboardsound = 0;
			  }

	      }
		   for(var key in this.gameplay.floors[this.gameplay.currentFloor][type]) {
				if (this.gameplay.floors[this.gameplay.currentFloor][type][key].stateCurrent === "normal"){
					this.gameplay.money += 7;
					this.gameplay.progress += 1;
					if (this.gameplay.progress === 3000) {
						this.notify("Project Completed: gained 10000 money!");
						this.gameplay.project= this.projectFactory.getProject();
						this.gameplay.progress = 0;
						this.gameplay.money += 10000;
					}
				}
			}
		  if (Object.keys(this.gameplay.floors[this.gameplay.currentFloor]["coder"]).length>0){
			this.gameplay.money -= (Object.keys(this.gameplay.floors[this.gameplay.currentFloor]["coder"]).length)*5;
			if (this.gameplay.money<this.gameplay.losecondition) {
				this.isRunning = false;
				alert("YOU LOSE! YOU'RE A FAILURE EVEN IN THIS STUPID BUSINESS!");
			}
		  }
	      break;

	    }

		}
	};
	// DONE PLAYING KEYBOARD SOUNDS & UPDATING MONEY + PROGRESS

  /**
   * Method for updating UI element states
   *
   */
  Game.prototype.refreshUI = function() {

    this.ui.money.text(this.gameplay.money);
    this.ui.time.text(moment(new Date(this.gameplay.time)).format('MMMM Do YYYY, h:mm:ss a'));
    this.ui.project.text(this.gameplay.project);

  };

	Game.prototype.testGrid = function() {

		var kentta = new Grid( { size: 5 });
		kentta.testGrid();
	};

	return Game;

});
<|endoftext|>


<commit_before>var socket = io.connect('', {
  'connect timeout': 1000
});

var model = {
  'message': ko.observable(),
  'siteshotUrl': ko.observable(),
  'imageUrl': ko.observable(false),
  'locked': ko.observable(false),
}

model.siteshotUrl.subscribe(function(newUrl){
  console.log('Changed', newUrl);
  if(newUrl){
    socket.emit('siteshot', newUrl);
  } else {
    model.message('Enter URL...');
  }
});

ko.applyBindings(model);

socket.on('siteshotResult', function(data){
  console.log(data);
  model.locked(data.locked);
  model.message(data.message);
  model.imageUrl(data.imageUrl);
});<commit_msg>do not spam in console<commit_after>var socket = io.connect('', {
  'connect timeout': 1000
});

var model = {
  'message': ko.observable(),
  'siteshotUrl': ko.observable(),
  'imageUrl': ko.observable(false),
  'locked': ko.observable(false),
}

model.siteshotUrl.subscribe(function(newUrl){
  if(newUrl){
    socket.emit('siteshot', newUrl);
  } else {
    model.message('Enter URL...');
  }
});

ko.applyBindings(model);

socket.on('siteshotResult', function(data){
  model.locked(data.locked);
  model.message(data.message);
  model.imageUrl(data.imageUrl);
});<|endoftext|>


<commit_before>var socket = io.connect(window.location.href);

$(document).ready(function() {

  $('#song-count').text($('.track').length + ' tracks')

  // Get total time
  var total = 0;
  $('.time').each(function(index) {
    total += $(this).data('time');
  });
  var time = moment.duration({s: total });
  var hours = ' hours ';
  var minutes = ' minutes';

  if (time.hours() === 1) hours = ' hour ';
  if (time.minutes() === 1) minutes = ' minute';

  $('#total-time').text(time.hours() + hours + time.minutes() + minutes);

  socket.on('connect', function() {
    if (localStorage.getItem('isHost')) {
      socket.emit('hostComeback', this.socket.sessionid);
      socket.emit('checkIfHost', this.socket.sessionid);
    }

    socket.emit('checkIfHost', this.socket.sessionid);
    socket.on('checkIfHostAnswer', function(isHost) {
      if (!isHost) {
        console.log('You are not a host');
        $('#play').unbind('click');
        $('.track').unbind('dblclick');
        $('#pause').unbind('click');
        $('#forward').unbind('click');
        $('#backward').unbind('click');
        $('.guest-mode').show();
      } else {
        console.log('Yes you are a host');
        $('.host-mode').show();
        localStorage.setItem('isHost', true);

        // If host, set localstorage variable isHost = true
        // When disconnected, check on server if host is disconnected.
        // If it is, create a 60 sec timeout, after which hostId is next socket in line
        // If host comes back within 60 sec, clear the timeout

      }
    });

  });

});<commit_msg>Latency-handling socket event<commit_after>var socket = io.connect(window.location.href);

$(document).ready(function() {

  $('#song-count').text($('.track').length + ' tracks')

  // Get total time
  var total = 0;
  $('.time').each(function(index) {
    total += $(this).data('time');
  });
  var time = moment.duration({s: total });
  var hours = ' hours ';
  var minutes = ' minutes';

  if (time.hours() === 1) hours = ' hour ';
  if (time.minutes() === 1) minutes = ' minute';

  $('#total-time').text(time.hours() + hours + time.minutes() + minutes);

  socket.on('connect', function() {
    if (localStorage.getItem('isHost')) {
      socket.emit('hostComeback', this.socket.sessionid);
      socket.emit('checkIfHost', this.socket.sessionid);
    }

    socket.emit('checkIfHost', this.socket.sessionid);
    socket.on('checkIfHostAnswer', function(isHost) {
      if (!isHost) {
        console.log('You are not a host');
        $('#play').unbind('click');
        $('.track').unbind('dblclick');
        $('#pause').unbind('click');
        $('#forward').unbind('click');
        $('#backward').unbind('click');
        $('.guest-mode').show();
      } else {
        console.log('Yes you are a host');
        $('.host-mode').show();
        localStorage.setItem('isHost', true);

        // If host, set localstorage variable isHost = true
        // When disconnected, check on server if host is disconnected.
        // If it is, create a 60 sec timeout, after which hostId is next socket in line
        // If host comes back within 60 sec, clear the timeout

      }
    });

  });

  var latency;
  var latencyInterval;
  var isPlaying = false;
  var startTime;

  socket.on('pong', function() {
    latency = Date.now() - startTime;
  });

});<|endoftext|>


<commit_before>var op_watch = null;
function op(city, tag, title, focii, architect, atype, body, x){
  var result = Resource.add_or_update(tag, {
    city_id: city,
    title: title,
    focii: focii,
    architect: architect,
    atype: atype,
    body: body
  }, x);
  if (tag == op_watch) {
    go('@' + tag);
    op_watch = null;
  }
}

Ops = new Resource('Op', {
  enhancer: function(x){
    x.children = [];
    x.site = x.focii && x.focii.split(' ')[0];
    x.thumb_url = x.site && x.site.resource() && x.site.resource().thumb_url;
  }
});

Operation = {

  exec: function(script, players, location, callback) {
    var params = {
      channel: 'noho',
      script:  script,
      items:   players.replace(/Person__/g, '')
    };

    if (test) return alert("CEML exec: " + $.param(params));

    $.get('/api/exec', params, function(optag){
      op_watch = optag;
      Ajax.autoload(callback);
    }, 'text');
  },

  // demo mode stuff

  create: function(site, title, atype, body) {
    var optag = "Op__" + Ajax.uuid();
    var city_id = site.resource().city_id;
    return op(city_id, optag, title, site, This.user.tag, atype, body);
  },

  group_assign_demo: function(agents, what, callback) {
    // console.log(agents);
    var op = Operation.create(agents[0], "\""+what+"\"", 'assignment group', what);
    callback(op);

    $.each(agents, function(i, agent){
      var delay = 4000 + Math.rand(10000);
      setTimeout(function(){
        Event.create('accepted', agent, op, {latch: "latched 1-10000 " + op.id + " " + This.user.tag});
      }, delay);
    });
  },

  assign_demo: function(person, assignment, callback) {
    var op = Operation.create(person, "\""+assignment+"\"", 'assignment individual', assignment);
    callback(op);

    setTimeout(function(){
      Event.create('accepted', person, op, {latch: "latched 1-10000 " + op.id + " " + This.user.tag});
    }, 3000);

    setTimeout(function(){
      Event.create('completed', person, op, {latch: "unlatched"});
    }, 15000);

  },

  invite_demo: function(landmark, title, assignment, callback) {
    var op = Operation.create(landmark, "\""+title+"\"", 'assignment invite', title);
    callback(op);

    $.each(Agents.in_city(op.city_id).slice(0, 10), function(i, agent){
      var delay = 2000 + Math.rand(10000);
      setTimeout(function(){
        Event.create('accepted', agent.id, op, {latch: "latched 1-10000 " + op.id + " " + This.user.tag});
      }, delay);
    });
  }  ,

  question_demo: function(question, agents) {
    var op = Operation.create(agents[0], "question: " + question, 'assignment question', question);

    $.each(agents, function(i, agent){
      var delay = 4000 + Math.rand(10000);
      setTimeout(function(){
        Event.create('accepted', agent, op, {latch: "unlatched"}, {msg: "wow, you're a real cool cat"});
      }, delay);
    });
  }

};
<commit_msg>spt for demo questions<commit_after>var op_watch = null;
function op(city, tag, title, focii, architect, atype, body, x){
  var result = Resource.add_or_update(tag, {
    city_id: city,
    title: title,
    focii: focii,
    architect: architect,
    atype: atype,
    body: body
  }, x);
  if (tag == op_watch) {
    go('@' + tag);
    op_watch = null;
  }
  return result;
}

Ops = new Resource('Op', {
  enhancer: function(x){
    x.children = [];
    x.site = x.focii && x.focii.split(' ')[0];
    x.thumb_url = x.site && x.site.resource() && x.site.resource().thumb_url;
  }
});

Operation = {

  exec: function(script, players, location, callback) {
    var params = {
      channel: 'noho',
      script:  script,
      items:   players.replace(/Person__/g, '')
    };

    if (test) return alert("CEML exec: " + $.param(params));

    $.get('/api/exec', params, function(optag){
      op_watch = optag;
      Ajax.autoload(callback);
    }, 'text');
  },

  // demo mode stuff

  create: function(site, title, atype, body) {
    var optag = "Op__" + Ajax.uuid();
    var city_id = site.resource().city_id;
    op_watch = optag;
    return op(city_id, optag, title, site, This.user.tag, atype, body);
  },

  group_assign_demo: function(agents, what, callback) {
    // console.log(agents);
    var op = Operation.create(agents[0], "\""+what+"\"", 'assignment group', what);
    callback(op);

    $.each(agents, function(i, agent){
      var delay = 4000 + Math.rand(10000);
      setTimeout(function(){
        Event.create('accepted', agent, op, {latch: "latched 1-10000 " + op.id + " " + This.user.tag});
      }, delay);
    });
  },

  assign_demo: function(person, assignment, callback) {
    var op = Operation.create(person, "\""+assignment+"\"", 'assignment individual', assignment);
    callback(op);

    setTimeout(function(){
      Event.create('accepted', person, op, {latch: "latched 1-10000 " + op.id + " " + This.user.tag});
    }, 3000);

    setTimeout(function(){
      Event.create('completed', person, op, {latch: "unlatched"});
    }, 15000);

  },

  invite_demo: function(landmark, title, assignment, callback) {
    var op = Operation.create(landmark, "\""+title+"\"", 'assignment invite', title);
    callback(op);

    $.each(Agents.in_city(op.city_id).slice(0, 10), function(i, agent){
      var delay = 2000 + Math.rand(10000);
      setTimeout(function(){
        Event.create('accepted', agent.id, op, {latch: "latched 1-10000 " + op.id + " " + This.user.tag});
      }, delay);
    });
  }  ,

  question_demo: function(question, agents) {
    var op = Operation.create(agents[0], "question: " + question, 'assignment question', question);

    $.each(agents, function(i, agent){
      var delay = 1000 + Math.rand(500);
      setTimeout(function(){
        Event.create('responded', agent, op, {latch: "unlatched"}, {msg: "wow, you're a real cool cat"});
      }, delay);
    });
  }

};
<|endoftext|>


<commit_before>
'use strict';

/**
 * This file has detailed comments as to the usage of these strings so when
 * translators work on these strings separately from the code, (but with the
 * comments) they have something to work on.
 * Each string should be commented using single-line comments.
 */
var i18n = {
  root: {
    // This message is used to describe any command or command parameter when
    // no description has been provided.
    canonDescNone: '(No description)',

    // The default name for a group of parameters.
    canonDefaultGroupName: 'Options',

    // These commands are used to execute commands on a remote system (using a
    // proxy). Parameters: %S is the name of the remote system.
    canonProxyDesc: 'Execute a command on %S',
    canonProxyManual: 'A set of commands that are executed on a remote system. The remote system is reached via %S',

    // This error message is displayed when we try to add a new command (using
    // a proxy) where one already exists with the same name.
    canonProxyExists: 'There is already a command called \'%S\'',

    // This message describes the '{' command, which allows entry of JavaScript
    // like traditional developer tool command lines.
    cliEvalJavascript: 'Enter JavaScript directly',

    // This message is displayed when the command line has more arguments than
    // the current command can understand.
    cliUnusedArg: 'Too many arguments',

    // The title of the dialog which displays the options that are available
    // to the current command.
    cliOptions: 'Available Options',

    // The error message when the user types a command that isn't registered
    cliUnknownCommand: 'Invalid Command',

    // A parameter should have a value, but doesn't
    cliIncompleteParam: 'Value required for \'%1$S\'.',

    // Error message given when a file argument points to a file that does not
    // exist, but should (e.g. for use with File->Open)
    // %1$S is a filename
    fileErrNotExists: '\'%1$S\' doesn\'t exist',

    // Error message given when a file argument points to a file that exists,
    // but should not (e.g. for use with File->Save As)
    // %1$S is a filename
    fileErrExists: '\'%1$S\' already exists',

    // Error message given when a file argument points to a non-file, when a
    // file is needed. %1$S is a filename
    fileErrIsNotFile: '\'%1$S\' is not a file',

    // Error message given when a file argument points to a non-directory,
    // when a directory is needed (e.g. for use with 'cd')
    // %1$S is a filename
    fileErrIsNotDirectory: '\'%1$S\' is not a directory',

    // Error message given when a file argument does not match the specified
    // regular expression
    // %1$S is a filename
    // %2$S is a regular expression
    fileErrDoesntMatch: '\'%1$S\' does not match \'%2$S\'',

    // When a command has a parameter that has a number of pre-defined options
    // the user interface presents these in a drop-down menu, where the first
    // 'option' is an indicator that a selection should be made. This string
    // describes that first option.
    fieldSelectionSelect: 'Select a %S…',

    // When a command has a parameter that can be repeated multiple times (e.g.
    // like the 'cat a.txt b.txt' command) the user interface presents buttons
    // to add and remove arguments. This string is used to add arguments.
    fieldArrayAdd: 'Add',
    fieldArrayDel: 'Delete',

    // When the menu has displayed all the matches that it should (i.e. about
    // 10 items) then we display this to alert the user that more matches are
    // available.
    fieldMenuMore: 'More matches, keep typing',

    // The command line provides completion for JavaScript commands, however
    // there are times when the scope of what we're completing against can't
    // be used. This error message is displayed when this happens.
    jstypeParseScope: 'Scope lost',

    // These error messages are displayed when the command line is doing
    // JavaScript completion and encounters errors.
    jstypeParseMissing: 'Can\'t find property \'%S\'',
    jstypeBeginSyntax: 'Syntax error',
    jstypeBeginUnterm: 'Unterminated string literal',

    // This message is displayed if the system for providing JavaScript
    // completions encounters and error it displays this.
    jstypeParseError: 'Error',

    // These error messages are displayed when the command line is passed a
    // variable which has the wrong format and can't be converted.
    // Parameters: %S is the passed variable.
    typesNumberNan: 'Can\'t convert "%S" to a number.',
    typesNumberNotInt2: 'Can\'t convert "%S" to an integer.',
    typesDateNan: 'Can\'t convert "%S" to a date.',

    // These error messages are displayed when the command line is passed a
    // variable which has a value out of range (number or date).
    // Parameters: %1$S is the passed variable, %2$S is the limit value.
    typesNumberMax: '%1$S is greater than maximum allowed: %2$S.',
    typesNumberMin: '%1$S is smaller than minimum allowed: %2$S.',
    typesDateMax: '%1$S is later than maximum allowed: %2$S.',
    typesDateMin: '%1$S is earlier than minimum allowed: %2$S.',

    // This error message is displayed when the command line is passed an
    // option with a limited number of correct values, but the passed value is
    // not one of them.
    typesSelectionNomatch: 'Can\'t use \'%S\'.',

    // This error message is displayed when the command line is expecting a CSS
    // query string, however the passed string is not valid.
    nodeParseSyntax: 'Syntax error in CSS query',

    // These error messages are displayed when the command line is expecting a
    // CSS string that matches a single node, but more nodes (or none) match.
    nodeParseMultiple: 'Too many matches (%S)',
    nodeParseNone: 'No matches',

    // These strings describe the "help" command, used to display a description
    // of a command (e.g. "help pref"), and its parameter 'search'.
    helpDesc: 'Get help on the available commands',
    helpManual: 'Provide help either on a specific command (if a search string is provided and an exact match is found) or on the available commands (if a search string is not provided, or if no exact match is found).',
    helpSearchDesc: 'Search string',
    helpSearchManual3: 'search string to use in narrowing down the displayed commands. Regular expressions not supported.',

    // These strings are displayed in the help page for a command in the
    // console.
    helpManSynopsis: 'Synopsis',

    // This message is displayed in the help page if the command has no
    // parameters.
    helpManNone: 'None',

    // This message is displayed in response to the 'help' command when used
    // without a filter, just above the list of known commands.
    helpListAll: 'Available Commands:',

    // These messages are displayed in response to the 'help <search>' command
    // (i.e. with a search string), just above the list of matching commands.
    // Parameters: %S is the search string.
    helpListPrefix: 'Commands starting with \'%S\':',
    helpListNone: 'No commands starting with \'%S\'',

    // When the 'help x' command wants to show the manual for the 'x' command,
    // it needs to be able to describe the parameters as either required or
    // optional, or if they have a default value.
    helpManRequired: 'required',
    helpManOptional: 'optional',
    helpManDefault: 'optional, default=%S',

    // Text shown as part of the output of the 'help' command when the command
    // in question has sub-commands, before a list of the matching sub-commands.
    subCommands: 'Sub-Commands',

    // Text shown as part of the output of the 'help' command when the command
    // in question should have sub-commands but in fact has none.
    subCommandsNone: 'None',

    // These strings are used to describe the 'context' command and its
    // 'prefix' parameter. See localization comment for 'connect' for an
    // explanation about 'prefix'.
    contextDesc: 'Concentrate on a group of commands',
    contextManual: 'Setup a default prefix to future commands. For example \'context git\' would allow you to type \'commit\' rather than \'git commit\'.',
    contextPrefixDesc: 'The command prefix',

    // This message message displayed during the processing of the 'context'
    // command, when the found command is not a parent command.
    contextNotParentError: 'Can\'t use \'%S\' as a prefix because it is not a parent command.',

    // These messages are displayed during the processing of the 'context'
    // command, to indicate success or that there is no command prefix.
    contextReply: 'Using %S as a command prefix',
    contextEmptyReply: 'Command prefix is unset',

    // These strings describe the 'connect' command and all its available
    // parameters. A 'prefix' is an  alias for the remote server (think of it
    // as a "connection name"), and it allows to identify a specific server
    // when connected to multiple remote servers.
    connectDesc: 'Proxy commands to server',
    connectManual: 'Connect to the server, creating local versions of the commands on the server. Remote commands initially have a prefix to distinguish them from local commands (but see the context command to get past this)',
    connectPrefixDesc: 'Parent prefix for imported commands',
    connectPortDesc: 'The TCP port to listen on',
    connectHostDesc: 'The hostname to bind to',
    connectDupReply: 'Connection called %S already exists.',

    // The output of the 'connect' command, telling the user what it has done.
    // Parameters: %S is the prefix command. See localization comment for
    // 'connect' for an explanation about 'prefix'.
    connectReply: 'Added %S commands.',

    // These strings describe the 'disconnect' command and all its available
    // parameters. See localization comment for 'connect' for an explanation
    // about 'prefix'.
    disconnectDesc2: 'Disconnect from server',
    disconnectManual2: 'Disconnect from a server currently connected for remote commands execution',
    disconnectPrefixDesc: 'Parent prefix for imported commands',
    disconnectForceDesc: 'Ignore outstanding requests',

    // This is the output of the 'disconnect' command, explaining the user what
    // has been done. Parameters: %S is the number of commands removed.
    disconnectReply: 'Removed %S commands.',

    // This error message is displayed when the user attempts to disconnect
    // before all requests have completed. Parameters: %S is a list of
    // incomplete requests.
    disconnectOutstanding: 'Outstanding requests (%S)',

    // These strings describe the 'cd' command and it's parameters.
    cdDesc: 'Change working directory',
    cdManual: 'Change the current working directory as used by the exec command',
    cdDirectoryDesc: 'The new working directory',
    cdOutput: 'Working directory is now %S',

    // These strings describe the 'exec' command and it's parameters.
    execDesc: 'Execute a system command',
    execManual: '',
    execCommandDesc: 'The command to execute',

    // These strings describe the 'global' command and its parameters
    globalDesc: 'Change the JS global',
    globalWindowDesc: 'The new window/global',
    globalOutput: 'JS global is now %S',

    // These strings describe the 'pref' command and all its available
    // sub-commands and parameters.
    prefDesc: 'Commands to control settings',
    prefManual: 'Commands to display and alter preferences both for GCLI and the surrounding environment',
    prefListDesc: 'Display available settings',
    prefListManual: 'Display a list of preferences, optionally filtered when using the \'search\' parameter',
    prefListSearchDesc: 'Filter the list of settings displayed',
    prefListSearchManual: 'Search for the given string in the list of available preferences',
    prefShowDesc: 'Display setting value',
    prefShowManual: 'Display the value of a given preference',
    prefShowSettingDesc: 'Setting to display',
    prefShowSettingManual: 'The name of the setting to display',

    // This message is used to show the preference name and the associated
    // preference value. Parameters: %1$S is the preference name, %2$S is the
    // preference value.
    prefShowSettingValue: '%1$S: %2$S',

    // These strings describe the 'pref set' command and all its parameters.
    prefSetDesc: 'Alter a setting',
    prefSetManual: 'Alter preferences defined by the environment',
    prefSetSettingDesc: 'Setting to alter',
    prefSetSettingManual: 'The name of the setting to alter.',
    prefSetValueDesc: 'New value for setting',
    prefSetValueManual: 'The new value for the specified setting',

    // These strings are displayed to the user the first time they try to alter
    // a setting.
    prefSetCheckHeading: 'This might void your warranty!',
    prefSetCheckBody: 'Changing these advanced settings can be harmful to the stability, security, and performance of this application. You should only continue if you are sure of what you are doing.',
    prefSetCheckGo: 'I\'ll be careful, I promise!',

    // These strings describe the 'pref reset' command and all its parameters.
    prefResetDesc: 'Reset a setting',
    prefResetManual: 'Reset the value of a setting to the system defaults',
    prefResetSettingDesc: 'Setting to reset',
    prefResetSettingManual: 'The name of the setting to reset to the system default value',

    // This string is displayed in the output from the 'pref list' command as a
    // label to an input element that allows the user to filter the results.
    prefOutputFilter: 'Filter',

    // These strings are displayed in the output from the 'pref list' command
    // as table headings.
    prefOutputName: 'Name',
    prefOutputValue: 'Value',

    // These strings describe the 'intro' command. The localization of
    // 'Got it!' should be the same used in introTextGo.
    introDesc: 'Show the opening message',
    introManual: 'Redisplay the message that is shown to new users until they click the \'Got it!\' button',

    // These strings are displayed when the user first opens the developer
    // toolbar to explain the command line, and is shown each time it is
    // opened until the user clicks the 'Got it!' button.
    introTextOpening2: 'GCLI is an experiment to create a highly usable command line for web developers.',
    introTextCommands: 'For a list of commands type',
    introTextKeys2: ', or to show/hide command hints press',
    introTextF1Escape: 'F1/Escape',
    introTextGo: 'Got it!',

    // This is a short description of the 'hideIntro' setting.
    hideIntroDesc: 'Show the initial welcome message',

    // This is a description of the 'eagerHelper' setting. It's displayed when
    // the user asks for help on the settings. eagerHelper allows users to
    // select between showing no tooltips, permanent tooltips, and only
    // important tooltips.
    eagerHelperDesc: 'How eager are the tooltips',

    // This is a short description of the 'allowSetDesc' setting.
    allowSetDesc: 'Has the user enabled the \'pref set\' command?'
  }
};

exports.root = i18n.root;
<commit_msg>refactor-864370: Typo fix.<commit_after>
'use strict';

/**
 * This file has detailed comments as to the usage of these strings so when
 * translators work on these strings separately from the code, (but with the
 * comments) they have something to work on.
 * Each string should be commented using single-line comments.
 */
var i18n = {
  root: {
    // This message is used to describe any command or command parameter when
    // no description has been provided.
    canonDescNone: '(No description)',

    // The default name for a group of parameters.
    canonDefaultGroupName: 'Options',

    // These commands are used to execute commands on a remote system (using a
    // proxy). Parameters: %S is the name of the remote system.
    canonProxyDesc: 'Execute a command on %S',
    canonProxyManual: 'A set of commands that are executed on a remote system. The remote system is reached via %S',

    // This error message is displayed when we try to add a new command (using
    // a proxy) where one already exists with the same name.
    canonProxyExists: 'There is already a command called \'%S\'',

    // This message describes the '{' command, which allows entry of JavaScript
    // like traditional developer tool command lines.
    cliEvalJavascript: 'Enter JavaScript directly',

    // This message is displayed when the command line has more arguments than
    // the current command can understand.
    cliUnusedArg: 'Too many arguments',

    // The title of the dialog which displays the options that are available
    // to the current command.
    cliOptions: 'Available Options',

    // The error message when the user types a command that isn't registered
    cliUnknownCommand: 'Invalid Command',

    // A parameter should have a value, but doesn't
    cliIncompleteParam: 'Value required for \'%1$S\'.',

    // Error message given when a file argument points to a file that does not
    // exist, but should (e.g. for use with File->Open)
    // %1$S is a filename
    fileErrNotExists: '\'%1$S\' doesn\'t exist',

    // Error message given when a file argument points to a file that exists,
    // but should not (e.g. for use with File->Save As)
    // %1$S is a filename
    fileErrExists: '\'%1$S\' already exists',

    // Error message given when a file argument points to a non-file, when a
    // file is needed. %1$S is a filename
    fileErrIsNotFile: '\'%1$S\' is not a file',

    // Error message given when a file argument points to a non-directory,
    // when a directory is needed (e.g. for use with 'cd')
    // %1$S is a filename
    fileErrIsNotDirectory: '\'%1$S\' is not a directory',

    // Error message given when a file argument does not match the specified
    // regular expression
    // %1$S is a filename
    // %2$S is a regular expression
    fileErrDoesntMatch: '\'%1$S\' does not match \'%2$S\'',

    // When a command has a parameter that has a number of pre-defined options
    // the user interface presents these in a drop-down menu, where the first
    // 'option' is an indicator that a selection should be made. This string
    // describes that first option.
    fieldSelectionSelect: 'Select a %S…',

    // When a command has a parameter that can be repeated multiple times (e.g.
    // like the 'cat a.txt b.txt' command) the user interface presents buttons
    // to add and remove arguments. This string is used to add arguments.
    fieldArrayAdd: 'Add',
    fieldArrayDel: 'Delete',

    // When the menu has displayed all the matches that it should (i.e. about
    // 10 items) then we display this to alert the user that more matches are
    // available.
    fieldMenuMore: 'More matches, keep typing',

    // The command line provides completion for JavaScript commands, however
    // there are times when the scope of what we're completing against can't
    // be used. This error message is displayed when this happens.
    jstypeParseScope: 'Scope lost',

    // These error messages are displayed when the command line is doing
    // JavaScript completion and encounters errors.
    jstypeParseMissing: 'Can\'t find property \'%S\'',
    jstypeBeginSyntax: 'Syntax error',
    jstypeBeginUnterm: 'Unterminated string literal',

    // This message is displayed if the system for providing JavaScript
    // completions encounters and error it displays this.
    jstypeParseError: 'Error',

    // These error messages are displayed when the command line is passed a
    // variable which has the wrong format and can't be converted.
    // Parameters: %S is the passed variable.
    typesNumberNan: 'Can\'t convert "%S" to a number.',
    typesNumberNotInt2: 'Can\'t convert "%S" to an integer.',
    typesDateNan: 'Can\'t convert "%S" to a date.',

    // These error messages are displayed when the command line is passed a
    // variable which has a value out of range (number or date).
    // Parameters: %1$S is the passed variable, %2$S is the limit value.
    typesNumberMax: '%1$S is greater than maximum allowed: %2$S.',
    typesNumberMin: '%1$S is smaller than minimum allowed: %2$S.',
    typesDateMax: '%1$S is later than maximum allowed: %2$S.',
    typesDateMin: '%1$S is earlier than minimum allowed: %2$S.',

    // This error message is displayed when the command line is passed an
    // option with a limited number of correct values, but the passed value is
    // not one of them.
    typesSelectionNomatch: 'Can\'t use \'%S\'.',

    // This error message is displayed when the command line is expecting a CSS
    // query string, however the passed string is not valid.
    nodeParseSyntax: 'Syntax error in CSS query',

    // These error messages are displayed when the command line is expecting a
    // CSS string that matches a single node, but more nodes (or none) match.
    nodeParseMultiple: 'Too many matches (%S)',
    nodeParseNone: 'No matches',

    // These strings describe the "help" command, used to display a description
    // of a command (e.g. "help pref"), and its parameter 'search'.
    helpDesc: 'Get help on the available commands',
    helpManual: 'Provide help either on a specific command (if a search string is provided and an exact match is found) or on the available commands (if a search string is not provided, or if no exact match is found).',
    helpSearchDesc: 'Search string',
    helpSearchManual3: 'search string to use in narrowing down the displayed commands. Regular expressions not supported.',

    // These strings are displayed in the help page for a command in the
    // console.
    helpManSynopsis: 'Synopsis',

    // This message is displayed in the help page if the command has no
    // parameters.
    helpManNone: 'None',

    // This message is displayed in response to the 'help' command when used
    // without a filter, just above the list of known commands.
    helpListAll: 'Available Commands:',

    // These messages are displayed in response to the 'help <search>' command
    // (i.e. with a search string), just above the list of matching commands.
    // Parameters: %S is the search string.
    helpListPrefix: 'Commands starting with \'%S\':',
    helpListNone: 'No commands starting with \'%S\'',

    // When the 'help x' command wants to show the manual for the 'x' command,
    // it needs to be able to describe the parameters as either required or
    // optional, or if they have a default value.
    helpManRequired: 'required',
    helpManOptional: 'optional',
    helpManDefault: 'optional, default=%S',

    // Text shown as part of the output of the 'help' command when the command
    // in question has sub-commands, before a list of the matching sub-commands.
    subCommands: 'Sub-Commands',

    // Text shown as part of the output of the 'help' command when the command
    // in question should have sub-commands but in fact has none.
    subCommandsNone: 'None',

    // These strings are used to describe the 'context' command and its
    // 'prefix' parameter. See localization comment for 'connect' for an
    // explanation about 'prefix'.
    contextDesc: 'Concentrate on a group of commands',
    contextManual: 'Setup a default prefix to future commands. For example \'context git\' would allow you to type \'commit\' rather than \'git commit\'.',
    contextPrefixDesc: 'The command prefix',

    // This message message displayed during the processing of the 'context'
    // command, when the found command is not a parent command.
    contextNotParentError: 'Can\'t use \'%S\' as a prefix because it is not a parent command.',

    // These messages are displayed during the processing of the 'context'
    // command, to indicate success or that there is no command prefix.
    contextReply: 'Using %S as a command prefix',
    contextEmptyReply: 'Command prefix is unset',

    // These strings describe the 'connect' command and all its available
    // parameters. A 'prefix' is an  alias for the remote server (think of it
    // as a "connection name"), and it allows to identify a specific server
    // when connected to multiple remote servers.
    connectDesc: 'Proxy commands to server',
    connectManual: 'Connect to the server, creating local versions of the commands on the server. Remote commands initially have a prefix to distinguish them from local commands (but see the context command to get past this)',
    connectPrefixDesc: 'Parent prefix for imported commands',
    connectPortDesc: 'The TCP port to listen on',
    connectHostDesc: 'The hostname to bind to',
    connectDupReply: 'Connection called %S already exists.',

    // The output of the 'connect' command, telling the user what it has done.
    // Parameters: %S is the prefix command. See localization comment for
    // 'connect' for an explanation about 'prefix'.
    connectReply: 'Added %S commands.',

    // These strings describe the 'disconnect' command and all its available
    // parameters. See localization comment for 'connect' for an explanation
    // about 'prefix'.
    disconnectDesc2: 'Disconnect from server',
    disconnectManual2: 'Disconnect from a server currently connected for remote commands execution',
    disconnectPrefixDesc: 'Parent prefix for imported commands',
    disconnectForceDesc: 'Ignore outstanding requests',

    // This is the output of the 'disconnect' command, explaining the user what
    // has been done. Parameters: %S is the number of commands removed.
    disconnectReply: 'Removed %S commands.',

    // This error message is displayed when the user attempts to disconnect
    // before all requests have completed. Parameters: %S is a list of
    // incomplete requests.
    disconnectOutstanding: 'Outstanding requests (%S)',

    // These strings describe the 'cd' command and its parameters.
    cdDesc: 'Change working directory',
    cdManual: 'Change the current working directory as used by the exec command',
    cdDirectoryDesc: 'The new working directory',
    cdOutput: 'Working directory is now %S',

    // These strings describe the 'exec' command and its parameters.
    execDesc: 'Execute a system command',
    execManual: '',
    execCommandDesc: 'The command to execute',

    // These strings describe the 'global' command and its parameters
    globalDesc: 'Change the JS global',
    globalWindowDesc: 'The new window/global',
    globalOutput: 'JS global is now %S',

    // These strings describe the 'pref' command and all its available
    // sub-commands and parameters.
    prefDesc: 'Commands to control settings',
    prefManual: 'Commands to display and alter preferences both for GCLI and the surrounding environment',
    prefListDesc: 'Display available settings',
    prefListManual: 'Display a list of preferences, optionally filtered when using the \'search\' parameter',
    prefListSearchDesc: 'Filter the list of settings displayed',
    prefListSearchManual: 'Search for the given string in the list of available preferences',
    prefShowDesc: 'Display setting value',
    prefShowManual: 'Display the value of a given preference',
    prefShowSettingDesc: 'Setting to display',
    prefShowSettingManual: 'The name of the setting to display',

    // This message is used to show the preference name and the associated
    // preference value. Parameters: %1$S is the preference name, %2$S is the
    // preference value.
    prefShowSettingValue: '%1$S: %2$S',

    // These strings describe the 'pref set' command and all its parameters.
    prefSetDesc: 'Alter a setting',
    prefSetManual: 'Alter preferences defined by the environment',
    prefSetSettingDesc: 'Setting to alter',
    prefSetSettingManual: 'The name of the setting to alter.',
    prefSetValueDesc: 'New value for setting',
    prefSetValueManual: 'The new value for the specified setting',

    // These strings are displayed to the user the first time they try to alter
    // a setting.
    prefSetCheckHeading: 'This might void your warranty!',
    prefSetCheckBody: 'Changing these advanced settings can be harmful to the stability, security, and performance of this application. You should only continue if you are sure of what you are doing.',
    prefSetCheckGo: 'I\'ll be careful, I promise!',

    // These strings describe the 'pref reset' command and all its parameters.
    prefResetDesc: 'Reset a setting',
    prefResetManual: 'Reset the value of a setting to the system defaults',
    prefResetSettingDesc: 'Setting to reset',
    prefResetSettingManual: 'The name of the setting to reset to the system default value',

    // This string is displayed in the output from the 'pref list' command as a
    // label to an input element that allows the user to filter the results.
    prefOutputFilter: 'Filter',

    // These strings are displayed in the output from the 'pref list' command
    // as table headings.
    prefOutputName: 'Name',
    prefOutputValue: 'Value',

    // These strings describe the 'intro' command. The localization of
    // 'Got it!' should be the same used in introTextGo.
    introDesc: 'Show the opening message',
    introManual: 'Redisplay the message that is shown to new users until they click the \'Got it!\' button',

    // These strings are displayed when the user first opens the developer
    // toolbar to explain the command line, and is shown each time it is
    // opened until the user clicks the 'Got it!' button.
    introTextOpening2: 'GCLI is an experiment to create a highly usable command line for web developers.',
    introTextCommands: 'For a list of commands type',
    introTextKeys2: ', or to show/hide command hints press',
    introTextF1Escape: 'F1/Escape',
    introTextGo: 'Got it!',

    // This is a short description of the 'hideIntro' setting.
    hideIntroDesc: 'Show the initial welcome message',

    // This is a description of the 'eagerHelper' setting. It's displayed when
    // the user asks for help on the settings. eagerHelper allows users to
    // select between showing no tooltips, permanent tooltips, and only
    // important tooltips.
    eagerHelperDesc: 'How eager are the tooltips',

    // This is a short description of the 'allowSetDesc' setting.
    allowSetDesc: 'Has the user enabled the \'pref set\' command?'
  }
};

exports.root = i18n.root;
<|endoftext|>


<commit_before>'use strict';

requirejs.config({
  baseUrl: '/javascripts/lib',
  enforceDefine: true,
  paths: {
    jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min'
  }
});

define(['jquery', 'appnet'],
  function($, appnet) {

  var url = $('body').data('url');
  var tabs = $('ol.tabs');
  var userMentions = tabs.find('.user-mentions');
  var globalFeed = tabs.find('.global-feed');
  var userPosts = tabs.find('.user-posts');
  var userStarred = tabs.find('.user-starred');
  var myFeed = tabs.find('.my-feed');
  var messages = $('ol.messages');
  var write = $('#write form');
  var userInfo = $('.user-info');
  var overlay = $('#overlay');
  var dashboard = $('.dashboard-content');
  var charLimit = $('#count');
  var body = $('body');
  var csrf = write.find('input[name="_csrf"]').val();

  var CHAR_MAX = 256;

  var resetTab = function(self, callback) {
    self.siblings().removeClass('selected');
    self.addClass('selected');
    callback();
  };

  var freezeDashboard = function() {
    dashboard.addClass('fixed');
  };

  var checkCharLimit = function(text) {
    var textLength = text.length;
    if (textLength > CHAR_MAX - 1) {
      write.find('textarea').val(text.substr(0, CHAR_MAX));
      charLimit.text(0);
    } else {
      charLimit.text(CHAR_MAX - textLength);
    }
  };

  /* Feed functionality */

  myFeed.click(function() {
    var self = $(this);
    messages.empty();
    resetTab(self, function() {
      appnet.getMyFeed();
    });
  });

  globalFeed.click(function() {
    var self = $(this);
    messages.empty();
    resetTab(self, function() {
      appnet.getGlobalFeed();
    });
  });

  userPosts.click(function() {
    var self = $(this);
    messages.empty();
    resetTab(self, function() {
      appnet.getUserPosts();
    });
  });

  userMentions.click(function() {
    var self = $(this);
    messages.empty();
    resetTab(self, function() {
      appnet.getUserMentions();
    });
  });

  userStarred.click(function() {
    var self = $(this);
    messages.empty();
    resetTab(self, function() {
      appnet.getUserStarred();
    });
  });

  /* Automatic feed loader */

  if (url === '/global/feed') {
    globalFeed.click();
  } else if (url.match(/\/user\/posts/)) {
    userPosts.click();
  } else if (url.match(/\/user\/mentions/)) {
    userMentions.click();
  } else if (url.match(/\/user\/starred/)) {
    userStarred.click();
  } else {
    // Defaults to first tab
    tabs.find('.selected').click();
  }

  /* Message functionality */

  messages.on('click', '.details .reply', function() {
    var self = $(this);
    write.find('textarea').val('@' + self.closest('.message-item').data('username') +
      ' ' + self.closest('.message-item').data('mentions') + ' ');
    write.find('#reply_to').val(self.closest('.message-item').data('id'));
    document.location.href = '#top';
    write.find('textarea').focus();
  });

  messages.on('click', '.details .star', function() {
    var self = $(this);
    if (self.hasClass('on')) {
      self.removeClass('on');
      self.find('span').text('Star');
      appnet.unstarMessage(self.closest('.message-item').data('id'), csrf);
    } else {
      self.addClass('on');
      self.find('span').text('Unstar');
      appnet.starMessage(self.closest('.message-item').data('id'), csrf);
    }
  });

  messages.on('click', '.details .repost', function() {
    var self = $(this);
    if (self.hasClass('on')) {
      self.removeClass('on');
      self.find('span').text('Repost');
      appnet.unrepostMessage(self.closest('.message-item').data('id'), csrf);
    } else {
      self.addClass('on');
      self.find('span').text('Unrepost');
      appnet.repostMessage(self.closest('.message-item').data('id'), csrf);
    }
  });

  messages.on('click', '.details .delete', function() {
    var self = $(this);
    appnet.deleteMessage(self.closest('.message-item').data('id'), csrf);
    self.closest('li.message-item').fadeOut();
  });

  messages.on('click', '.details .thread', function() {
    var self = $(this);
    appnet.showThread(self.closest('.message-item').data('id'));
    freezeDashboard();
  });

  body.on('click', 'time', function() {
    var self = $(this);
    appnet.showPost(self.closest('.message-item').data('id'));
    freezeDashboard();
  });

  body.on('click', 'a.tags', function(ev) {
    ev.preventDefault();
    var self = $(this);
    appnet.showTagged(self.attr('href').split('/tagged/')[1]);
    freezeDashboard();
  });

  messages.on('click', '#paginated', function() {
    var self = $(this);
    appnet.getOlderPosts(self.prev().data('id'));
  });

  /* User functionality */

  userInfo.on('click', '.follow', function() {
    var self = $(this);
    if (self.hasClass('on')) {
      self.removeClass('on');
      self.text('Follow');
      appnet.unfollow(self.parent().data('userid'), csrf);
    } else {
      self.addClass('on');
      self.text('Unfollow');
      appnet.follow(self.parent().data('userid'), csrf);
    }
  });

  userInfo.on('click', '.mute', function() {
    var self = $(this);
    if (self.hasClass('on')) {
      self.removeClass('on');
      self.text('Mute');
      appnet.unmute(self.parent().data('userid'), csrf);
    } else {
      self.addClass('on');
      self.text('Unmute');
      appnet.mute(self.parent().data('userid'), csrf);
    }
  });

  userInfo.on('click', '.followers', function() {
    var self = $(this);
    appnet.showFollowers();
    freezeDashboard();
  });

  userInfo.on('click', '.following', function() {
    var self = $(this);
    appnet.showFollowing();
    freezeDashboard();
  });

  overlay.on('click', '.close', function() {
    overlay.slideUp(function() {
      $(this).html('');
      dashboard.removeClass('fixed');
    });
  });

  /* Write functionality */

  checkCharLimit(write.find('textarea').val());

  write.find('textarea').focus(function() {
    var self = $(this);
    charLimit.addClass('on');
    checkCharLimit(self.val());
  });

  write.find('textarea').blur(function() {
    charLimit.removeClass('on');
  });

  // Clear the reply_to id if this is empty
  write.find('textarea').keyup(function() {
    var self = $(this);
    checkCharLimit(self.val());
    if (self.val().trim().length === 0) {
      write.find('#reply_to').val('');
    }
  });

  write.submit(function(ev) {
    ev.preventDefault();

    var self = $(this);
    appnet.postMessage(self);
    url = '/my/feed';
    self.find('textarea').val('');
    charLimit.text(CHAR_MAX);
    return false;
  });
});
<commit_msg>fixed reply to bug<commit_after>'use strict';

requirejs.config({
  baseUrl: '/javascripts/lib',
  enforceDefine: true,
  paths: {
    jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min'
  }
});

define(['jquery', 'appnet'],
  function($, appnet) {

  var url = $('body').data('url');
  var tabs = $('ol.tabs');
  var userMentions = tabs.find('.user-mentions');
  var globalFeed = tabs.find('.global-feed');
  var userPosts = tabs.find('.user-posts');
  var userStarred = tabs.find('.user-starred');
  var myFeed = tabs.find('.my-feed');
  var messages = $('ol.messages');
  var write = $('#write form');
  var userInfo = $('.user-info');
  var overlay = $('#overlay');
  var dashboard = $('.dashboard-content');
  var charLimit = $('#count');
  var body = $('body');
  var csrf = write.find('input[name="_csrf"]').val();

  var CHAR_MAX = 256;

  var resetTab = function(self, callback) {
    self.siblings().removeClass('selected');
    self.addClass('selected');
    callback();
  };

  var freezeDashboard = function() {
    dashboard.addClass('fixed');
  };

  var checkCharLimit = function(text) {
    var textLength = text.length;
    if (textLength > CHAR_MAX - 1) {
      write.find('textarea').val(text.substr(0, CHAR_MAX));
      charLimit.text(0);
    } else {
      charLimit.text(CHAR_MAX - textLength);
    }
  };

  /* Feed functionality */

  myFeed.click(function() {
    var self = $(this);
    messages.empty();
    resetTab(self, function() {
      appnet.getMyFeed();
    });
  });

  globalFeed.click(function() {
    var self = $(this);
    messages.empty();
    resetTab(self, function() {
      appnet.getGlobalFeed();
    });
  });

  userPosts.click(function() {
    var self = $(this);
    messages.empty();
    resetTab(self, function() {
      appnet.getUserPosts();
    });
  });

  userMentions.click(function() {
    var self = $(this);
    messages.empty();
    resetTab(self, function() {
      appnet.getUserMentions();
    });
  });

  userStarred.click(function() {
    var self = $(this);
    messages.empty();
    resetTab(self, function() {
      appnet.getUserStarred();
    });
  });

  /* Automatic feed loader */

  if (url === '/global/feed') {
    globalFeed.click();
  } else if (url.match(/\/user\/posts/)) {
    userPosts.click();
  } else if (url.match(/\/user\/mentions/)) {
    userMentions.click();
  } else if (url.match(/\/user\/starred/)) {
    userStarred.click();
  } else {
    // Defaults to first tab
    tabs.find('.selected').click();
  }

  /* Message functionality */

  messages.on('click', '.details .reply', function() {
    var self = $(this);
    write.find('textarea').val('@' + self.closest('.message-item').data('username') +
      ' ' + self.closest('.message-item').data('mentions') + ' ');
    write.find('#reply_to').val(self.closest('.message-item').data('id'));
    document.location.href = '#top';
    write.find('textarea').focus();
  });

  messages.on('click', '.details .star', function() {
    var self = $(this);
    if (self.hasClass('on')) {
      self.removeClass('on');
      self.find('span').text('Star');
      appnet.unstarMessage(self.closest('.message-item').data('id'), csrf);
    } else {
      self.addClass('on');
      self.find('span').text('Unstar');
      appnet.starMessage(self.closest('.message-item').data('id'), csrf);
    }
  });

  messages.on('click', '.details .repost', function() {
    var self = $(this);
    if (self.hasClass('on')) {
      self.removeClass('on');
      self.find('span').text('Repost');
      appnet.unrepostMessage(self.closest('.message-item').data('id'), csrf);
    } else {
      self.addClass('on');
      self.find('span').text('Unrepost');
      appnet.repostMessage(self.closest('.message-item').data('id'), csrf);
    }
  });

  messages.on('click', '.details .delete', function() {
    var self = $(this);
    appnet.deleteMessage(self.closest('.message-item').data('id'), csrf);
    self.closest('li.message-item').fadeOut();
  });

  messages.on('click', '.details .thread', function() {
    var self = $(this);
    appnet.showThread(self.closest('.message-item').data('id'));
    freezeDashboard();
  });

  body.on('click', 'time', function() {
    var self = $(this);
    appnet.showPost(self.closest('.message-item').data('id'));
    freezeDashboard();
  });

  body.on('click', 'a.tags', function(ev) {
    ev.preventDefault();
    var self = $(this);
    appnet.showTagged(self.attr('href').split('/tagged/')[1]);
    freezeDashboard();
  });

  messages.on('click', '#paginated', function() {
    var self = $(this);
    appnet.getOlderPosts(self.prev().data('id'));
  });

  /* User functionality */

  userInfo.on('click', '.follow', function() {
    var self = $(this);
    if (self.hasClass('on')) {
      self.removeClass('on');
      self.text('Follow');
      appnet.unfollow(self.parent().data('userid'), csrf);
    } else {
      self.addClass('on');
      self.text('Unfollow');
      appnet.follow(self.parent().data('userid'), csrf);
    }
  });

  userInfo.on('click', '.mute', function() {
    var self = $(this);
    if (self.hasClass('on')) {
      self.removeClass('on');
      self.text('Mute');
      appnet.unmute(self.parent().data('userid'), csrf);
    } else {
      self.addClass('on');
      self.text('Unmute');
      appnet.mute(self.parent().data('userid'), csrf);
    }
  });

  userInfo.on('click', '.followers', function() {
    var self = $(this);
    appnet.showFollowers();
    freezeDashboard();
  });

  userInfo.on('click', '.following', function() {
    var self = $(this);
    appnet.showFollowing();
    freezeDashboard();
  });

  overlay.on('click', '.close', function() {
    overlay.slideUp(function() {
      $(this).html('');
      dashboard.removeClass('fixed');
    });
  });

  /* Write functionality */

  checkCharLimit(write.find('textarea').val());

  write.find('textarea').focus(function() {
    var self = $(this);
    charLimit.addClass('on');
    checkCharLimit(self.val());
  });

  write.find('textarea').blur(function() {
    charLimit.removeClass('on');
  });

  // Clear the reply_to id if this is empty
  write.find('textarea').keyup(function() {
    var self = $(this);
    checkCharLimit(self.val());
    if (self.val().trim().length === 0) {
      write.find('#reply_to').val('');
    }
  });

  write.submit(function(ev) {
    ev.preventDefault();

    var self = $(this);
    appnet.postMessage(self);
    url = '/my/feed';
    self.find('textarea').val('');
    charLimit.text(CHAR_MAX);
    write.find('#reply_to').val('');
    return false;
  });
});
<|endoftext|>


<commit_before>(function(){

	// script goes here

})();<commit_msg>prepared the scripts and Data by setting up the angularJS app and controller<commit_after>(function(){

	var app = angular.module('rickNMortyQuiz',[]);

	app.controller('MortyController', ['$scope', '$http','$sce', function($scope,$http,$sce){
		// the entire application will be controlled within this controller
	}]);

})();<|endoftext|>


<commit_before>$(function() {
  calendarView = {};
  var $container = $('#container');
  var colors = [
    '',
    'lime',
    'green',
    'red'
  ];
  var dateArray = [];
  for (var i = 0; i < 7; i++) {
    dateArray.unshift(new Date());
    dateArray[0].setDate(dateArray[0].getDate() + i);
  }
  var aggData = [[0, 0, null], [0, 1, null], [0, 2, 8], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117], [4, 4, 115], [5, 0, 88], [5, 1, 32], [5, 2, 12], [5, 3, 6], [5, 4, 120], [6, 0, 13], [6, 1, 44], [6, 2, 88], [6, 3, 98], [6, 4, 96], [7, 0, 31], [7, 1, 1], [7, 2, 82], [7, 3, 32], [7, 4, 30], [8, 0, 85], [8, 1, 97], [8, 2, 123], [8, 3, 64], [8, 4, 84], [9, 0, 47], [9, 1, 114], [9, 2, 31], [9, 3, 30], [9, 4, 91], [23, 6, 150]];

  calendarView.colorTranslater = function(ele) {
    if (ele[2] == 0 || ele[2] == 1 || ele[2] == 2) {
      return ele[2];
    } else {
      return 3;
    }
  };

  calendarView.render = function () {
    $container.highcharts({
      chart: {
        type: 'heatmap',
        marginTop: 40,
        marginBottom: 80,
        plotBorderWidth: 1,
      },
      title: {
        text: null
      },
      xAxis: {
        categories: ['1a', '2a', '3a', '4a', '5a', '6a', '7a', '8a', '9a', '10a', '11a', '12a', '1p', '2p', '3p', '4p', '5p', '6p', '7p', '8p', '9p', '10p', '11p', '12p']
      },
      yAxis: {
        categories: dateArray.map(function(ele){return ele.toDateString().slice(0,-5);}),
        title: null,
      },
      colorAxis: {
        min: 0,
        minColor: '#FFFFFF',
        maxColor: Highcharts.getOptions().colors[0],
        reversed: true
      },
      plotOptions: {
        heatmap: {
          colorbyPoint: true,
        }
      },
      legend: {
        align: 'right',
        layout: 'vertical',
        margin: 0,
        verticalAlign: 'top',
        y: 25,
        symbolHeight: 280
      },
      tooltip: {
        formatter: function () {
          return ' At ' + this.series.xAxis.categories[this.point.x] + ' on ' + this.series.yAxis.categories[this.point.y] + ':
 '; //TODO: List of guests with preference greater than 0.
        }
        // formatter: function () {
        //   // console.log(this);
        //   return '' + this.series.xAxis.categories[this.point.x] + ' sold
' +
        //       this.point.value + ' items on
' + this.series.yAxis.categories[this.point.y] + '';
        // }
      },
      series: [{
        name: 'Aggregate Prefs',
        borderWidth: 1,
        data: aggData,
        dataLabels: {
          enabled: false,
        },
        borderWidth: 0,
        id: 5, //TODO: TopicID
        index: 1
      },
//start of personal preference data series
      {
        name: 'Personal Prefs',
        borderWidth: 1,
        data: aggData.map(function(ele) {
          return [ele[0], ele[1], Math.random() * 100];
        }),
        dataLabels: {
          enabled: false,
        },
        events:  {
          click: function() {
            //Sends relevant information to backend.
            var vote = dateArray[event.point.y].toDateString() + '@' + event.point.series.xAxis.categories[event.point.x];
            // console.log(vote);
            console.log(
              event.point.series.xAxis.categories[event.point.x],
              event.point.series.yAxis.categories[event.point.y],
              event.point.series.name,
              this.userOptions.id);
            var userHash = $('#user-id').attr('data-userHash');
            sendClickToDatabase(vote,userHash,this.userOptions.id, getNewCalendarData);
            //Receives information
            //TODO: Write the ability to receive info here.
            //Sets vote-state hover color.
            //TODO: update local copy of vote-state array

          },
        },
        borderWidth: 0,
        id: 5, //TODO: TopicID
        colors: Highcharts.getOptions().colors[3],
        index: 0
      }
    ]
    });

    chart = $container.highcharts();
  };

  // $('.highcharts-series-0').on('click', 'rect', function() {
  //   console.log(this);
  //   $(this).css('background-color', 'red !important');
  // });

  function sendClickToDatabase(vote,userHashArg,topicIdArg, callback) {
    $.ajax({
      url: '/api/votes',
      type: 'POST',
      data: {name: vote,userHash: userHashArg, topicId: topicIdArg},
      cache: false
    })
    .done( function (data) {
      // call the callback function here
      console.log('Successful ajax call:');
      console.log(data);
      if(callback) callback(topicIdArg,userHashArg);
    })
    .fail( function(jqXHR, textStatus, errorThrown) {
      console.log('Failed to send click to database.');
      // call the error version of the callback if any
    });
  };

  function getNewCalendarData(topicIdArg,userHashArg) {

    $.ajax({
      url: '/api/votes/' + topicIdArg,
      type: 'GET',
      cache: false
    })
    .done( function (data) {
      // call the callback function here
      console.log('Successful ajax call:');
      console.log(data);
      // data will be full list of vote options and weights for a specific topic
      // TODO: Translate fresh data into aggData
    })
    .fail( function(jqXHR, textStatus, errorThrown) {
      console.log('Failed to send click to database.');
      // call the error version of the callback if any
    });

    $.ajax({
      url: '/api/votes/' + topicIdArg + '/' + userHashArg,
      type: 'GET',
      cache: false
    })
    .done( function (data) {
      // call the callback function here
      console.log('Successful ajax call:');
      console.log(data);
      // data will be a list of a given user's choices and weights
      // TODO: Translate fresh data into perData
    })
    .fail( function(jqXHR, textStatus, errorThrown) {
      console.log('Failed to send click to database.');
      // call the error version of the callback if any
    });
  }

  // getNewCalendarData(topicIdArg,userHashArg); //TODO: populate this with arguments
  calendarView.render(); //this should be invoked elsewhere.

  $('g.highcharts-series-group').hover(
    function() {
      chart.series[1].setVisible();
      chart.setTitle({text: 'Click on times to set your preferences.'});
    },
    function () {
      chart.series[1].setVisible();
      chart.setTitle({text: null});
    });
});
<commit_msg>more QOL improvements, incl. CSS styling to to calendar<commit_after>$(function() {
  calendarView = {};
  var $container = $('#container');
  var colors = [
    '',
    'lime',
    'green',
    'red'
  ];
  var dateArray = [];
  for (var i = 0; i < 7; i++) {
    dateArray.unshift(new Date());
    dateArray[0].setDate(dateArray[0].getDate() + i);
  }
  var aggData = [[0, 0, null], [0, 1, null], [0, 2, 8], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117], [4, 4, 115], [5, 0, 88], [5, 1, 32], [5, 2, 12], [5, 3, 6], [5, 4, 120], [6, 0, 13], [6, 1, 44], [6, 2, 88], [6, 3, 98], [6, 4, 96], [7, 0, 31], [7, 1, 1], [7, 2, 82], [7, 3, 32], [7, 4, 30], [8, 0, 85], [8, 1, 97], [8, 2, 123], [8, 3, 64], [8, 4, 84], [9, 0, 47], [9, 1, 114], [9, 2, 31], [9, 3, 30], [9, 4, 91], [23, 6, 150]];

  calendarView.colorTranslater = function(ele) {
    if (ele[2] == 0 || ele[2] == 1 || ele[2] == 2) {
      return ele[2];
    } else {
      return 3;
    }
  };

  calendarView.render = function () {
    $container.highcharts({
      chart: {
        type: 'heatmap',
        marginTop: 40,
        marginBottom: 80,
        plotBorderWidth: 1,
      },
      title: {
        text: null
      },
      xAxis: {
        categories: ['1a', '2a', '3a', '4a', '5a', '6a', '7a', '8a', '9a', '10a', '11a', '12a', '1p', '2p', '3p', '4p', '5p', '6p', '7p', '8p', '9p', '10p', '11p', '12p']
      },
      yAxis: {
        categories: dateArray.map(function(ele){return ele.toDateString().slice(0,-5);}),
        title: null,
      },
      colorAxis: {
        min: 0,
        minColor: '#FFFFFF',
        maxColor: Highcharts.getOptions().colors[0],
        reversed: true
      },
      plotOptions: {
        heatmap: {
          colorbyPoint: true,
        }
      },
      legend: {
        align: 'right',
        layout: 'vertical',
        margin: 0,
        verticalAlign: 'top',
        y: 25,
        symbolHeight: 280
      },
      tooltip: {
        formatter: function () {
          return ' At ' + this.series.xAxis.categories[this.point.x] + ' on ' + this.series.yAxis.categories[this.point.y];
          //  + ':
 '; //TODO: List of guests with preference greater than 0.
        }
      },
      series: [{
        name: 'Aggregate Prefs',
        borderWidth: 1,
        data: aggData,
        dataLabels: {
          enabled: false,
        },
        borderWidth: 0,
        id: 5, //TODO: TopicID
        index: 1
      },
//start of personal preference data series
      {
        name: 'Personal Prefs',
        borderWidth: 1,
        data: aggData.map(function(ele) {
          return [ele[0], ele[1], Math.random() * 100];
        }),
        dataLabels: {
          enabled: false,
        },
        events:  {
          click: function() {
            //Sends relevant information to backend.
              // console.log(vote);
              // console.log(
              //   event.point.series.xAxis.categories[event.point.x],
              //   event.point.series.yAxis.categories[event.point.y],
              //   event.point.series.name,
              //   this.userOptions.id);
            var vote = dateArray[event.point.y].toDateString() + '@' + event.point.series.xAxis.categories[event.point.x];
            var userHash = $('#user-id').attr('data-userHash');
            sendClickToDatabase(vote,userHash,this.userOptions.id, getNewCalendarData);
            //Sets vote-state hover color.
            //TODO: update local copy of vote-state array? Or wait on getNewData?

          },
        },
        borderWidth: 0,
        id: 5, //TODO: TopicID
        colors: Highcharts.getOptions().colors[3],
        index: 0
      }
    ]
    });

    chart = $container.highcharts();
  };

  $('.highcharts-series-1').on('click', function() {
    console.log(this);
    $(this).css('background-color', 'red !important');
  });

  function sendClickToDatabase(vote,userHashArg,topicIdArg, callback) {
    $.ajax({
      url: '/api/votes',
      type: 'POST',
      data: {name: vote,userHash: userHashArg, topicId: topicIdArg},
      cache: false
    })
    .done( function (data) {
      // call the callback function here
      console.log('Successful ajax call:');
      console.log(data);
      if(callback) callback(topicIdArg,userHashArg);
    })
    .fail( function(jqXHR, textStatus, errorThrown) {
      console.log('Failed to send click to database.');
      // call the error version of the callback if any
    });
  };

  function getNewCalendarData(topicIdArg,userHashArg) {

    $.ajax({
      url: '/api/votes/' + topicIdArg,
      type: 'GET',
      cache: false
    })
    .done( function (data) {
      // call the callback function here
      console.log('Successful ajax call:');
      console.log(data);
      // data will be full list of vote options and weights for a specific topic
      // TODO: Translate fresh data into aggData
    })
    .fail( function(jqXHR, textStatus, errorThrown) {
      console.log('Failed to send click to database.');
      // call the error version of the callback if any
    });

    $.ajax({
      url: '/api/votes/' + topicIdArg + '/' + userHashArg,
      type: 'GET',
      cache: false
    })
    .done( function (data) {
      // call the callback function here
      console.log('Successful ajax call:');
      console.log(data);
      // data will be a list of a given user's choices and weights
      // TODO: Translate fresh data into perData
    })
    .fail( function(jqXHR, textStatus, errorThrown) {
      console.log('Failed to send click to database.');
      // call the error version of the callback if any
    });
  }

  // getNewCalendarData(topicIdArg,userHashArg); //TODO: populate this with arguments
  calendarView.render(); //this should be invoked elsewhere.

  $('g.highcharts-series-group').hover(
    function() {
      chart.series[1].setVisible();
      chart.setTitle({text: 'Click on times to set your preferences.'});
    },
    function () {
      chart.series[1].setVisible();
      chart.setTitle({text: null});
    });
});
<|endoftext|>