<commit_before>require(
	[
		"animationmanager.js",
		"level/world.js",
		"level/player.js",
		"level/enemy.js",
		"level/miner.js",
		"level/healthbar.js",
		"gameobject.js",
		"level/cameracontroller.js",
		"level/ui.js",
		"level/particlesystem.js"
	], main);

function main()
{
    StateManager.addState({
    	stability: 100,
    	maxStability: 100,
    	world: null,
    	player: null,
    	enemies: [],
    	miners: [],
    	ui: null,
		name: "level",

		initialise: function() {
			this.player = null;
			this.world = null;
			this.enemies = [];
			this.miners = [];
			this.ui = null;
    		this.hotspotMiners = Math.random() * 90;
    		this.hotspotEnemies = Math.random() * 90 + 180;
			this.world = new World();
			this.player = new Player(Math.random() * 360, this.world);
			this.ui = new UI(this.stability);
<<<<<<< HEAD
=======

			for (var i = 0; i < 10; ++i) {
				this.miners.push(new Miner(Math.random() * 360, this.world, this.hotspotMiners));
			}

			for (var i = 0; i < 10; ++i) {
				this.enemies.push(new Enemy(Math.random() * 360, this.world, this.hotspotEnemies));
			}

			Game.PIXI.Camera.addChild(this.world.clouds);
>>>>>>> 5a5bfcd77a8cdca5545e45f16c8d748a0d588bfa
		},
		update: function(data) {
			this.player.update(data);

			if (Input.isDown('b')) {
				this.myPartEmitter.position.x -= 1;
			}

			for (var i = 0; i < this.miners.length; ++i) {
				this.miners[i].update(data);
			}

			for (var i = 0; i < this.enemies.length; ++i) {
				this.enemies[i].update(data);
			}
			this.ui.update();
			this.world.update();
		},
		destroy: function() {
			Game.PIXI.Camera.children = [];
		}
	});

	StateManager.switchState("level");
}<commit_msg>Fixed merge<commit_after>require(
	[
		"animationmanager.js",
		"level/world.js",
		"level/player.js",
		"level/enemy.js",
		"level/miner.js",
		"level/healthbar.js",
		"gameobject.js",
		"level/cameracontroller.js",
		"level/ui.js",
		"level/particlesystem.js"
	], main);

function main()
{
    StateManager.addState({
    	stability: 100,
    	maxStability: 100,
    	world: null,
    	player: null,
    	enemies: [],
    	miners: [],
    	ui: null,
		name: "level",

		initialise: function() {
			this.player = null;
			this.world = null;
			this.enemies = [];
			this.miners = [];
			this.ui = null;
    		this.hotspotMiners = Math.random() * 90;
    		this.hotspotEnemies = Math.random() * 90 + 180;
			this.world = new World();
			this.player = new Player(Math.random() * 360, this.world);
			this.ui = new UI(this.stability);

			Game.PIXI.Camera.addChild(this.world.clouds);
		},
		update: function(data) {
			this.player.update(data);

			if (Input.isDown('b')) {
				this.myPartEmitter.position.x -= 1;
			}

			for (var i = 0; i < this.miners.length; ++i) {
				this.miners[i].update(data);
			}

			for (var i = 0; i < this.enemies.length; ++i) {
				this.enemies[i].update(data);
			}
			this.ui.update();
			this.world.update();
		},
		destroy: function() {
			Game.PIXI.Camera.children = [];
		}
	});

	StateManager.switchState("level");
}<|endoftext|>


<commit_before>function add_card(number, owner) {
  cards.push({ number: number, owner: owner, balance: '...' });
  save_cards();
  get_balance(cards[cards.length - 1]);
  return true;
}

function remove_card(id) {
  cards.splice(id, 1);
  save_cards();
}

function update_view(status) {
  var table = document.getElementById('cards');
  if (table) {
    while (table.firstChild) {
      table.removeChild(table.firstChild);
    }
    if (cards.length) {
      document.getElementById('header').style.display = 'none';
      var row;
      for (var i = 0; i < cards.length; ++i) {
        var id_delete = 'btn-delete-' + i;
        row = table.insertRow(table.rows.length);
        row.insertCell(0).innerHTML = '
' + cards[i].owner + '

' + cards[i].number + '

Удалить
';
        row.insertCell(1).innerHTML = '
' + cards[i].balance + '
';
        document.getElementById(id_delete).card_id = i;
        document.getElementById(id_delete).addEventListener('click', function(e) {
          remove_card(e.target.card_id);
        }, false);
      }
      if (sync) {
        status = status ? status + '
' : '';
        row = table.insertRow(table.rows.length);
        var cell = row.insertCell(0);
        cell.colSpan = 2;
        cell.innerHTML = status + 'Последняя синхронизация: ' + sync.date + ' – ' + sync.time + '';
      }
    } else {
      loaded();
    }
  }
}

function loaded() {
  var element;
  element = document.getElementById('header'); if (element) { element.style.display = 'block'; }
  element = document.getElementById('header-help'); if (element) { element.style.display = 'block'; }
  element = document.getElementById('header-loading'); if (element) { element.style.display = 'none'; }
}

function get_balance(card) {
  // Fetch CSRF:
  var xhr_csrf = new XMLHttpRequest();
  xhr_csrf.addEventListener('readystatechange', function () {
    if (xhr_csrf.readyState === 4) {
      if (xhr_csrf.status === 200) {
        // Fetch card balance:
        var response = new DOMParser().parseFromString(xhr_csrf.responseText, 'text/html');
        var csrf = encodeURIComponent(response.getElementById('csrftoken').value);
        var xhr_card = new XMLHttpRequest();
        xhr_card.addEventListener('readystatechange', function () {
          if (xhr_card.readyState === 4) {
            if (xhr_card.status === 200) {
              // TODO Handle "Too many requests" server response.
              var json = JSON.parse(xhr_card.responseText).result;
              card.balance = typeof(json.balance) !== 'undefined' ? json.balance / 100.0 : 'Ошибка';
              console.info(card.owner + ': ' + json.type);
              save_cards();
              save_datetime();
            } else {
              update_view('Не удалось проверить баланс. Попробуйте позже.');
            }
          }
        });
        xhr_card.open('POST', 'https://cabinet.onay.kz/check');
        xhr_card.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr_card.send('pan=' + card.number + '&csrf=' + csrf);
      } else {
        update_view('Не удалось проверить баланс. Попробуйте позже.');
      }
    }
  });
  xhr_csrf.open('GET', 'https://cabinet.onay.kz');
  xhr_csrf.send();
}

function save_cards() {
  chrome.storage.sync.set({ cards: cards });
  update_view();
}

function save_datetime() {
  var dt = new Date();
  var day = ('0' + dt.getDate()).slice(-2);
  var month = ('0' + (dt.getMonth() + 1)).slice(-2);
  var year = ('0' + dt.getFullYear()).slice(-2);
  var hours = ('0' + dt.getHours()).slice(-2);
  var minutes = ('0' + dt.getMinutes()).slice(-2);
  var seconds = ('0' + dt.getSeconds()).slice(-2);
  sync = {
    date: day + '.' + month + '.' + year,
    time: hours + ':' + minutes + ':' + seconds
  };
  chrome.storage.sync.set({ sync: sync });
  update_view();
}

function load_settings() {
  chrome.storage.sync.get('sync', function(items) {
    sync = items.sync;
  });
  chrome.storage.sync.get('cards', function(items) {
    if (items.cards && items.cards.length) {
      cards = items.cards;
      update_view('Загрузка...');
      for (var i = 0; i < cards.length; ++i) {
        get_balance(cards[i]);
      }
    } else {
      loaded();
    }
  });
}

// Initialize:

var cards = [];
var sync = {};
load_settings();
<commit_msg>Remove debug function<commit_after>function add_card(number, owner) {
  cards.push({ number: number, owner: owner, balance: '...' });
  save_cards();
  get_balance(cards[cards.length - 1]);
  return true;
}

function remove_card(id) {
  cards.splice(id, 1);
  save_cards();
}

function update_view(status) {
  var table = document.getElementById('cards');
  if (table) {
    while (table.firstChild) {
      table.removeChild(table.firstChild);
    }
    if (cards.length) {
      document.getElementById('header').style.display = 'none';
      var row;
      for (var i = 0; i < cards.length; ++i) {
        var id_delete = 'btn-delete-' + i;
        row = table.insertRow(table.rows.length);
        row.insertCell(0).innerHTML = '
' + cards[i].owner + '

' + cards[i].number + '

Удалить
';
        row.insertCell(1).innerHTML = '
' + cards[i].balance + '
';
        document.getElementById(id_delete).card_id = i;
        document.getElementById(id_delete).addEventListener('click', function(e) {
          remove_card(e.target.card_id);
        }, false);
      }
      if (sync) {
        status = status ? status + '
' : '';
        row = table.insertRow(table.rows.length);
        var cell = row.insertCell(0);
        cell.colSpan = 2;
        cell.innerHTML = status + 'Последняя синхронизация: ' + sync.date + ' – ' + sync.time + '';
      }
    } else {
      loaded();
    }
  }
}

function loaded() {
  var element;
  element = document.getElementById('header'); if (element) { element.style.display = 'block'; }
  element = document.getElementById('header-help'); if (element) { element.style.display = 'block'; }
  element = document.getElementById('header-loading'); if (element) { element.style.display = 'none'; }
}

function get_balance(card) {
  // Fetch CSRF:
  var xhr_csrf = new XMLHttpRequest();
  xhr_csrf.addEventListener('readystatechange', function () {
    if (xhr_csrf.readyState === 4) {
      if (xhr_csrf.status === 200) {
        // Fetch card balance:
        var response = new DOMParser().parseFromString(xhr_csrf.responseText, 'text/html');
        var csrf = encodeURIComponent(response.getElementById('csrftoken').value);
        var xhr_card = new XMLHttpRequest();
        xhr_card.addEventListener('readystatechange', function () {
          if (xhr_card.readyState === 4) {
            if (xhr_card.status === 200) {
              // TODO Handle "Too many requests" server response.
              var json = JSON.parse(xhr_card.responseText).result;
              card.balance = typeof(json.balance) !== 'undefined' ? json.balance / 100.0 : 'Ошибка';
              save_cards();
              save_datetime();
            } else {
              update_view('Не удалось проверить баланс. Попробуйте позже.');
            }
          }
        });
        xhr_card.open('POST', 'https://cabinet.onay.kz/check');
        xhr_card.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr_card.send('pan=' + card.number + '&csrf=' + csrf);
      } else {
        update_view('Не удалось проверить баланс. Попробуйте позже.');
      }
    }
  });
  xhr_csrf.open('GET', 'https://cabinet.onay.kz');
  xhr_csrf.send();
}

function save_cards() {
  chrome.storage.sync.set({ cards: cards });
  update_view();
}

function save_datetime() {
  var dt = new Date();
  var day = ('0' + dt.getDate()).slice(-2);
  var month = ('0' + (dt.getMonth() + 1)).slice(-2);
  var year = ('0' + dt.getFullYear()).slice(-2);
  var hours = ('0' + dt.getHours()).slice(-2);
  var minutes = ('0' + dt.getMinutes()).slice(-2);
  var seconds = ('0' + dt.getSeconds()).slice(-2);
  sync = {
    date: day + '.' + month + '.' + year,
    time: hours + ':' + minutes + ':' + seconds
  };
  chrome.storage.sync.set({ sync: sync });
  update_view();
}

function load_settings() {
  chrome.storage.sync.get('sync', function(items) {
    sync = items.sync;
  });
  chrome.storage.sync.get('cards', function(items) {
    if (items.cards && items.cards.length) {
      cards = items.cards;
      update_view('Загрузка...');
      for (var i = 0; i < cards.length; ++i) {
        get_balance(cards[i]);
      }
    } else {
      loaded();
    }
  });
}

// Initialize:

var cards = [];
var sync = {};
load_settings();
<|endoftext|>


<commit_before>/*global require,$*/
require([
    "jquery",
    "util/random"
], function () {
    "use strict";
    $("#randomNumber").text(Math.randomBelow(42));
});

<commit_msg>require.js: jQuery<commit_after>/*global require*/
require([
    "jquery",
    "util/random"
], function ($) {
    "use strict";
    $("#randomNumber").text(Math.randomBelow(42));
});

<|endoftext|>


<commit_before>//########################################################
//###############   STATE OBJECT and CONSTANTS  ##########
//########################################################
const state = {
  guns: []
}

//var template = '';

//const rootURL = 'http://localhost:8080/guns';

const rootURL = 'https://firearmbase.herokuapp.com/guns';

//#########################################################
//#################  STATE MODIFICATION METHODS  ##########
//#########################################################

function getAllGuns() {
  return new Promise(function (res, rej) {
    $.ajax({
      url: rootURL,
      type: "GET",
      headers: {
        "accept": "application/jsonp;odata=verbose",
      },
      success: function(gundata) {
        var num=0;
        gundata.forEach( gun => {
          //state.guns[gun.fullName] = gun;
          state.guns[num] = gun;
          num++;
        });
        //console.log('StateObject: ',state.guns);
        console.log('first promise hit');
        res();
      },
      error: function(error){
        console.log('error: ',error);
      }
    })
  })
  return state;
}

getAllGuns()
.then(showMenu);

//#########################################################
//#################  DOM MODIFICATION METHODS  ############
//#########################################################

function outputGunsReport() {
  // return new Promise( (res, rej) => {
    var template = '
';
    state.guns.forEach( gun => {
      console.log('ONE: ', typeof gun);
      template += '
'+gun.fullName+'
';
    })
    template += '<button id="home_page">Home</button>';
    template += '
';
    console.log('state.guns object ', state.guns);
    $("#output").html(template);
    $("#home_page").click(function(){
      showMenu();
    })
  // });
}

//#########################################################
//#################  DATABASE METHODS      ################
//#########################################################

function gunDbTalk(gunData){
  console.log('gunTalk ', gunData);
    $.ajax({
      url: rootURL,
      type: "POST",
      headers: {
        "accept": "application/json;odata=verbose",
      },
      data: JSON.stringify(gunData),
      contentType: "application/json; charset=utf-8",
      dataType: 'json',
      success: function(gundata) {

        //console.log('StateObject: ',state.guns);
        console.log('HEY!  Object: ',gundata);
        // res();
      },
      error: function(error){
        console.log('error: ',error);
      }
    })
  getAllGuns();
  showMenu();
}

//#########################################################
//#################  PROGRAM CONTROL FLOW  ################
//#########################################################

//This function shows the opening menu
function showMenu(){
  var template = '
'
  template += '<button id="list_all">List All Guns</button>';
  template += '<button id="create_gun">Add Gun</button>';
  template += '<button id="read_gun">Find Gun</button>';
  template += '<button id="update_gun">Modify Gun</button>';
  template += '<button id="delete_gun">Delete Gun</button>';
  template += '
';

  $("#output").html(template);

  // List all guns
  $("#list_all").click(function(){
    outputGunsReport();
  })

  // Add a gun to database
  $("#create_gun").click(function(){
    //console.log('Create_gun clicked')

    var template = `<div><form>`;
    template += '<input id="manufacturer" type="text" placeholder="manufacturer" name="manufacturer">';
    template += '<input id="model"  type="text" placeholder="model" name="model">';
    template += '<input id="chambering"  type="text" placeholder="chambering" name="chambering">';
    template += '<input id="type" type="text" placeholder="type" name="type">';
    template += '<input  id="serial_number" type="text" placeholder="serial_number" name="serial_number">';
    template += '<input id="image" type="text" placeholder="image" name="image">'
    template += '<input id="value" type="text" placeholder="value" name="value">';
    template += '<input id="sold" type="text" placeholder="sold" name="sold">';
    template += '<input id="buyer" type="text" placeholder="buyer" name="buyer">';
    template += '<button type="submit" id="create_gun_submit">Submit</submit> ';
    template += '</form>
';

    $("#output").html(template);

    $("#create_gun_submit").click(function(e){
      e.preventDefault();
      gunObj = {
        manufacturer: $("#manufacturer").val(),
        model: $("#model").val(),
        chambering: $("#chambering").val(),
        type: $("#type").val(),
        serial_number: $("#serial_number").val(),
        image: $("#image").val(),
        value: $("#value").val(),
        sold: $("#sold").val(),
        buyer: $("#buyer").val()
      }
      var newGunData =   $("#manufacturer").val();
      console.log("From showmenu() ",gunObj);
      gunDbTalk(gunObj);
    })
  })  //end of #create_gun listener

  // Search for a gun in the state.guns object
  $("#read_gun").click(function(){
    console.log('Find gun clicked')
  })

  $("#update_gun").click(function(){
    console.log('Update gun clicked')
  })

  $("#delete_gun").click(function(){
    console.log('Delete gun clicked')
  })

}  // end of showMenu()
<commit_msg>working on find capability. making progress.<commit_after>//########################################################
//###############   STATE OBJECT and CONSTANTS  ##########
//########################################################
const state = {
  guns: []
}

//var template = '';

const rootURL = 'http://localhost:8080/guns';

//const rootURL = 'https://firearmbase.herokuapp.com/guns';

//#########################################################
//#################  STATE MODIFICATION METHODS  ##########
//#########################################################

function getAllGuns() {
  return new Promise(function (res, rej) {
    $.ajax({
      url: rootURL,
      type: "GET",
      headers: {
        "accept": "application/jsonp;odata=verbose",
      },
      success: function(gundata) {
        var num=0;
        gundata.forEach( gun => {
          //state.guns[gun.fullName] = gun;
          state.guns[num] = gun;
          num++;
        });
        console.log('StateObject: ',state.guns);
        res();
      },
      error: function(error){
        console.log('error: ',error);
      }
    })
  })
  return state;
}

getAllGuns()
.then(showMenu);

//#########################################################
//#################  DOM MODIFICATION METHODS  ############
//#########################################################

function outputGunsReport() {
  // return new Promise( (res, rej) => {
    var template = '
';
    state.guns.forEach( gun => {
      console.log('ONE: ', typeof gun);
      template += '
'+gun.fullName+'
';
    })
    template += '<button id="home_page">Home</button>';
    template += '
';
    console.log('state.guns object ', state.guns);
    $("#output").html(template);
    $("#home_page").click(function(){
      showMenu();
    })
  // });
}

//#########################################################
//#################  DATABASE METHODS      ################
//#########################################################

function gunDbTalk(gunData, http_method){
  console.log('gunTalk ', gunData);
  if (gunData.id) myURL = rootURL + "/" + gunData.id;
  else myURL = rootURL;
    $.ajax({
      url: myURL,
      type: http_method,
      headers: {
        "accept": "application/json;odata=verbose",
      },
      data: JSON.stringify(gunData),
      contentType: "application/json; charset=utf-8",
      dataType: 'json',
      success: function(gundata) {

        //console.log('StateObject: ',state.guns);
        console.log('HEY!  Object: ',gundata);
        // res();
      },
      error: function(error){
        console.log('error: ',error);
      }
    })
  getAllGuns();
  showMenu();
}

//#########################################################
//#################  PROGRAM CONTROL FLOW  ################
//#########################################################

//This function shows the opening menu
function showMenu(){
  var template = '
'
  template += '<button id="list_all">List All Guns</button>';
  template += '<button id="create_gun">Add Gun</button>';
  template += '<button id="read_gun">Find Gun</button>';
  template += '<button id="update_gun">Modify Gun</button>';
  template += '<button id="delete_gun">Delete Gun</button>';
  template += '
';

  $("#output").html(template);

  // List all guns
  $("#list_all").click(function(){
    outputGunsReport();
  })

  // Add a gun to database
  $("#create_gun").click(function(){
    //console.log('Create_gun clicked')

    var template = `<div><form>`;
    template += '<input id="manufacturer" type="text" placeholder="manufacturer" name="manufacturer">';
    template += '<input id="model"  type="text" placeholder="model" name="model">';
    template += '<input id="chambering"  type="text" placeholder="chambering" name="chambering">';
    template += '<input id="type" type="text" placeholder="type" name="type">';
    template += '<input  id="serial_number" type="text" placeholder="serial_number" name="serial_number">';
    template += '<input id="image" type="text" placeholder="image" name="image">'
    template += '<input id="value" type="text" placeholder="value" name="value">';
    template += '<input id="sold" type="text" placeholder="sold" name="sold">';
    template += '<input id="buyer" type="text" placeholder="buyer" name="buyer">';
    template += '<button type="submit" id="create_gun_submit">Submit</submit> ';
    template += '</form>
';

    $("#output").html(template);

    $("#create_gun_submit").click(function(e){
      e.preventDefault();
      gunObj = {
        manufacturer: $("#manufacturer").val(),
        model: $("#model").val(),
        chambering: $("#chambering").val(),
        type: $("#type").val(),
        serial_number: $("#serial_number").val(),
        image: $("#image").val(),
        value: $("#value").val(),
        sold: $("#sold").val(),
        buyer: $("#buyer").val()
      }

      console.log("From showmenu() ",gunObj);
      gunDbTalk(gunObj, "POST");
    })
  })  //end of #create_gun listener

  //Search for a gun in the state.guns object
  $("#read_gun").click(function(){
    console.log('Find gun clicked')
    var template = `<div><form>`;
    template += '<input id="manufacturer" type="text" placeholder="manufacturer" name="manufacturer">';
    template += '<input id="model"  type="text" placeholder="model" name="model">';
    template += '<input id="chambering"  type="text" placeholder="chambering" name="chambering">';
    template += '<input id="type" type="text" placeholder="type" name="type">';
    template += '<input  id="serial_number" type="text" placeholder="serial_number" name="serial_number">';
    template += '<input id="image" type="text" placeholder="image" name="image">'
    template += '<input id="value" type="text" placeholder="value" name="value">';
    template += '<input id="sold" type="text" placeholder="sold" name="sold">';
    template += '<input id="buyer" type="text" placeholder="buyer" name="buyer">';
    template += '<button type="submit" id="search_gun_submit">Submit</submit> ';
    template += '</form>
';

    $("#output").html(template);

    $("#search_gun_submit").click(function(e){
      e.preventDefault();
      gunObj = {
        manufacturer: $("#manufacturer").val(),
        model: $("#model").val(),
        chambering: $("#chambering").val(),
        type: $("#type").val(),
        serial_number: $("#serial_number").val(),
        image: $("#image").val(),
        value: $("#value").val(),
        sold: $("#sold").val(),
        buyer: $("#buyer").val()
      }

      console.log("From findGun ",gunObj);

      var searchObj = {};
      var searchList = [];
      for (key in gunObj) {
        if (key) { searchObj[key] = gunObj[key]; }
        state.guns.forEach(function(gun) {
          if (gun[key] === searchObj[key]) {
            searchList.push(gun.id);
            console.log('Gun ID: ',gun.id,'fullName: ',gun.fullName);
          }
        })
      }

      console.log(searchList);
    })

  })  //end of searchgun menu pick

  $("#read_gun").click(function() {
    //var gunid = state.guns[0].id;
    //obj = { id: gunid };
    //gunDbTalk(obj, "GET");
    //console.log("I read this gun: ",value);
  });

  $("#update_gun").click(function(){
    console.log('Update gun clicked')
  })

  $("#delete_gun").click(function(){
    console.log('Delete gun clicked')
  })

}  // end of showMenu()
<|endoftext|>


<commit_before>window.addEventListener("load", eventWindowLoaded, false);
function eventWindowLoaded() {
    canvasApp();
}

function canvasApp() {
    var MOMENTUM_TRANSFER_RATE = 0.8;  // the rate only applies to the momentum difference, not the full momentum

    var Vector = function Vector(x, y, move_x, move_y) {
        this.x = x;
        this.y = y;
        var c = Math.sqrt(move_x*move_x + move_y*move_y);
        this.move_x = move_x / c;  // should be stored as a regularized x value
        this.move_y = move_y / c;  // should be stored as a regularized y123123 value
    };
    Vector.prototype.nextPosition = function(momentum) {
        this.x += momentum * this.move_x;
        this.y += momentum * this.move_y;
    };
    Vector.prototype.reflect = function(run, rise) {  // reflects the slope of the particle over the slope given
        var theta = Math.atan(rise / run);
        var phi = Math. atan(rise / run);
        var alpha = Math.abs(theta - phi);
        this.move_y = Math.sin(theta - alpha);
        this.move_x = Math.cos(theta - alpha);
    };

    var Particle = function Particle(vector, velocity, mass, radius) {
        this.vector = vector;
        this.velocity = velocity;
        this.mass = mass;
        this.radius = radius;
    };
    Particle.prototype.collide = function(other) {
        // the other argument will eventually need to be an array of Particles, which are all colliding with this one
        var rise = -(other.x - this.x);
        var run = other.y - this.y;
        this.reflect(run, rise);
        other.reflect(run, rise);
        this_velocity = ((this.velocity * this.mass) + (other.velocity * other.mass) +
                        ((1 - MOMENTUM_TRANSFER_RATE) * Math.abs((this.velocity * this.mass) - (other.velocity * other.mass))))
                        / (2 * this.mass);
        other_velocity = ((this.mass * this_velocity) -
                         (1 - MOMENTUM_TRANSFER_RATE) * Math.abs((this.velocity * this.mass) - (other.velocity * other.mass)))
                         / other.mass;
        this.velocity = this_velocity;
        other.velocity = other_velocity;
    };
    Particle.prototype.move = function() {
        this.vector.nextPosition();
        // check for collisions with other particles, and then call collision if they have collided. The method needs to be
        // reworked in case more than two particles collide at once
    };

    var Clump = function() {
        this.particles = [];
    };
    Clump.prototype.addParticle = function(particle) {};
    Clump.prototype.order = function() {};

    drawScreen();

    function drawScreen() {
        var space = document.getElementById("space");
        if(!space || !space.getContext) {
            return;
        }
        var context = space.getContext("2d");
        context.fillStyle = "#ff0000";
        context.fillRect(0, 0, 500, 300)
    }
}
<commit_msg>corrected collision method<commit_after>window.addEventListener("load", eventWindowLoaded, false);
function eventWindowLoaded() {
    canvasApp();
}

function canvasApp() {
    var MOMENTUM_TRANSFER_RATE = 0.8;

    var Vector = function Vector(x, y, move_x, move_y) {
        this.x = x;
        this.y = y;
        var c = Math.sqrt(move_x*move_x + move_y*move_y);
        this.move_x = move_x / c;  // should be stored as a regularized x value
        this.move_y = move_y / c;  // should be stored as a regularized y123123 value
    };
    Vector.prototype.nextPosition = function(momentum) {
        this.x += momentum * this.move_x;
        this.y += momentum * this.move_y;
    };
    Vector.prototype.reflect = function(run, rise) {  // reflects the slope of the particle over the slope given
        var theta = Math.atan(rise / run);
        var phi = Math. atan(rise / run);
        var alpha = Math.abs(theta - phi);
        this.move_y = Math.sin(theta - alpha);
        this.move_x = Math.cos(theta - alpha);
    };

    var Particle = function Particle(vector, velocity, mass, radius) {
        this.vector = vector;
        this.velocity = velocity;
        this.mass = mass;
        this.radius = radius;
    };
    Particle.prototype.collide = function(other) {
        // the other argument will eventually need to be an array of Particles, which are all colliding with this one
        // var rise = -(other.x - this.x);
        // var run = other.y - this.y;
        // this.reflect(run, rise);
        // other.reflect(run, rise);
        // this_velocity = ((this.velocity * this.mass) + (other.velocity * other.mass) +
        //                 ((1 - MOMENTUM_TRANSFER_RATE) * Math.abs((this.velocity * this.mass) - (other.velocity * other.mass))))
        //                 / (2 * this.mass);
        // other_velocity = ((this.mass * this_velocity) -
        //                  (1 - MOMENTUM_TRANSFER_RATE) * Math.abs((this.velocity * this.mass) - (other.velocity * other.mass)))
        //                  / other.mass;
        // this.velocity = this_velocity;
        // other.velocity = other_velocity;

        var rise = -(other.x - this.x);
        var run = other.y - this.y;
        this.reflect(run, rise);
        other.reflect(run, rise);
        this_velocity = ((MOMETUM_TRANSFER_RATE * other.velocity * other.mass) +
                        ((1 - MOMENTUM_TRANSFER_RATE) * this.velocity * this.mass)) /
                        this.mass
        other_velocity = ((MOMETUM_TRANSFER_RATE * this.velocity * this.mass) +
                         ((1 - MOMENTUM_TRANSFER_RATE) * other.velocity * other.mass)) /
                         other.mass
        this.velocity = this_velocity;
        other.velocity = other_velocity;
    };
    Particle.prototype.move = function() {
        this.vector.nextPosition();
        // check for collisions with other particles, and then call collision if they have collided. The method needs to be
        // reworked in case more than two particles collide at once
    };

    var Clump = function() {
        this.particles = [];
    };
    Clump.prototype.addParticle = function(particle) {};
    Clump.prototype.order = function() {};

    drawScreen();

    function drawScreen() {
        var space = document.getElementById("space");
        if(!space || !space.getContext) {
            return;
        }
        var context = space.getContext("2d");
        context.fillStyle = "#ff0000";
        context.fillRect(0, 0, 500, 300)
    }
}
<|endoftext|>


<commit_before>/*global
    Thorax:true,
    $serverSide,
    assignTemplate, createError, createInheritVars, createRegistryWrapper, getValue,
    inheritVars, resetInheritVars,
    ServerMarshal
*/

// Provide default behavior for client-failover
if (typeof $serverSide === 'undefined') {
  window.$serverSide = false;
}

var isIE11 = !!navigator.userAgent.match(/Trident\/7\./);
var isIE = isIE11 || (/msie [\w.]+/).exec(navigator.userAgent.toLowerCase());

//support zepto.forEach on jQuery
if (!$.fn.forEach) {
  $.fn.forEach = function(iterator, context) {
    $.fn.each.call(this, function(index) {
      iterator.call(context || this, this, index);
    });
  };
}

var viewNameAttributeName = 'data-view-name',
    viewCidAttributeName = 'data-view-cid',
    viewHelperAttributeName = 'data-view-helper',

    // Used to identify views that can be restored vs. rerendered on the client side.
    // Values are:
    //  - true - Can be restored
    //  - false - Must be rerendered
    //  - Omitted - Normal HTML element without associated view
    viewRestoreAttribute = 'data-view-restore';

//view instances
var viewsIndexedByCid = {};

if (!Handlebars.templates) {
  Handlebars.templates = {};
}

var Thorax = this.Thorax = {
  templatePathPrefix: '',
  //view classes
  Views: {},

  // Allows tagging of sections of code with a name for debugging purposes.
  // This or onException should be overriden to allow for reporting exceptions to analytics servers
  // or integration with libraries such as Costanza.
  bindSection: function(name, info, callback) {
    if (!callback) {
      callback = info;
      info = undefined;
    }
    return function() {
      try {
        return callback.apply(this, arguments);
      } catch (err) {
        Thorax.onException(name, err, info);
      }
    };
  },
  runSection: function(name, info, callback) {
    return Thorax.bindSection(name, info, callback)();
  },

  onException: function(name, err /* , info */) {
    throw err;
  },

  //deprecated, here to ensure existing projects aren't mucked with
  templates: Handlebars.templates
};

Thorax.View = Backbone.View.extend({
  constructor: function ThoraxView(options) {
    // store first argument for configureView()
    this._constructorArg = options;
    var response = Backbone.View.call(this, options);
    this._constructorArg = undefined;

    _.each(inheritVars, function(obj) {
      if (obj.ctor) {
        obj.ctor(this, response);
      }
    }, this);
    return response;
  },

  toString: function() {
    return '[object View.' + this.name + ']';
  },

  // View configuration, _configure was removed
  // in Backbone 1.1, define _configure as a noop
  // for Backwards compatibility with 1.0 and earlier
  _configure: function() {},
  _ensureElement: function () {
    configureView(this);

    if (!$serverSide && this.el) {
      var $el = $(_.result(this, 'el'));
      if ($el.length && ($el.attr('data-view-restore') === 'true')) {
        return this.restore($el);
      }
    }

    return Backbone.View.prototype._ensureElement.call(this);
  },

  setElement : function(element, delegate) {
    var $element = $(element),
        existingCid = $element.attr('data-view-cid');
    if (existingCid) {
      this._assignCid(existingCid);
    }
    var response = Backbone.View.prototype.setElement.call(this, $element, delegate);

    // Use a hash here to avoid multiple DOM operations
    var attr = {'data-view-cid': this.cid};
    if (this.name) {
      attr[viewNameAttributeName] = this.name;
    }
    this.$el.attr(attr);

    if (element.parentNode) {
      // This is a view that is attaching to an existing node and is unlikely to be added as
      // a children of any views. Assume that anyone doing this will manage the lifecycle
      // appropriately and destroy so we don't leak due to the `$.view` lookup that we are
      // registering here.
      this.retain();
    }

    return response;
  },
  _assignCid: function(cid) {
    if (this.cid && viewsIndexedByCid[this.cid]) {
      delete viewsIndexedByCid[this.cid];
      viewsIndexedByCid[cid] = this;
    }

    if (this.parent) {
      delete this.parent.children[this.cid];
      this.parent.children[cid] = this;
    }

    this.cid = cid;
  },

  _addChild: function(view) {
    if (this.children[view.cid]) {
      return view;
    }

    view.retain();
    this.children[view.cid] = view;
    // _helperOptions is used to detect if is HelperView
    // we do not want to remove child in this case as
    // we are adding the HelperView to the declaring view
    // (whatever view used the view helper in it's template)
    // but it's parent will not equal the declaring view
    // in the case of a nested helper, which will cause an error.
    // In either case it's not necessary to ever call
    // _removeChild on a HelperView as _addChild should only
    // be called when a HelperView is created.
    if (view.parent && view.parent !== this && !view._helperOptions) {
      view.parent._removeChild(view);
    }
    view.parent = this;
    this.trigger('child', view);
    return view;
  },

  _removeChild: function(view) {
    delete this.children[view.cid];
    view.parent = null;
    view.release();
    return view;
  },

  _destroy: function() {
    this.trigger('destroyed');
    delete viewsIndexedByCid[this.cid];

    this.stopListening();
    this.off();

    _.each(this.children, function(child) {
      child.parent = null;
      child.release();
    });

    if (this.el) {
      this.undelegateEvents();
      this.$el.remove();

      ServerMarshal.destroy(this.$el);
    }

    // Absolute worst case scenario, kill off some known fields to minimize the impact
    // of being retained.
    this.el = this.$el =
      this.parent = this.children =
      this.model = this.collection = this._collection =
      this._boundDataObjectsByCid = this._objectOptionsByCid =
      this._helperOptions = undefined;
  },

  restore: function(element, forceRerender) {
    // Extract from $ objects if passed
    element = element[0] || element;

    if (this._renderCount) {
      // Ensure that we are registered to the right cid (this could have been reset previously)
      var oldCid = this.$el.attr('data-view-cid');
      if (this.cid !== oldCid) {
        this._assignCid(oldCid);
      }

      $(element).replaceWith(this.$el);

      this.trigger('restore:fail', {
        type: 'previously-rendered',
        view: this,
        element: element
      });
      return;
    }

    this.setElement(element);

    var restoreable = this.$el.attr('data-view-restore') === 'true';
    this.$el.removeAttr('data-view-restore');

    if (!$serverSide && restoreable) {
      // Ensure that our associated template is wired up so that helpers who need to
      // resolve template children are able to do so.
      assignTemplate(this, 'template', {
        required: false
      });

      this._renderCount = 1;
      this.trigger('restore', forceRerender);

      if (forceRerender) {
        // We have an explicit rerender that we wanted to defer until the end of the restore process
        this.render();
      } else {
        // Check to see if we are in a partial restore situation
        var remainingViews = this.$('[data-view-restore]'),
            rerender = _.filter(remainingViews, function(el) {
              // Ignore views that are deeply nested or views that are under a layout element
              // when checking to see if we need to rerender.
              var parent = $(el).parent();
              return !parent.attr('data-layout-cid') && (parent.view({el: true, helper: true})[0] === element);
            });
        if (rerender.length) {
          this.trigger('restore:fail', {
            type: 'remaining',
            view: this,
            element: element,
            rerendered: rerender
          });

          this.render();
        }
      }

      this.trigger('after-restore', forceRerender);

      return true;
    } else {
      this.trigger('restore:fail', {
        type: 'not-restorable',
        view: this,
        element: element
      });

      this.render();
    }
  },

  render: function(output) {
    var self = this;
    // NOP for destroyed views
    if (!self.el) {
      return self;
    }

    function render() {
      if (self._rendering) {
        // Nested rendering of the same view instances can lead to some very nasty issues with
        // the root render process overwriting any updated data that may have been output in the child
        // execution. If in a situation where you need to rerender in response to an event that is
        // triggered sync in the rendering lifecycle it's recommended to defer the subsequent render
        // or refactor so that all preconditions are known prior to exec.
        throw createError('nested-render');
      }

      var children = {},
          previous = [];
      _.each(self.children, function(child, key) {
        if (!child._helperOptions) {
          children[key] = child;
        } else {
          child._cull = true;
          previous.push(child);
        }
      });
      self.children = children;
      self._previousHelpers = previous;

      self.trigger('before:rendered');
      self._rendering = true;

      if (_.isUndefined(output) || (!_.isElement(output) && !Thorax.Util.is$(output) && !(output && output.el) && !_.isString(output) && !_.isFunction(output))) {
        // try one more time to assign the template, if we don't
        // yet have one we must raise
        assignTemplate(self, 'template', {
          required: true
        });
        output = self.renderTemplate(self.template);
      } else if (_.isFunction(output)) {
        output = self.renderTemplate(output);
      }

      // Destroy any helpers that may be lingering
      _.each(previous, function(child) {
        if (child._cull) {
          self._removeChild(child);
        }
      });
      self._previousHelpers = undefined;

      if ($serverSide) {
        if (self.$el.attr(viewRestoreAttribute) !== 'false') {
          self.$el.attr(viewRestoreAttribute, $serverSide);
        }
      } else {
        self.$el.removeAttr(viewRestoreAttribute);
      }

      //accept a view, string, Handlebars.SafeString or DOM element
      self.html((output && output.el) || (output && output.string) || output);

      ++self._renderCount;

      self.trigger('rendered');
    }

    Thorax.runSection('thorax-render', {name: self.name}, function() {
      try {
        render();
      } finally {
        self._rendering = false;
      }
    });
    return self;
  },

  context: function() {
    return this.model && this.model.attributes;
  },

  _getContext: function() {
    var context = Object.create ? Object.create(this) : _.clone(this);
    return _.extend(context, this.context.call ? this.context() : this.context);
  },

  // Private variables in handlebars / options.data in template helpers
  _getData: function(data) {
    return {
      view: this,
      root: data,
      cid: _.uniqueId('t'),
      yield: function() {
        // fn is seeded by template helper passing context to data
        return data.fn && data.fn(data);
      }
    };
  },

  renderTemplate: function(file, context, ignoreErrors) {
    var template;
    if (_.isFunction(file)) {
      template = file;
    } else {
      template = Thorax.Util.getTemplate(file, ignoreErrors);
    }
    if (!template || template === Handlebars.VM.noop) {
      return '';
    } else {
      context = context || this._getContext();

      return template(context, {
        helpers: this.helpers,
        data: this._getData(context)
      });
    }
  },

  ensureRendered: function() {
    !this._renderCount && this.render();
  },
  shouldRender: function(flag) {
    // Render if flag is truthy or if we have already rendered and flag is undefined/null
    return flag || (flag == null && this._renderCount);
  },
  conditionalRender: function(flag) {
    if (this.shouldRender(flag)) {
      this.render();
    }
  },

  appendTo: function(el) {
    this.ensureRendered();
    $(el).append(this.el);
    this.trigger('ready', {target: this});
  },

  html: function(html) {
    if (_.isUndefined(html)) {
      return this.$el.html();
    } else {
      this.trigger('before:append');
      var element = this._replaceHTML(html);
      this.trigger('append');
      return element;
    }
  },

  release: function() {
    --this._referenceCount;
    if (this._referenceCount <= 0) {
      this._destroy();
    }
  },

  retain: function(owner) {
    if (!viewsIndexedByCid[this.cid]) {
      // Register with the `$.view` helper.
      viewsIndexedByCid[this.cid] = this;
    }

    ++this._referenceCount;
    if (owner) {
      // Not using listenTo helper as we want to run once the owner is destroyed
      this.listenTo(owner, 'destroyed', owner.release);
    }
  },

  _replaceHTML: function(html) {
    // We want to pull our elements out of the tree if we are under jQuery
    // or IE as both have the tendancy to mangle the elements we want to reuse
    // on cleanup. This could leak event binds if users are performing custom binds
    // but this generally not recommended.
    if (this._renderCount && (isIE || $.fn.jquery)) {
      while (this.el.hasChildNodes()) {
        this.el.removeChild(this.el.childNodes[0]);
      }
    }

    this.$el.empty();
    return this.$el.append(html);
  },

  _anchorClick: function(event) {
    var target = $(event.currentTarget),
        href = target.attr('href');

    // Don't push if meta or shift key are clicked
    if (event.metaKey || event.shiftKey) {
      return true;
    }

    // Route anything that starts with # or / (excluding //domain urls)
    if (href && (href[0] === '#' || (href[0] === '/' && href[1] !== '/'))) {
      Backbone.history.navigate(href, {
        trigger: true
      });
      return false;
    }
    return true;
  }
});

Thorax.View.extend = function() {
  createInheritVars(this);

  var child = Backbone.View.extend.apply(this, arguments);
  child.__parent__ = this;

  resetInheritVars(child);

  return child;
};

createRegistryWrapper(Thorax.View, Thorax.Views);

function configureView(view) {
  var options = view._constructorArg;

  view._referenceCount = 0;

  view._objectOptionsByCid = {};
  view._boundDataObjectsByCid = {};

  // Setup object event tracking
  _.each(inheritVars, function(obj) {
    view[obj.name] = [];
  });

  view.children = {};
  view._renderCount = 0;

  //this.options is removed in Thorax.View, we merge passed
  //properties directly with the view and template context
  if (options) {
    _.extend(view, options);
  }

  // Setup helpers
  bindHelpers(view);

  _.each(inheritVars, function(obj) {
    if (obj.configure) {
      obj.configure(view);
    }
  });

  view.trigger('configure');
}

function bindHelpers(view) {
  if (view.helpers) {
    _.each(view.helpers, function(helper, name) {
      view.helpers[name] = function() {
        var args = _.toArray(arguments),
            options = _.last(args);
        options.context = this;
        return helper.apply(view, args);
      };
    });
  }
}

//$(selector).view() helper
$.fn.view = function(options) {
  options = _.defaults(options || {}, {
    helper: true
  });
  var selector = '[' + viewCidAttributeName + ']';
  if (!options.helper) {
    selector += ':not([' + viewHelperAttributeName + '])';
  }
  var el = $(this).closest(selector);
  if (el) {
    if (options.el) {
      return el;
    } else {
      var cid = el.attr(viewCidAttributeName),
          view = viewsIndexedByCid[cid];
      if (!view) {
        throw createError('fn-view-unregistered');
      }
      return view;
    }
  } else {
    return false;
  }
};
<commit_msg>Provide setImmediate shim<commit_after>/*global
    Thorax:true,
    $serverSide,
    assignTemplate, createError, createInheritVars, createRegistryWrapper, getValue,
    inheritVars, resetInheritVars,
    ServerMarshal
*/

// Provide default behavior for client-failover
if (typeof $serverSide === 'undefined') {
  window.$serverSide = false;
}

var isIE11 = !!navigator.userAgent.match(/Trident\/7\./);
var isIE = isIE11 || (/msie [\w.]+/).exec(navigator.userAgent.toLowerCase());

//support zepto.forEach on jQuery
if (!$.fn.forEach) {
  $.fn.forEach = function(iterator, context) {
    $.fn.each.call(this, function(index) {
      iterator.call(context || this, this, index);
    });
  };
}

var setImmediate = window.setImmediate || function(callback) {
  setTimeout(callback, 0);
};

var viewNameAttributeName = 'data-view-name',
    viewCidAttributeName = 'data-view-cid',
    viewHelperAttributeName = 'data-view-helper',

    // Used to identify views that can be restored vs. rerendered on the client side.
    // Values are:
    //  - true - Can be restored
    //  - false - Must be rerendered
    //  - Omitted - Normal HTML element without associated view
    viewRestoreAttribute = 'data-view-restore';

//view instances
var viewsIndexedByCid = {};

if (!Handlebars.templates) {
  Handlebars.templates = {};
}

var Thorax = this.Thorax = {
  templatePathPrefix: '',
  //view classes
  Views: {},

  // Allows tagging of sections of code with a name for debugging purposes.
  // This or onException should be overriden to allow for reporting exceptions to analytics servers
  // or integration with libraries such as Costanza.
  bindSection: function(name, info, callback) {
    if (!callback) {
      callback = info;
      info = undefined;
    }
    return function() {
      try {
        return callback.apply(this, arguments);
      } catch (err) {
        Thorax.onException(name, err, info);
      }
    };
  },
  runSection: function(name, info, callback) {
    return Thorax.bindSection(name, info, callback)();
  },

  onException: function(name, err /* , info */) {
    throw err;
  },

  //deprecated, here to ensure existing projects aren't mucked with
  templates: Handlebars.templates
};

Thorax.View = Backbone.View.extend({
  constructor: function ThoraxView(options) {
    // store first argument for configureView()
    this._constructorArg = options;
    var response = Backbone.View.call(this, options);
    this._constructorArg = undefined;

    _.each(inheritVars, function(obj) {
      if (obj.ctor) {
        obj.ctor(this, response);
      }
    }, this);
    return response;
  },

  toString: function() {
    return '[object View.' + this.name + ']';
  },

  // View configuration, _configure was removed
  // in Backbone 1.1, define _configure as a noop
  // for Backwards compatibility with 1.0 and earlier
  _configure: function() {},
  _ensureElement: function () {
    configureView(this);

    if (!$serverSide && this.el) {
      var $el = $(_.result(this, 'el'));
      if ($el.length && ($el.attr('data-view-restore') === 'true')) {
        return this.restore($el);
      }
    }

    return Backbone.View.prototype._ensureElement.call(this);
  },

  setElement : function(element, delegate) {
    var $element = $(element),
        existingCid = $element.attr('data-view-cid');
    if (existingCid) {
      this._assignCid(existingCid);
    }
    var response = Backbone.View.prototype.setElement.call(this, $element, delegate);

    // Use a hash here to avoid multiple DOM operations
    var attr = {'data-view-cid': this.cid};
    if (this.name) {
      attr[viewNameAttributeName] = this.name;
    }
    this.$el.attr(attr);

    if (element.parentNode) {
      // This is a view that is attaching to an existing node and is unlikely to be added as
      // a children of any views. Assume that anyone doing this will manage the lifecycle
      // appropriately and destroy so we don't leak due to the `$.view` lookup that we are
      // registering here.
      this.retain();
    }

    return response;
  },
  _assignCid: function(cid) {
    if (this.cid && viewsIndexedByCid[this.cid]) {
      delete viewsIndexedByCid[this.cid];
      viewsIndexedByCid[cid] = this;
    }

    if (this.parent) {
      delete this.parent.children[this.cid];
      this.parent.children[cid] = this;
    }

    this.cid = cid;
  },

  _addChild: function(view) {
    if (this.children[view.cid]) {
      return view;
    }

    view.retain();
    this.children[view.cid] = view;
    // _helperOptions is used to detect if is HelperView
    // we do not want to remove child in this case as
    // we are adding the HelperView to the declaring view
    // (whatever view used the view helper in it's template)
    // but it's parent will not equal the declaring view
    // in the case of a nested helper, which will cause an error.
    // In either case it's not necessary to ever call
    // _removeChild on a HelperView as _addChild should only
    // be called when a HelperView is created.
    if (view.parent && view.parent !== this && !view._helperOptions) {
      view.parent._removeChild(view);
    }
    view.parent = this;
    this.trigger('child', view);
    return view;
  },

  _removeChild: function(view) {
    delete this.children[view.cid];
    view.parent = null;
    view.release();
    return view;
  },

  _destroy: function() {
    this.trigger('destroyed');
    delete viewsIndexedByCid[this.cid];

    this.stopListening();
    this.off();

    _.each(this.children, function(child) {
      child.parent = null;
      child.release();
    });

    if (this.el) {
      this.undelegateEvents();
      this.$el.remove();

      ServerMarshal.destroy(this.$el);
    }

    // Absolute worst case scenario, kill off some known fields to minimize the impact
    // of being retained.
    this.el = this.$el =
      this.parent = this.children =
      this.model = this.collection = this._collection =
      this._boundDataObjectsByCid = this._objectOptionsByCid =
      this._helperOptions = undefined;
  },

  restore: function(element, forceRerender) {
    // Extract from $ objects if passed
    element = element[0] || element;

    if (this._renderCount) {
      // Ensure that we are registered to the right cid (this could have been reset previously)
      var oldCid = this.$el.attr('data-view-cid');
      if (this.cid !== oldCid) {
        this._assignCid(oldCid);
      }

      $(element).replaceWith(this.$el);

      this.trigger('restore:fail', {
        type: 'previously-rendered',
        view: this,
        element: element
      });
      return;
    }

    this.setElement(element);

    var restoreable = this.$el.attr('data-view-restore') === 'true';
    this.$el.removeAttr('data-view-restore');

    if (!$serverSide && restoreable) {
      // Ensure that our associated template is wired up so that helpers who need to
      // resolve template children are able to do so.
      assignTemplate(this, 'template', {
        required: false
      });

      this._renderCount = 1;
      this.trigger('restore', forceRerender);

      if (forceRerender) {
        // We have an explicit rerender that we wanted to defer until the end of the restore process
        this.render();
      } else {
        // Check to see if we are in a partial restore situation
        var remainingViews = this.$('[data-view-restore]'),
            rerender = _.filter(remainingViews, function(el) {
              // Ignore views that are deeply nested or views that are under a layout element
              // when checking to see if we need to rerender.
              var parent = $(el).parent();
              return !parent.attr('data-layout-cid') && (parent.view({el: true, helper: true})[0] === element);
            });
        if (rerender.length) {
          this.trigger('restore:fail', {
            type: 'remaining',
            view: this,
            element: element,
            rerendered: rerender
          });

          this.render();
        }
      }

      this.trigger('after-restore', forceRerender);

      return true;
    } else {
      this.trigger('restore:fail', {
        type: 'not-restorable',
        view: this,
        element: element
      });

      this.render();
    }
  },

  render: function(output) {
    var self = this;
    // NOP for destroyed views
    if (!self.el) {
      return self;
    }

    function render() {
      if (self._rendering) {
        // Nested rendering of the same view instances can lead to some very nasty issues with
        // the root render process overwriting any updated data that may have been output in the child
        // execution. If in a situation where you need to rerender in response to an event that is
        // triggered sync in the rendering lifecycle it's recommended to defer the subsequent render
        // or refactor so that all preconditions are known prior to exec.
        throw createError('nested-render');
      }

      var children = {},
          previous = [];
      _.each(self.children, function(child, key) {
        if (!child._helperOptions) {
          children[key] = child;
        } else {
          child._cull = true;
          previous.push(child);
        }
      });
      self.children = children;
      self._previousHelpers = previous;

      self.trigger('before:rendered');
      self._rendering = true;

      if (_.isUndefined(output) || (!_.isElement(output) && !Thorax.Util.is$(output) && !(output && output.el) && !_.isString(output) && !_.isFunction(output))) {
        // try one more time to assign the template, if we don't
        // yet have one we must raise
        assignTemplate(self, 'template', {
          required: true
        });
        output = self.renderTemplate(self.template);
      } else if (_.isFunction(output)) {
        output = self.renderTemplate(output);
      }

      // Destroy any helpers that may be lingering
      _.each(previous, function(child) {
        if (child._cull) {
          self._removeChild(child);
        }
      });
      self._previousHelpers = undefined;

      if ($serverSide) {
        if (self.$el.attr(viewRestoreAttribute) !== 'false') {
          self.$el.attr(viewRestoreAttribute, $serverSide);
        }
      } else {
        self.$el.removeAttr(viewRestoreAttribute);
      }

      //accept a view, string, Handlebars.SafeString or DOM element
      self.html((output && output.el) || (output && output.string) || output);

      ++self._renderCount;

      self.trigger('rendered');
    }

    Thorax.runSection('thorax-render', {name: self.name}, function() {
      try {
        render();
      } finally {
        self._rendering = false;
      }
    });
    return self;
  },

  context: function() {
    return this.model && this.model.attributes;
  },

  _getContext: function() {
    var context = Object.create ? Object.create(this) : _.clone(this);
    return _.extend(context, this.context.call ? this.context() : this.context);
  },

  // Private variables in handlebars / options.data in template helpers
  _getData: function(data) {
    return {
      view: this,
      root: data,
      cid: _.uniqueId('t'),
      yield: function() {
        // fn is seeded by template helper passing context to data
        return data.fn && data.fn(data);
      }
    };
  },

  renderTemplate: function(file, context, ignoreErrors) {
    var template;
    if (_.isFunction(file)) {
      template = file;
    } else {
      template = Thorax.Util.getTemplate(file, ignoreErrors);
    }
    if (!template || template === Handlebars.VM.noop) {
      return '';
    } else {
      context = context || this._getContext();

      return template(context, {
        helpers: this.helpers,
        data: this._getData(context)
      });
    }
  },

  ensureRendered: function() {
    !this._renderCount && this.render();
  },
  shouldRender: function(flag) {
    // Render if flag is truthy or if we have already rendered and flag is undefined/null
    return flag || (flag == null && this._renderCount);
  },
  conditionalRender: function(flag) {
    if (this.shouldRender(flag)) {
      this.render();
    }
  },

  appendTo: function(el) {
    this.ensureRendered();
    $(el).append(this.el);
    this.trigger('ready', {target: this});
  },

  html: function(html) {
    if (_.isUndefined(html)) {
      return this.$el.html();
    } else {
      this.trigger('before:append');
      var element = this._replaceHTML(html);
      this.trigger('append');
      return element;
    }
  },

  release: function() {
    --this._referenceCount;
    if (this._referenceCount <= 0) {
      this._destroy();
    }
  },

  retain: function(owner) {
    if (!viewsIndexedByCid[this.cid]) {
      // Register with the `$.view` helper.
      viewsIndexedByCid[this.cid] = this;
    }

    ++this._referenceCount;
    if (owner) {
      // Not using listenTo helper as we want to run once the owner is destroyed
      this.listenTo(owner, 'destroyed', owner.release);
    }
  },

  _replaceHTML: function(html) {
    // We want to pull our elements out of the tree if we are under jQuery
    // or IE as both have the tendancy to mangle the elements we want to reuse
    // on cleanup. This could leak event binds if users are performing custom binds
    // but this generally not recommended.
    if (this._renderCount && (isIE || $.fn.jquery)) {
      while (this.el.hasChildNodes()) {
        this.el.removeChild(this.el.childNodes[0]);
      }
    }

    this.$el.empty();
    return this.$el.append(html);
  },

  _anchorClick: function(event) {
    var target = $(event.currentTarget),
        href = target.attr('href');

    // Don't push if meta or shift key are clicked
    if (event.metaKey || event.shiftKey) {
      return true;
    }

    // Route anything that starts with # or / (excluding //domain urls)
    if (href && (href[0] === '#' || (href[0] === '/' && href[1] !== '/'))) {
      Backbone.history.navigate(href, {
        trigger: true
      });
      return false;
    }
    return true;
  }
});

Thorax.View.extend = function() {
  createInheritVars(this);

  var child = Backbone.View.extend.apply(this, arguments);
  child.__parent__ = this;

  resetInheritVars(child);

  return child;
};

createRegistryWrapper(Thorax.View, Thorax.Views);

function configureView(view) {
  var options = view._constructorArg;

  view._referenceCount = 0;

  view._objectOptionsByCid = {};
  view._boundDataObjectsByCid = {};

  // Setup object event tracking
  _.each(inheritVars, function(obj) {
    view[obj.name] = [];
  });

  view.children = {};
  view._renderCount = 0;

  //this.options is removed in Thorax.View, we merge passed
  //properties directly with the view and template context
  if (options) {
    _.extend(view, options);
  }

  // Setup helpers
  bindHelpers(view);

  _.each(inheritVars, function(obj) {
    if (obj.configure) {
      obj.configure(view);
    }
  });

  view.trigger('configure');
}

function bindHelpers(view) {
  if (view.helpers) {
    _.each(view.helpers, function(helper, name) {
      view.helpers[name] = function() {
        var args = _.toArray(arguments),
            options = _.last(args);
        options.context = this;
        return helper.apply(view, args);
      };
    });
  }
}

//$(selector).view() helper
$.fn.view = function(options) {
  options = _.defaults(options || {}, {
    helper: true
  });
  var selector = '[' + viewCidAttributeName + ']';
  if (!options.helper) {
    selector += ':not([' + viewHelperAttributeName + '])';
  }
  var el = $(this).closest(selector);
  if (el) {
    if (options.el) {
      return el;
    } else {
      var cid = el.attr(viewCidAttributeName),
          view = viewsIndexedByCid[cid];
      if (!view) {
        throw createError('fn-view-unregistered');
      }
      return view;
    }
  } else {
    return false;
  }
};
<|endoftext|>


<commit_before>(function(){
	var board = document.querySelector('#gameboard'),
		ROWS = 10,
		COLS = 10,
		TOTAL_TILES = ROWS * COLS;

	var clickHandler = function(e){
		swapClass(e.currentTarget,"wall");
	};

	var contextHandler = function(e){
		e.preventDefault();
		for(var i=0;i<TOTAL_TILES;i++){
			removeClass(board.children[i],"start");
		}

		removeClass(e.currentTarget,"wall");
		swapClass(e.currentTarget,"start");
		return;
	};

	// Initialize board
	var init = function(){
		for(var i=0;i<TOTAL_TILES;i++)
		{
			var el = document.createElement('div');
			el.id = i;
			el.className = 'tile';

			el.addEventListener("click",clickHandler);
			el.addEventListener("contextmenu",contextHandler);
			board.appendChild(el);

			// This is used to adjust rows/colums  number
			board.style.width = ROWS * 30 + "px";
		}
	};
	// Switch wall class for selected tile
	var swapClass = function(el,classname){
		var classes = el.className.split(" ");

		if(classes.indexOf(classname) === -1)
		{
		 	classes.push(classname);
		} else {
			var i = classes.indexOf(classname);
			classes.splice(i,1);
		}

		el.className = classes.join(" ");
	};

	var removeClass = function(el,classname){
		var classes = el.className.split(" "),
			i = classes.indexOf(classname);
		if(i !== -1)
		{
			classes.splice(i,1);
			console.log(classes);
			el.className = classes.join(" ");
		}
	}
	// Entry point
	init();
})();<commit_msg>Started floodfill method<commit_after>(function(){
	'use strict';
	var board = document.querySelector('#gameboard'),
		ROWS = 10,
		COLS = 10,
		TOTAL_TILES = ROWS * COLS;

	function clickHandler(e) {
		swapClass(e.currentTarget,"wall");
	}

	function contextHandler(e){
		e.preventDefault();
		for(var i=0;i<TOTAL_TILES;i++){
			removeClass(board.children[i],"start");
		}

		removeClass(e.currentTarget,"wall");
		swapClass(e.currentTarget,"start");
		return;
	}

	// Initialize board
	function init(){
		// Set board size
		board.style.width = COLS * 30 + "px";
		// Create tiles
		for(var i=0;i<TOTAL_TILES;i++)
		{
			var el = document.createElement('div');
			el.id = i;
			el.className = 'tile';

			el.addEventListener("click",clickHandler);
			el.addEventListener("contextmenu",contextHandler);
			board.appendChild(el);
		}

	}

	function start(){

	}

	function floodfill(element,currentType,targetType){
		if(currentType == targetType){
			return;
		}

		if(element.type != targetType){
			return;
		}
		// Do here whatever you want

		// Do floodfill recursively in 8 directions
		// pseudo-code: for each direction do floodfill();

		return;
	}

	// Switch wall class for selected tile
	function swapClass(el,classname){
		var classes = el.className.split(" ");

		if(classes.indexOf(classname) === -1)
		{
		 	classes.push(classname);
		} else {
			var i = classes.indexOf(classname);
			classes.splice(i,1);
		}

		el.className = classes.join(" ");
	}

	function removeClass(el,classname){
		var classes = el.className.split(" "),
			i = classes.indexOf(classname);
		if(i !== -1)
		{
			classes.splice(i,1);
			console.log(classes);
			el.className = classes.join(" ");
		}
	}
	// Entry point
	init();
})();<|endoftext|>


<commit_before>'use strict';

import sigma from "sigma";
import $ from "jquery";
import "fancybox";

var _sigma;
var $GP;

Object.size = obj => {
  var size = 0;
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      size++;
    }
  }
  return size;
};

$(document).ready(() => setupGUI());

function setupGUI() {
  $GP = {
    calculating: false,
  };
  $GP.info = $("#attributepane");
  $GP.info_donnees = $GP.info.find(".nodeattributes");
  $GP.info_name = $GP.info.find(".name");
  $GP.info_link = $GP.info.find(".link");
  $GP.info_data = $GP.info.find(".data");
  $GP.info_close = $GP.info.find(".returntext");
  $GP.info_close2 = $GP.info.find(".close");
  $GP.info_p = $GP.info.find(".p");
  $GP.info_close.click(nodeNormal);
  $GP.info_close2.click(nodeNormal);
  $GP.form = $("#mainpanel").find("form");
  $GP.search = new Search($GP.form.find("#search"));
  $GP.cluster = new Cluster($GP.form.find("#attributeselect"));
  initSigma();
}

function initSigma() {
  //noinspection JSPotentiallyInvalidConstructorUsage
  _sigma = new sigma({
    container: $('#sigma-canvas'),
    settings: {
      "defaultEdgeType": "curve",
      "defaultHoverLabelBGColor": "#002147",
      "labelThreshold": 10,
      "defaultLabelHoverColor": "#fff",
      "fontStyle": "bold",
      "hoverFontStyle": "bold",
      "zoomMax": 20,
      "zoomMin": 0.75
    }
  });

  _sigma.active = false;
  _sigma.neighbors = {};
  _sigma.detail = false;

  $.getJSON('data.json', data => {
    //noinspection JSUnresolvedFunction
    _sigma.graph.read(data);

    _sigma.clusters = {};

    //noinspection JSUnresolvedFunction
    for (var node of _sigma.graph.nodes()) {
      if (!_sigma.clusters[node.color]) {
        _sigma.clusters[node.color] = [];
      }
      _sigma.clusters[node.color].push(node.id);
    }

    //noinspection JSUnresolvedFunction
    _sigma.bind("clickNode", event => nodeActive(event.data.node));

    configSigmaElements();

    //noinspection JSUnresolvedFunction
    _sigma.refresh();
  });
}

function configSigmaElements() {
  var clustersHtml = [];
  var clusterNumber = 1;
  for (var cluster of _sigma.clusters) {
    clustersHtml.push('

'
      + ' Group ' + (clusterNumber++) + ' (' + cluster.length + ' members)
');
  }
  $GP.cluster.content(clustersHtml.join(""));

  //noinspection JSUnresolvedFunction
  $("a.fb").fancybox({
    minWidth: 400,
    maxWidth: 800,
    maxHeight: 600,
  });

  $("#zoom").find("div.z").each(() => {
    var rel = $(this).attr("rel");
    $(this).click(() => {
      if (rel == "center") {
        //noinspection JSUnresolvedFunction
        _sigma.cameras.goTo(0, 0, 1, 0);
      } else {
        //noinspection JSUnresolvedFunction
        _sigma.utils.zoomTo(0, 0, "in" == rel ? 1.5 : 0.5, 0);
      }
    });
  });

  var hashAnchor = window.location.hash.substr(1);
  if (0 < hashAnchor.length) {
    switch (hashAnchor) {
      case "information":
        $.fancybox.open($("#information"), cluster);
        break;
      default:
        $GP.search.exactMatch = $GP.search.search(hashAnchor);
        $GP.search.clean();
    }
  }
}

function Search(searchElem) {
  this.input = searchElem.find("input[name=search]");
  this.state = searchElem.find(".state");
  this.results = searchElem.find(".results");
  this.exactMatch = false;
  this.lastSearch = "";
  this.searching = false;
  this.input.focus(() => {
    if (!$(this).data("focus")) {
      $(this).data("focus", true);
      $(this).removeClass("empty");
    }
    this.clean();
  });
  this.input.keydown(event => {
    if (event.which == 13) {
      this.state.addClass("searching");
      this.search(this.input.val());
    }
  });
  this.state.click(() => {
    var stateValue = this.input.val();
    if (this.searching && stateValue == this.lastSearch) {
      this.close();
    } else {
      this.state.addClass("searching");
      this.search(stateValue);
    }
  });
  this.close = () => {
    this.state.removeClass("searching");
    this.results.hide();
    this.searching = false;
    this.input.val("");
    nodeNormal();
  };
  this.clean = () => {
    this.results.empty().hide();
    this.state.removeClass("searching");
    this.input.val("");
  };
  this.search = text => {
    var foundNodes = [];
    var textRegex = new RegExp(this.exactMatch ? ("^" + text + "$").toLowerCase() : text.toLowerCase());
    this.exactMatch = false;
    this.searching = true;
    this.lastSearch = text;
    this.results.empty();
    if (text.length <= 2) {
      this.results.html("El texto a buscar debe contener al menos 3 letras.");
    } else {
      //noinspection JSUnresolvedFunction
      for (var node of _sigma.graph.nodes()) {
        if (textRegex.test(node.label.toLowerCase())) {
          foundNodes.push(node);
        }
      }
      var output = ["Resultados encontrados: "];
      if (foundNodes.length == 0) {
        if (!showCluster(text)) {
          output.push("No se encontró ningún nodo.");
        }
      } else {
        nodeActive(foundNodes[0].id);
        if (foundNodes.length > 1) {
          for (var foundNode of foundNodes) {
            output.push('" + foundNode.label + "");
          }
        }
      }
      this.results.html(output.join(""));
    }
    foundNodes.length == 1 ? this.results.hide() : this.results.show();
  }
}

function Cluster(clusterElem) {
  this.cluster = clusterElem;
  this.display = false;
  this.list = this.cluster.find(".list");
  this.list.empty();
  this.select = this.cluster.find(".select");
  this.select.click(() => $GP.cluster.toggle());
  this.toggle = () => this.display ? this.hide() : this.show();
  this.content = html => {
    this.list.html(html);
    this.list.find("a").click(() => showCluster($(this).attr("href").substr(1)));
  };
  this.hide = () => {
    this.display = false;
    this.list.hide();
    this.select.removeClass("close");
  };
  this.show = () => {
    this.display = true;
    this.list.show();
    this.select.addClass("close");
  }
}

function nodeNormal() {
  if (!$GP.calculating && _sigma.detail) {
    $GP.calculating = true;
    _sigma.detail = true;
    //noinspection JSUnresolvedFunction
    $GP.info.delay(400).animate({width: 'hide'}, 350);
    $GP.cluster.hide();
    //noinspection JSUnresolvedFunction
    for (var edge of _sigma.graph.edges()) {
      edge.attr.color = false;
      edge.hidden = false;
    }
    //noinspection JSUnresolvedFunction
    for (var node of _sigma.graph.nodes()) {
      node.hidden = false;
      node.attr.color = false;
      node.attr.lineWidth = false;
      node.attr.size = false
    }
    //_sigma.draw(2, 2, 2, 2);
    //noinspection JSUnresolvedFunction
    _sigma.refresh();
    _sigma.neighbors = {};
    _sigma.active = false;
    $GP.calculating = false;
    window.location.hash = "";
  }
}

function nodeActive(nodeId) {
  _sigma.neighbors = {};
  _sigma.detail = true;
  var node = _sigma.graph.nodesIndex[nodeId];
  var outgoing = {};
  var incoming = {};
  //noinspection JSUnresolvedFunction
  for (var edge of _sigma.graph.edges()) {
    edge.attr.lineWidth = false;
    edge.hidden = true;

    var n = {
      name: edge.label,
      color: edge.color
    };

    if (nodeId == edge.source) {
      outgoing[edge.target] = n;
    } else if (nodeId == edge.target) {
      incoming[edge.source] = n;
    }
    if (nodeId == edge.source || nodeId == edge.target) {
      _sigma.neighbors[nodeId == edge.target ? edge.source : edge.target] = n;
    }
    edge.hidden = false;
    edge.attr.color = "rgba(0, 0, 0, 1)";
  }
  //noinspection JSUnresolvedFunction
  for (var otherNode of _sigma.graph.nodes()) {
    otherNode.hidden = true;
    otherNode.attr.lineWidth = false;
    otherNode.attr.color = otherNode.color;
  }

  var createList = neighborsAndNodeIds => {
    var neighborsHtmlList = [];
    var neighbors = [];
    for (var neighborId of neighborsAndNodeIds) {
      var neighbor = _sigma.graph.nodesIndex[neighborId];
      neighbor.hidden = false;
      neighbor.attr.lineWidth = false;
      neighbor.attr.color = neighborsAndNodeIds[neighborId].color;
      if (neighborId != nodeId) {
        neighbors.push({
          id: neighborId,
          name: neighbor.label,
          group: (neighborsAndNodeIds[neighborId].name) ? neighborsAndNodeIds[neighborId].name : "",
          color: neighborsAndNodeIds[neighborId].color
        })
      }
    }
    neighbors.sort((node1, node2) => node1.group.toLowerCase().localeCompare(node2.group.toLowerCase())
        || node1.name.toLowerCase().localeCompare(node2.name.toLowerCase()));
    for (neighbor in neighbors) {
      neighborsHtmlList.push('
'
        + '' + neighbor.name + "
");
    }
    return neighborsHtmlList;
  };

  var neighborsHtml = neighborsHtml.concat(createList(_sigma.neighbors));

  node.hidden = false;
  node.attr.color = node.color;
  node.attr.lineWidth = 6;
  node.attr.strokeStyle = "#000000";

  //noinspection JSUnresolvedFunction
  _sigma.refresh();

  $GP.info_link.find("ul").html(neighborsHtml.join(""));

  if (node.attr.attributes) {
    var attributesHtml = [];
    for (var attr of node.attr.attributes) {
      if (attr != false) {
        attributesHtml.push('' + attr + ': ' + attr + '
');
      }
    }

    $GP.info_name.html('
'
      + node.label + "
");

    $GP.info_data.html(attributesHtml.join("
"));
  }
  $GP.info_data.show();
  $GP.info_p.html("Conexiones:");
  $GP.info.animate({width: 'show'}, 350);
  $GP.info_donnees.hide();
  $GP.info_donnees.show();
  _sigma.active = nodeId;
  window.location.hash = node.label;
}

function showCluster(clusterName) {
  var cluster = _sigma.clusters[clusterName];
  if (cluster.length > 0) {
    _sigma.detail = true;
    cluster.sort();
    //noinspection JSUnresolvedFunction
    for (var edge of _sigma.graph.edges()) {
      edge.hidden = false;
      edge.attr.lineWidth = false;
      edge.attr.color = false;
    }
    //noinspection JSUnresolvedFunction
    for (var node of _sigma.graph.nodes()) {
      node.hidden = true;
    }
    var clusterHiddenNodesHtmlList = [];
    var clusterHiddenNodesIds = [];
    for (var clusterNodeId of cluster) {
      var clusterNode = _sigma.graph.nodesIndex[clusterNodeId];
      if (clusterNode.hidden) {
        clusterHiddenNodesIds.push(clusterNodeId);
        clusterNode.hidden = false;
        clusterNode.attr.lineWidth = false;
        clusterNode.attr.color = clusterNode.color;
        clusterHiddenNodesHtmlList.push('
'
          + clusterNode.label + "
");
      }
    }
    _sigma.clusters[clusterName] = clusterHiddenNodesIds;
    //noinspection JSUnresolvedFunction
    _sigma.refresh();
    $GP.info_name.html("" + clusterName + "");
    $GP.info_data.hide();
    $GP.info_p.html("Miembros del grupo:");
    $GP.info_link.find("ul").html(clusterHiddenNodesHtmlList.join(""));
    $GP.info.animate({width: 'show'}, 350);
    $GP.search.clean();
    $GP.cluster.hide();
    return true;
  }
  return false;
}
<commit_msg>Use template literals<commit_after>'use strict';

import sigma from "sigma";
import $ from "jquery";
import "fancybox";

var _sigma;
var $GP;

Object.size = obj => {
  var size = 0;
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      size++;
    }
  }
  return size;
};

$(document).ready(() => setupGUI());

function setupGUI() {
  $GP = {
    calculating: false,
  };
  $GP.info = $("#attributepane");
  $GP.info_donnees = $GP.info.find(".nodeattributes");
  $GP.info_name = $GP.info.find(".name");
  $GP.info_link = $GP.info.find(".link");
  $GP.info_data = $GP.info.find(".data");
  $GP.info_close = $GP.info.find(".returntext");
  $GP.info_close2 = $GP.info.find(".close");
  $GP.info_p = $GP.info.find(".p");
  $GP.info_close.click(nodeNormal);
  $GP.info_close2.click(nodeNormal);
  $GP.form = $("#mainpanel").find("form");
  $GP.search = new Search($GP.form.find("#search"));
  $GP.cluster = new Cluster($GP.form.find("#attributeselect"));
  initSigma();
}

function initSigma() {
  //noinspection JSPotentiallyInvalidConstructorUsage
  _sigma = new sigma({
    container: $('#sigma-canvas'),
    settings: {
      defaultEdgeType: "curve",
      defaultHoverLabelBGColor: "#002147",
      labelThreshold: 10,
      defaultLabelHoverColor: "#fff",
      fontStyle: "bold",
      hoverFontStyle: "bold",
      zoomMax: 20,
      zoomMin: 0.75
    }
  });

  _sigma.active = false;
  _sigma.neighbors = {};
  _sigma.detail = false;

  $.getJSON('data.json', data => {
    //noinspection JSUnresolvedFunction
    _sigma.graph.read(data);

    _sigma.clusters = {};

    //noinspection JSUnresolvedFunction
    for (var node of _sigma.graph.nodes()) {
      if (!(node.color in _sigma.clusters)) {
        _sigma.clusters[node.color] = [];
      }
      _sigma.clusters[node.color].push(node.id);
    }

    //noinspection JSUnresolvedFunction
    _sigma.bind("clickNode", event => nodeActive(event.data.node));

    configSigmaElements();

    //noinspection JSUnresolvedFunction
    _sigma.refresh();
  });
}

function configSigmaElements() {
  var clustersHtml = [];
  var clusterNumber = 1;
  for (var cluster of _sigma.clusters) {
    clustersHtml.push(`

      Group ${clusterNumber++} (${cluster.length} members)
`);
  }
  $GP.cluster.content(clustersHtml.join(""));

  //noinspection JSUnresolvedFunction
  $("a.fb").fancybox({
    minWidth: 400,
    maxWidth: 800,
    maxHeight: 600,
  });

  $("#zoom").find("div.z").each(() => {
    var rel = $(this).attr("rel");
    $(this).click(() => {
      if (rel == "center") {
        //noinspection JSUnresolvedFunction
        _sigma.cameras.goTo(0, 0, 1, 0);
      } else {
        //noinspection JSUnresolvedFunction
        _sigma.utils.zoomTo(0, 0, "in" == rel ? 1.5 : 0.5, 0);
      }
    });
  });

  var hashAnchor = window.location.hash.substr(1);
  if (0 < hashAnchor.length) {
    switch (hashAnchor) {
      case "information":
        $.fancybox.open($("#information"), cluster);
        break;
      default:
        $GP.search.exactMatch = $GP.search.search(hashAnchor);
        $GP.search.clean();
    }
  }
}

function Search(searchElem) {
  this.input = searchElem.find("input[name=search]");
  this.state = searchElem.find(".state");
  this.results = searchElem.find(".results");
  this.exactMatch = false;
  this.lastSearch = "";
  this.searching = false;
  this.input.focus(() => {
    if (!$(this).data("focus")) {
      $(this).data("focus", true);
      $(this).removeClass("empty");
    }
    this.clean();
  });
  this.input.keydown(event => {
    if (event.which == 13) {
      this.state.addClass("searching");
      this.search(this.input.val());
    }
  });
  this.state.click(() => {
    var stateValue = this.input.val();
    if (this.searching && stateValue == this.lastSearch) {
      this.close();
    } else {
      this.state.addClass("searching");
      this.search(stateValue);
    }
  });
  this.close = () => {
    this.state.removeClass("searching");
    this.results.hide();
    this.searching = false;
    this.input.val("");
    nodeNormal();
  };
  this.clean = () => {
    this.results.empty().hide();
    this.state.removeClass("searching");
    this.input.val("");
  };
  this.search = text => {
    var foundNodes = [];
    var textRegex = new RegExp(this.exactMatch ? ("^" + text + "$").toLowerCase() : text.toLowerCase());
    this.exactMatch = false;
    this.searching = true;
    this.lastSearch = text;
    this.results.empty();
    if (text.length <= 2) {
      this.results.html("El texto a buscar debe contener al menos 3 letras.");
    } else {
      //noinspection JSUnresolvedFunction
      for (var node of _sigma.graph.nodes()) {
        if (textRegex.test(node.label.toLowerCase())) {
          foundNodes.push(node);
        }
      }
      var output = ["Resultados encontrados: "];
      if (foundNodes.length == 0) {
        if (!showCluster(text)) {
          output.push("No se encontró ningún nodo.");
        }
      } else {
        nodeActive(foundNodes[0].id);
        if (foundNodes.length > 1) {
          for (var foundNode of foundNodes) {
            output.push(`<a href="#${foundNode.label}" onclick="nodeActive('${foundNode.id}')">${foundNode.label}</a>`);
          }
        }
      }
      this.results.html(output.join(""));
    }
    foundNodes.length == 1 ? this.results.hide() : this.results.show();
  }
}

function Cluster(clusterElem) {
  this.cluster = clusterElem;
  this.display = false;
  this.list = this.cluster.find(".list");
  this.list.empty();
  this.select = this.cluster.find(".select");
  this.select.click(() => $GP.cluster.toggle());
  this.toggle = () => this.display ? this.hide() : this.show();
  this.content = html => {
    this.list.html(html);
    this.list.find("a").click(() => showCluster($(this).attr("href").substr(1)));
  };
  this.hide = () => {
    this.display = false;
    this.list.hide();
    this.select.removeClass("close");
  };
  this.show = () => {
    this.display = true;
    this.list.show();
    this.select.addClass("close");
  }
}

function nodeNormal() {
  if (!$GP.calculating && _sigma.detail) {
    $GP.calculating = true;
    _sigma.detail = true;
    //noinspection JSUnresolvedFunction
    $GP.info.delay(400).animate({width: 'hide'}, 350);
    $GP.cluster.hide();
    //noinspection JSUnresolvedFunction
    for (var edge of _sigma.graph.edges()) {
      edge.attr.color = false;
      edge.hidden = false;
    }
    //noinspection JSUnresolvedFunction
    for (var node of _sigma.graph.nodes()) {
      node.hidden = false;
      node.attr.color = false;
      node.attr.lineWidth = false;
      node.attr.size = false
    }
    //_sigma.draw(2, 2, 2, 2);
    //noinspection JSUnresolvedFunction
    _sigma.refresh();
    _sigma.neighbors = {};
    _sigma.active = false;
    $GP.calculating = false;
    window.location.hash = "";
  }
}

function nodeActive(nodeId) {
  _sigma.neighbors = {};
  _sigma.detail = true;
  var node = _sigma.graph.nodesIndex[nodeId];
  var outgoing = {};
  var incoming = {};
  //noinspection JSUnresolvedFunction
  for (var edge of _sigma.graph.edges()) {
    edge.attr.lineWidth = false;
    edge.hidden = true;

    var n = {
      name: edge.label,
      color: edge.color
    };

    if (nodeId == edge.source) {
      outgoing[edge.target] = n;
    } else if (nodeId == edge.target) {
      incoming[edge.source] = n;
    }
    if (nodeId == edge.source || nodeId == edge.target) {
      _sigma.neighbors[nodeId == edge.target ? edge.source : edge.target] = n;
    }
    edge.hidden = false;
    edge.attr.color = "rgba(0, 0, 0, 1)";
  }
  //noinspection JSUnresolvedFunction
  for (var otherNode of _sigma.graph.nodes()) {
    otherNode.hidden = true;
    otherNode.attr.lineWidth = false;
    otherNode.attr.color = otherNode.color;
  }

  var createList = neighborsAndNodeIds => {
    var neighborsHtmlList = [];
    var neighbors = [];
    for (var neighborId of neighborsAndNodeIds) {
      var neighbor = _sigma.graph.nodesIndex[neighborId];
      neighbor.hidden = false;
      neighbor.attr.lineWidth = false;
      neighbor.attr.color = neighborsAndNodeIds[neighborId].color;
      if (neighborId != nodeId) {
        neighbors.push({
          id: neighborId,
          name: neighbor.label,
          group: (neighborsAndNodeIds[neighborId].name) ? neighborsAndNodeIds[neighborId].name : "",
          color: neighborsAndNodeIds[neighborId].color
        })
      }
    }
    neighbors.sort((node1, node2) => node1.group.toLowerCase().localeCompare(node2.group.toLowerCase())
        || node1.name.toLowerCase().localeCompare(node2.name.toLowerCase()));
    for (neighbor in neighbors) {
      neighborsHtmlList.push(`

        ${neighbor.name}
`);
    }
    return neighborsHtmlList;
  };

  var neighborsHtml = neighborsHtml.concat(createList(_sigma.neighbors));

  node.hidden = false;
  node.attr.color = node.color;
  node.attr.lineWidth = 6;
  node.attr.strokeStyle = "#000000";

  //noinspection JSUnresolvedFunction
  _sigma.refresh();

  $GP.info_link.find("ul").html(neighborsHtml.join(""));

  if (node.attr.attributes) {
    var attributesHtml = [];
    for (var attr of node.attr.attributes) {
      if (attr != false) {
        attributesHtml.push('' + attr + ': ' + attr + '
');
      }
    }

    $GP.info_name.html('
'
      + node.label + "
");

    $GP.info_data.html(attributesHtml.join("
"));
  }
  $GP.info_data.show();
  $GP.info_p.html("Conexiones:");
  $GP.info.animate({width: 'show'}, 350);
  $GP.info_donnees.hide();
  $GP.info_donnees.show();
  _sigma.active = nodeId;
  window.location.hash = node.label;
}

function showCluster(clusterName) {
  var cluster = _sigma.clusters[clusterName];
  if (cluster.length > 0) {
    _sigma.detail = true;
    cluster.sort();
    //noinspection JSUnresolvedFunction
    for (var edge of _sigma.graph.edges()) {
      edge.hidden = false;
      edge.attr.lineWidth = false;
      edge.attr.color = false;
    }
    //noinspection JSUnresolvedFunction
    for (var node of _sigma.graph.nodes()) {
      node.hidden = true;
    }
    var clusterHiddenNodesHtmlList = [];
    var clusterHiddenNodesIds = [];
    for (var clusterNodeId of cluster) {
      var clusterNode = _sigma.graph.nodesIndex[clusterNodeId];
      if (clusterNode.hidden) {
        clusterHiddenNodesIds.push(clusterNodeId);
        clusterNode.hidden = false;
        clusterNode.attr.lineWidth = false;
        clusterNode.attr.color = clusterNode.color;
        clusterHiddenNodesHtmlList.push(`

          ${clusterNode.label}
`);
      }
    }
    _sigma.clusters[clusterName] = clusterHiddenNodesIds;
    //noinspection JSUnresolvedFunction
    _sigma.refresh();
    $GP.info_name.html("" + clusterName + "");
    $GP.info_data.hide();
    $GP.info_p.html("Miembros del grupo:");
    $GP.info_link.find("ul").html(clusterHiddenNodesHtmlList.join(""));
    $GP.info.animate({width: 'show'}, 350);
    $GP.search.clean();
    $GP.cluster.hide();
    return true;
  }
  return false;
}
<|endoftext|>


<commit_before>(function(window) {

    var $textArea = $('#textarea');
    if (!('webkitSpeechRecognition' in window)) {
        upgrade();
    } else {
        var recognizing;
        var recognition = new webkitSpeechRecognition();
        recognition.continuous = true;
        reset();
        recognition.onend = reset;

        recognition.onresult = function(event) {
            // Calculating and saving the cursor position where the text will be displayed
            var pos = $textArea.getCursorPosition()
                // Deleting an interim result from the textArea field
                // Restoring the cursor position
            $textArea.setCursorPosition(pos);
            for (var i = event.resultIndex; i < event.results.length; ++i) {
                if (event.results[i].isFinal) {
                    $textArea.insertAtCaret(event.results[i][0].transcript);
                }
            }
        };

        // recognition.onstart = function() { ... }
        // recognition.onerror = function(event) { ... }
    }

    $('#test').click(function() {
        console.log('Recording!');
        toggleStartStop();
    });

    gapi.savetodrive.go();

    function toggleStartStop() {
        if (recognizing) {
            recognition.stop();
            reset();
        } else {
            recognition.start();
            recognizing = true;
        }
    }

    function reset() {
        recognizing = false;
    }

    function upgrade() {
        alert("This is 2015! Get Google Chrome and browse the web in style!");
    }

    (function($, undefined) {
        $.fn.getCursorPosition = function() {
            var el = $(this).get(0);
            var pos = 0;
            if ('selectionStart' in el) {
                pos = el.selectionStart;
            } else if ('selection' in document) {
                el.focus();
                var Sel = document.selection.createRange();
                var SelLength = document.selection.createRange().text.length;
                Sel.moveStart('character', -el.value.length);
                pos = Sel.text.length - SelLength;
            }
            return pos;
        };
        $.fn.setCursorPosition = function(pos) {
            if (this.setSelectionRange) {
                this.setSelectionRange(pos, pos);
            } else if (this.createTextRange) {
                var range = this.createTextRange();
                range.collapse(true);
                if (pos < 0) {
                    pos = $(this).val().length + pos;
                }
                range.moveEnd('character', pos);
                range.moveStart('character', pos);
                range.select();
            }
        };
        $.fn.insertAtCaret = function(myValue) {
            return this.each(function() {
                var me = this;
                if (document.selection) { // IE
                    me.focus();
                    sel = document.selection.createRange();
                    sel.text = myValue;
                    me.focus();
                } else if (me.selectionStart || me.selectionStart == '0') { // Real browsers
                    var startPos = me.selectionStart,
                        endPos = me.selectionEnd,
                        scrollTop = me.scrollTop;
                    me.value = me.value.substring(0, startPos) + myValue + me.value.substring(endPos, me.value.length);
                    me.focus();
                    me.selectionStart = startPos + myValue.length;
                    me.selectionEnd = startPos + myValue.length;
                    me.scrollTop = scrollTop;
                } else {
                    me.value += myValue;
                    me.focus();
                }
            });
        };
    })(jQuery);
})(window);
<commit_msg>Connected record text to mic button<commit_after>(function(window) {

    var $textArea = $('#textarea');
    if (!('webkitSpeechRecognition' in window)) {
        upgrade();
    } else {
        var recognizing;
        var recognition = new webkitSpeechRecognition();
        recognition.continuous = true;
        reset();
        recognition.onend = reset;

        recognition.onresult = function(event) {
            // Calculating and saving the cursor position where the text will be displayed
            var pos = $textArea.getCursorPosition()
                // Deleting an interim result from the textArea field
                // Restoring the cursor position
            $textArea.setCursorPosition(pos);
            for (var i = event.resultIndex; i < event.results.length; ++i) {
                if (event.results[i].isFinal) {
                    $textArea.insertAtCaret(event.results[i][0].transcript);
                }
            }
        };

        // recognition.onstart = function() { ... }
        // recognition.onerror = function(event) { ... }
    }

    $('#micContainer').click(function() {
        console.log('Recording!');
        toggleStartStop();
    });

    //gapi.savetodrive.go();

    function toggleStartStop() {
        if (recognizing) {
            recognition.stop();
            reset();
        } else {
            recognition.start();
            recognizing = true;
        }
    }

    function reset() {
        recognizing = false;
    }

    function upgrade() {
        alert("This is 2015! Get Google Chrome and browse the web in style!");
    }

    (function($, undefined) {
        $.fn.getCursorPosition = function() {
            var el = $(this).get(0);
            var pos = 0;
            if ('selectionStart' in el) {
                pos = el.selectionStart;
            } else if ('selection' in document) {
                el.focus();
                var Sel = document.selection.createRange();
                var SelLength = document.selection.createRange().text.length;
                Sel.moveStart('character', -el.value.length);
                pos = Sel.text.length - SelLength;
            }
            return pos;
        };
        $.fn.setCursorPosition = function(pos) {
            if (this.setSelectionRange) {
                this.setSelectionRange(pos, pos);
            } else if (this.createTextRange) {
                var range = this.createTextRange();
                range.collapse(true);
                if (pos < 0) {
                    pos = $(this).val().length + pos;
                }
                range.moveEnd('character', pos);
                range.moveStart('character', pos);
                range.select();
            }
        };
        $.fn.insertAtCaret = function(myValue) {
            return this.each(function() {
                var me = this;
                if (document.selection) { // IE
                    me.focus();
                    sel = document.selection.createRange();
                    sel.text = myValue;
                    me.focus();
                } else if (me.selectionStart || me.selectionStart == '0') { // Real browsers
                    var startPos = me.selectionStart,
                        endPos = me.selectionEnd,
                        scrollTop = me.scrollTop;
                    me.value = me.value.substring(0, startPos) + myValue + me.value.substring(endPos, me.value.length);
                    me.focus();
                    me.selectionStart = startPos + myValue.length;
                    me.selectionEnd = startPos + myValue.length;
                    me.scrollTop = scrollTop;
                } else {
                    me.value += myValue;
                    me.focus();
                }
            });
        };
    })(jQuery);
})(window);
<|endoftext|>