<commit_before>app.controller('MainController', function($scope) {
  $scope.pointsLeft = 28;
  $scope.abilityLabels = new Array("STR: ", "DEX: ", "CON: ", "INT: ", "WIS: ", "CHA: ");
  $scope.modLabel = " | Mod: "
  $scope.pointBuyScore = new Array(8, 8, 8, 8, 8, 8);
  $scope.racialBonus = new Array(0, 0, 0, 0, 0, 0);
  $scope.classBonus = new Array(0, 0, 0, 0, 0, 0);
  $scope.abilityMod = new Array(-1, -1, -1, -1, -1, -1);
  $scope.racialStats = [
                        {id: -1, label: "None"},
                        {id: 0, label: "Strength"},
                        {id: 1, label: "Dexterity"},
                        {id: 2, label: "Constitution"},
                        {id: 3, label: "Intelligence"},
                        {id: 4, label: "Wisdom"},
                        {id: 5, label: "Charisma"}];
  $scope.classStats = [
                        {id: -1, label: "None"},
                        {id: 0, label: "Strength"},
                        {id: 1, label: "Dexterity"},
                        {id: 2, label: "Constitution"},
                        {id: 3, label: "Intelligence"},
                        {id: 4, label: "Wisdom"},
                        {id: 5, label: "Charisma"}];
  $scope.racialAbilityScoreSelected = $scope.racialStats[0];
  $scope.classAbilityScoreSelected = $scope.classStats[0];

  $scope.getAbilityMod = function(abilityScore){ return parseInt(Math.floor((abilityScore / 2) - 5)) };

  $scope.getPointValue = function(abilityScore){
    // return (parseInt(abilityScore) - 8) Does not work starting at 15, will investigate another formula
    // And in the mean time, I shall use literally the worst method available.
    switch(abilityScore) {
      case 8:
        return 0;
        break;
      case 9:
        return 1;
        break;
      case 10:
        return 2;
        break;
      case 11:
        return 3;
        break;
      case 12:
        return 4;
        break;
      case 13:
        return 5;
        break;
      case 14:
        return 6;
        break;
      case 15:
        return 8;
        break;
      case 16:
        return 10;
        break;
      case 17:
        return 13;
        break;
      case 18:
        return 16;
        break;
    }
  };

  $scope.setAbilityMod = function(index){ $scope.abilityMod[index] = parseInt($scope.getAbilityMod($scope.pointBuyScore[index] + $scope.racialBonus[index] + $scope.classBonus[index]))};

  $scope.updateAbilityMods = function(){
    for (var i = 0; i < 6; i++){
      $scope.abilityMod[i] = parseInt($scope.getAbilityMod($scope.pointBuyScore[i] + $scope.racialBonus[i] + $scope.classBonus[i]));
    }
  };

  $scope.incrementScore = function(attribute, index){
    var abilityScore = parseInt(attribute);
    if(attribute < 18) {
      var pointDifference = parseInt($scope.getPointValue(abilityScore + 1) - $scope.getPointValue(abilityScore));
      if($scope.pointsLeft >= pointDifference) {
        $scope.pointBuyScore[index] = $scope.pointBuyScore[index] + 1;
        $scope.setAbilityMod(index);
        $scope.pointsLeft = $scope.pointsLeft - pointDifference;
      }
    }
  };

  $scope.decrementScore = function(attribute, index){
    var abilityScore = parseInt(attribute);
    if(abilityScore > 8) {
      var pointDifference = parseInt($scope.getPointValue(abilityScore) - $scope.getPointValue(abilityScore - 1));
      $scope.pointBuyScore[index] = $scope.pointBuyScore[index] - 1;
      $scope.setAbilityMod(index);
      $scope.pointsLeft = $scope.pointsLeft + pointDifference;
    }
  };

  $scope.selectRaceBonus = function(attribute, optionIndex){
    if(attribute != "None"){
      // remove all racial bonuses for all attributes
      for (var i = 0; i < 6; i++){
        $scope.racialBonus[i] = 0;
      }
      // add new racial bonus
      $scope.racialBonus[optionIndex] = 2;
      $scope.updateAbilityMods();
      // search the classBonus array for a missing attribute
      for (var i = 0; i < 7; i++){
        if(!(i in $scope.classStats) || $scope.classStats[i].id != (i - 1)){
          // insert the missing attribute into the options array once found
          $scope.classStats.splice(i, 0, {id: (i - 1), label: $scope.getAttributeById(i - 1)});
        }
      }
      // remove the now racially-selected stat from the class options array
      // we have to do this AFTER inserting the missing one because when the...
      // ...options array is complete we know with certainty what stats are at which position.
      $scope.classStats.splice(optionIndex + 1, 1);
    } else if(attribute == "None"){
      // remove all racial bonuses for all attributes
      for (var i = 0; i < 6; i++){
        $scope.racialBonus[i] = 0;
      }
      $scope.updateAbilityMods();
      // search the classBonus array for a missing attribute
      for (var i = 0; i < 7; i++){
        if(!(i in $scope.classStats) || $scope.classStats[i].id != (i - 1)){
          // insert the missing attribute into the options array once found
          // we are not removing an attribute options since the user has selected no racial bonus
          $scope.classStats.splice(i, 0, {id: (i - 1), label: $scope.getAttributeById(i - 1)});
        }
      }
    }
  };

  $scope.selectClassBonus = function(attribute, optionIndex){
    if(attribute != "None"){
      // remove all class bonuses for all attributes
      for (var i = 0; i < 6; i++){
        $scope.classBonus[i] = 0;
      }
      // add new class bonus
      $scope.classBonus[optionIndex] = 2;
      $scope.updateAbilityMods();
      // search the racialBonus array for a missing attribute
      for (var i = 0; i < 7; i++){
        if(!(i in $scope.racialStats) || $scope.racialStats[i].id != (i - 1)){
          // insert the missing attribute into the options array once found
          $scope.racialStats.splice(i, 0, {id: (i - 1), label: $scope.getAttributeById(i - 1)});
        }
      }
      // remove the now class-selected stat from the racial options array
      // we have to do this AFTER inserting the missing one because when the...
      // ...options array is complete we know with certainty what stats are at which position.
      $scope.racialStats.splice(optionIndex + 1, 1);
    } else if(attribute == "None"){
      // remove all class bonuses for all attributes
      for (var i = 0; i < 6; i++){
        $scope.racialBonus[i] = 0;
      }
      $scope.updateAbilityMods();
      // search the racialBonus array for a missing attribute
      for (var i = 0; i < 7; i++){
        if(!(i in $scope.racialStats) || $scope.racialStats[i].id != (i - 1)){
          // insert the missing attribute into the options array once found
          // we are not removing an attribute options since the user has selected no class bonus
          $scope.racialStats.splice(i, 0, {id: (i - 1), label: $scope.getAttributeById(i - 1)});
        }
      }
    }
  };

  $scope.getAttributeById = function(id){
    switch(id){
      case -1:
        return "None";
        break;
      case 0:
        return "Strength";
        break;
      case 1:
        return "Dexterity";
        break;
      case 2:
        return "Constitution";
        break;
      case 3:
        return "Intelligence";
        break;
      case 4:
        return "Wisdom";
        break;
      case 5:
        return "Charisma";
        break;
    }
  };
});<commit_msg>Fixed a bug in selectClassBonus, did not remove bonus when None was selected.<commit_after>app.controller('MainController', function($scope) {
  $scope.pointsLeft = 28;
  $scope.abilityLabels = new Array("STR: ", "DEX: ", "CON: ", "INT: ", "WIS: ", "CHA: ");
  $scope.modLabel = " | Mod: "
  $scope.pointBuyScore = new Array(8, 8, 8, 8, 8, 8);
  $scope.racialBonus = new Array(0, 0, 0, 0, 0, 0);
  $scope.classBonus = new Array(0, 0, 0, 0, 0, 0);
  $scope.abilityMod = new Array(-1, -1, -1, -1, -1, -1);
  $scope.racialStats = [
                        {id: -1, label: "None"},
                        {id: 0, label: "Strength"},
                        {id: 1, label: "Dexterity"},
                        {id: 2, label: "Constitution"},
                        {id: 3, label: "Intelligence"},
                        {id: 4, label: "Wisdom"},
                        {id: 5, label: "Charisma"}];
  $scope.classStats = [
                        {id: -1, label: "None"},
                        {id: 0, label: "Strength"},
                        {id: 1, label: "Dexterity"},
                        {id: 2, label: "Constitution"},
                        {id: 3, label: "Intelligence"},
                        {id: 4, label: "Wisdom"},
                        {id: 5, label: "Charisma"}];
  $scope.racialAbilityScoreSelected = $scope.racialStats[0];
  $scope.classAbilityScoreSelected = $scope.classStats[0];

  $scope.getAbilityMod = function(abilityScore){ return parseInt(Math.floor((abilityScore / 2) - 5)) };

  $scope.getPointValue = function(abilityScore){
    // return (parseInt(abilityScore) - 8) Does not work starting at 15, will investigate another formula
    // And in the mean time, I shall use literally the worst method available.
    switch(abilityScore) {
      case 8:
        return 0;
        break;
      case 9:
        return 1;
        break;
      case 10:
        return 2;
        break;
      case 11:
        return 3;
        break;
      case 12:
        return 4;
        break;
      case 13:
        return 5;
        break;
      case 14:
        return 6;
        break;
      case 15:
        return 8;
        break;
      case 16:
        return 10;
        break;
      case 17:
        return 13;
        break;
      case 18:
        return 16;
        break;
    }
  };

  $scope.setAbilityMod = function(index){ $scope.abilityMod[index] = parseInt($scope.getAbilityMod($scope.pointBuyScore[index] + $scope.racialBonus[index] + $scope.classBonus[index]))};

  $scope.updateAbilityMods = function(){
    for (var i = 0; i < 6; i++){
      $scope.abilityMod[i] = parseInt($scope.getAbilityMod($scope.pointBuyScore[i] + $scope.racialBonus[i] + $scope.classBonus[i]));
    }
  };

  $scope.incrementScore = function(attribute, index){
    var abilityScore = parseInt(attribute);
    if(attribute < 18) {
      var pointDifference = parseInt($scope.getPointValue(abilityScore + 1) - $scope.getPointValue(abilityScore));
      if($scope.pointsLeft >= pointDifference) {
        $scope.pointBuyScore[index] = $scope.pointBuyScore[index] + 1;
        $scope.setAbilityMod(index);
        $scope.pointsLeft = $scope.pointsLeft - pointDifference;
      }
    }
  };

  $scope.decrementScore = function(attribute, index){
    var abilityScore = parseInt(attribute);
    if(abilityScore > 8) {
      var pointDifference = parseInt($scope.getPointValue(abilityScore) - $scope.getPointValue(abilityScore - 1));
      $scope.pointBuyScore[index] = $scope.pointBuyScore[index] - 1;
      $scope.setAbilityMod(index);
      $scope.pointsLeft = $scope.pointsLeft + pointDifference;
    }
  };

  $scope.selectRaceBonus = function(attribute, optionIndex){
    if(attribute != "None"){
      // remove all racial bonuses for all attributes
      for (var i = 0; i < 6; i++){
        $scope.racialBonus[i] = 0;
      }
      // add new racial bonus
      $scope.racialBonus[optionIndex] = 2;
      $scope.updateAbilityMods();
      // search the classBonus array for a missing attribute
      for (var i = 0; i < 7; i++){
        if(!(i in $scope.classStats) || $scope.classStats[i].id != (i - 1)){
          // insert the missing attribute into the options array once found
          $scope.classStats.splice(i, 0, {id: (i - 1), label: $scope.getAttributeById(i - 1)});
        }
      }
      // remove the now racially-selected stat from the class options array
      // we have to do this AFTER inserting the missing one because when the...
      // ...options array is complete we know with certainty what stats are at which position.
      $scope.classStats.splice(optionIndex + 1, 1);
    } else if(attribute == "None"){
      // remove all racial bonuses for all attributes
      for (var i = 0; i < 6; i++){
        $scope.racialBonus[i] = 0;
      }
      $scope.updateAbilityMods();
      // search the classBonus array for a missing attribute
      for (var i = 0; i < 7; i++){
        if(!(i in $scope.classStats) || $scope.classStats[i].id != (i - 1)){
          // insert the missing attribute into the options array once found
          // we are not removing an attribute options since the user has selected no racial bonus
          $scope.classStats.splice(i, 0, {id: (i - 1), label: $scope.getAttributeById(i - 1)});
        }
      }
    }
  };

  $scope.selectClassBonus = function(attribute, optionIndex){
    if(attribute != "None"){
      // remove all class bonuses for all attributes
      for (var i = 0; i < 6; i++){
        $scope.classBonus[i] = 0;
      }
      // add new class bonus
      $scope.classBonus[optionIndex] = 2;
      $scope.updateAbilityMods();
      // search the racialBonus array for a missing attribute
      for (var i = 0; i < 7; i++){
        if(!(i in $scope.racialStats) || $scope.racialStats[i].id != (i - 1)){
          // insert the missing attribute into the options array once found
          $scope.racialStats.splice(i, 0, {id: (i - 1), label: $scope.getAttributeById(i - 1)});
        }
      }
      // remove the now class-selected stat from the racial options array
      // we have to do this AFTER inserting the missing one because when the...
      // ...options array is complete we know with certainty what stats are at which position.
      $scope.racialStats.splice(optionIndex + 1, 1);
    } else if(attribute == "None"){
      // remove all class bonuses for all attributes
      for (var i = 0; i < 6; i++){
        $scope.classBonus[i] = 0;
      }
      $scope.updateAbilityMods();
      // search the racialBonus array for a missing attribute
      for (var i = 0; i < 7; i++){
        if(!(i in $scope.racialStats) || $scope.racialStats[i].id != (i - 1)){
          // insert the missing attribute into the options array once found
          // we are not removing an attribute options since the user has selected no class bonus
          $scope.racialStats.splice(i, 0, {id: (i - 1), label: $scope.getAttributeById(i - 1)});
        }
      }
    }
  };

  $scope.getAttributeById = function(id){
    switch(id){
      case -1:
        return "None";
        break;
      case 0:
        return "Strength";
        break;
      case 1:
        return "Dexterity";
        break;
      case 2:
        return "Constitution";
        break;
      case 3:
        return "Intelligence";
        break;
      case 4:
        return "Wisdom";
        break;
      case 5:
        return "Charisma";
        break;
    }
  };
});<|endoftext|>


<commit_before>"use strict"

module.exports = (context, callback) => {
    callback(undefined, {nodeVersion: process.version });
}

<commit_msg>Get info function to output input request<commit_after>"use strict"

module.exports = (context, callback) => {
    callback(undefined, {nodeVersion: process.version, input: context });
}

<|endoftext|>


<commit_before>/**
 * Inji js core
 *
 * @author Alexey Krupskiy <admin@inji.ru>
 * @link http://inji.ru/
 * @copyright 2015 Alexey Krupskiy
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
 */

function Inji() {
  this.options = {};
  this.onLoadCallbacks = [];
  this.loaded = false;
  this.listeners = {};
  this.loadedScripts = {};
}
Inji.prototype.onLoad = function (callback, start) {
  if (typeof callback == 'function') {
    if (this.loaded) {
      callback();
    } else {
      if (start) {
        this.onLoadCallbacks.unshift(callback);
      } else {
        this.onLoadCallbacks.push(callback);
      }
    }
  }
}
Inji.prototype.startCallbacks = function () {
  console.log('inji start onload');
  var callback;
  while (callback = this.onLoadCallbacks.shift()) {
    if (typeof callback == 'function') {
      callback();
    }
  }
  if (this.onLoadCallbacks.length != 0) {
    this.startCallbacks();
  }
  var indicator = document.getElementById('loading-indicator');
  if (indicator) {
    indicator.style.display = 'none';
  }
  inji.loaded = true;
  console.log('inji start complete');
}
Inji.prototype.start = function (options) {
  console.log('Inji start');
  for (var key in options.compresedScripts) {
    inji.loadedScripts[options.compresedScripts[key]] = true;
  }
  this.options = options;
  if (options.onLoadModules) {
    this.onLoad(function () {
      for (var key in options.onLoadModules) {
        if (typeof inji[key] == 'undefined') {
          inji[key] = new window[key]();
          if (typeof (inji[key].init) == 'function') {
            console.log(key + ' init');
            inji[key].init();
          }
        }
      }
    }, true)
  }
  if (options.scripts.length > 0) {
    this.loadScripts(options.scripts, 0);
  } else {
    inji.startCallbacks();
  }
}
Inji.prototype.loadScripts = function (scripts, key) {
  this.addScript(scripts[key], function () {
    if (typeof (scripts[key].name) != 'undefined') {
      inji.loadedScripts[scripts[key].file] = true;
      if (typeof inji[scripts[key].name] == 'undefined') {
        console.log('js ' + scripts[key].name + '(' + scripts[key].file + ') loaded');
        inji[scripts[key].name] = new window[scripts[key].name]();
        if (typeof (inji[scripts[key].name].init) == 'function') {
          inji[scripts[key].name].init();
        }
      }
    } else if (typeof (scripts[key].file) != 'undefined') {
      inji.loadedScripts[scripts[key].file] = true;
      console.log('js ' + scripts[key].file + ' loaded');

    } else {
      inji.loadedScripts[scripts[key]] = true;
      console.log('js ' + scripts[key] + ' loaded');
      inji.event('loadScript', scripts[key]);
    }
    if (typeof (scripts[key + 1]) != 'undefined') {
      inji.loadScripts(scripts, key + 1);
    } else {
      console.log('All scripts loaded');
      inji.startCallbacks();
    }
  });
}
Inji.prototype.addScript = function (script, callback) {
  var element = document.createElement('script');
  var src = '';
  if (typeof (script.file) != 'undefined') {
    src = script.file;
  } else {
    src = script;
  }
  if (inji.loadedScripts[src]) {
    if (typeof (callback) == 'function') {
      callback();
    }
    return true;
  }
  element.src = src;
  element.type = 'text/javascript';
  if (typeof (callback) == 'function') {
    element.onload = callback;
  }
  document.head.appendChild(element);

}
Inji.prototype.on = function (eventType, callback) {
  if (typeof this.listeners[eventType] == 'undefined') {
    this.listeners[eventType] = [];
  }
  this.listeners[eventType].push(callback);
}
Inji.prototype.event = function (eventType, object) {
  if (typeof this.listeners[eventType] != 'undefined') {
    for (var key in this.listeners[eventType]) {
      this.listeners[eventType][key](eventType, object);
    }
  }
}
Inji.prototype.randomString = function (length) {
  if (!length) {
    length = 20;
  }
  var text = "";
  var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (var i = 0; i < length; i++)
    text += chars.charAt(Math.floor(Math.random() * chars.length));

  return text;
}
Inji.prototype.numberFormat = function (number, decimals, dec_point, thousands_sep) {
  //// Format a number with grouped thousands
  //
  // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +	 bugfix by: Michael White (http://crestidg.com)

  var i, j, kw, kd, km;

  // input sanitation & defaults
  if (isNaN(decimals = Math.abs(decimals))) {
    decimals = 2;
  }
  if (dec_point == undefined) {
    dec_point = ",";
  }
  if (thousands_sep == undefined) {
    thousands_sep = ".";
  }

  i = parseInt(number = (+number || 0).toFixed(decimals)) + "";

  if ((j = i.length) > 3) {
    j = j % 3;
  } else {
    j = 0;
  }

  km = (j ? i.substr(0, j) + thousands_sep : "");
  kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
  //kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).slice(2) : "");
  kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, 0).slice(2) : "");

  return km + kw + kd;
}
Inji.prototype.get = function (query) {
  var element = document.querySelector(query);
  if (element) {
    return new function () {
      this.element = element;
      this.attr = function (name) {
        for (var key in this.element.attributes) {
          var attr = element.attributes[key];
          if (attr.name == name) {
            return attr.value;
          }
        }
        return null;
      }
      this.data = function (name) {
        var data = this.attr('data-' + name);
        try {
          return JSON.parse(data);
        } catch (e) {
          return data;
        }

      }
    }
  }
}
Inji.prototype.parseQueryString = function (string) {
  var result = {};

  string = string.indexOf('?') === 0 ? string.substr(1) : string;
  if (!string.length) {
    return [];
  }
  string = decodeURIComponent(string.replace(/\[[\"\']/g, '[').replace(/[\"\']\]/g, ']'));
  var result = {};
  var params = string.split('&');
  for (var key in params) {
    var item = params[key];
    var itemPaths = item.match(/\[([^\]]*)\]/g);
    if (itemPaths === null) {
      result[item.split('=')[0]] = item.split('=')[1];
      continue;
    }
    var rootParam = item.substr(0, item.indexOf('['));
    if (typeof result[rootParam] == 'undefined') {
      result[rootParam] = {};
    }
    var resultCurPath = result[rootParam];
    for (var itemPathKey in itemPaths) {
      var itemPath = itemPaths[itemPathKey].replace('[', '').replace(']', '');
      if (itemPath == '') {
        itemPath = Object.keys(resultCurPath).length;
      }
      if (typeof resultCurPath[itemPath] == 'undefined') {
        resultCurPath[itemPath] = parseInt(itemPathKey) + 1 < itemPaths.length ? {} : item.split('=')[1];
      }
      if (parseInt(itemPathKey) + 1 < itemPaths.length) {
        resultCurPath = resultCurPath[itemPath];
      }
    }

  }
  return result;
}
var inji = new Inji();<commit_msg>fix default return type<commit_after>/**
 * Inji js core
 *
 * @author Alexey Krupskiy <admin@inji.ru>
 * @link http://inji.ru/
 * @copyright 2015 Alexey Krupskiy
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
 */

function Inji() {
  this.options = {};
  this.onLoadCallbacks = [];
  this.loaded = false;
  this.listeners = {};
  this.loadedScripts = {};
}
Inji.prototype.onLoad = function (callback, start) {
  if (typeof callback == 'function') {
    if (this.loaded) {
      callback();
    } else {
      if (start) {
        this.onLoadCallbacks.unshift(callback);
      } else {
        this.onLoadCallbacks.push(callback);
      }
    }
  }
}
Inji.prototype.startCallbacks = function () {
  console.log('inji start onload');
  var callback;
  while (callback = this.onLoadCallbacks.shift()) {
    if (typeof callback == 'function') {
      callback();
    }
  }
  if (this.onLoadCallbacks.length != 0) {
    this.startCallbacks();
  }
  var indicator = document.getElementById('loading-indicator');
  if (indicator) {
    indicator.style.display = 'none';
  }
  inji.loaded = true;
  console.log('inji start complete');
}
Inji.prototype.start = function (options) {
  console.log('Inji start');
  for (var key in options.compresedScripts) {
    inji.loadedScripts[options.compresedScripts[key]] = true;
  }
  this.options = options;
  if (options.onLoadModules) {
    this.onLoad(function () {
      for (var key in options.onLoadModules) {
        if (typeof inji[key] == 'undefined') {
          inji[key] = new window[key]();
          if (typeof (inji[key].init) == 'function') {
            console.log(key + ' init');
            inji[key].init();
          }
        }
      }
    }, true)
  }
  if (options.scripts.length > 0) {
    this.loadScripts(options.scripts, 0);
  } else {
    inji.startCallbacks();
  }
}
Inji.prototype.loadScripts = function (scripts, key) {
  this.addScript(scripts[key], function () {
    if (typeof (scripts[key].name) != 'undefined') {
      inji.loadedScripts[scripts[key].file] = true;
      if (typeof inji[scripts[key].name] == 'undefined') {
        console.log('js ' + scripts[key].name + '(' + scripts[key].file + ') loaded');
        inji[scripts[key].name] = new window[scripts[key].name]();
        if (typeof (inji[scripts[key].name].init) == 'function') {
          inji[scripts[key].name].init();
        }
      }
    } else if (typeof (scripts[key].file) != 'undefined') {
      inji.loadedScripts[scripts[key].file] = true;
      console.log('js ' + scripts[key].file + ' loaded');

    } else {
      inji.loadedScripts[scripts[key]] = true;
      console.log('js ' + scripts[key] + ' loaded');
      inji.event('loadScript', scripts[key]);
    }
    if (typeof (scripts[key + 1]) != 'undefined') {
      inji.loadScripts(scripts, key + 1);
    } else {
      console.log('All scripts loaded');
      inji.startCallbacks();
    }
  });
}
Inji.prototype.addScript = function (script, callback) {
  var element = document.createElement('script');
  var src = '';
  if (typeof (script.file) != 'undefined') {
    src = script.file;
  } else {
    src = script;
  }
  if (inji.loadedScripts[src]) {
    if (typeof (callback) == 'function') {
      callback();
    }
    return true;
  }
  element.src = src;
  element.type = 'text/javascript';
  if (typeof (callback) == 'function') {
    element.onload = callback;
  }
  document.head.appendChild(element);

}
Inji.prototype.on = function (eventType, callback) {
  if (typeof this.listeners[eventType] == 'undefined') {
    this.listeners[eventType] = [];
  }
  this.listeners[eventType].push(callback);
}
Inji.prototype.event = function (eventType, object) {
  if (typeof this.listeners[eventType] != 'undefined') {
    for (var key in this.listeners[eventType]) {
      this.listeners[eventType][key](eventType, object);
    }
  }
}
Inji.prototype.randomString = function (length) {
  if (!length) {
    length = 20;
  }
  var text = "";
  var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (var i = 0; i < length; i++)
    text += chars.charAt(Math.floor(Math.random() * chars.length));

  return text;
}
Inji.prototype.numberFormat = function (number, decimals, dec_point, thousands_sep) {
  //// Format a number with grouped thousands
  //
  // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +	 bugfix by: Michael White (http://crestidg.com)

  var i, j, kw, kd, km;

  // input sanitation & defaults
  if (isNaN(decimals = Math.abs(decimals))) {
    decimals = 2;
  }
  if (dec_point == undefined) {
    dec_point = ",";
  }
  if (thousands_sep == undefined) {
    thousands_sep = ".";
  }

  i = parseInt(number = (+number || 0).toFixed(decimals)) + "";

  if ((j = i.length) > 3) {
    j = j % 3;
  } else {
    j = 0;
  }

  km = (j ? i.substr(0, j) + thousands_sep : "");
  kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
  //kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).slice(2) : "");
  kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, 0).slice(2) : "");

  return km + kw + kd;
}
Inji.prototype.get = function (query) {
  var element = document.querySelector(query);
  if (element) {
    return new function () {
      this.element = element;
      this.attr = function (name) {
        for (var key in this.element.attributes) {
          var attr = element.attributes[key];
          if (attr.name == name) {
            return attr.value;
          }
        }
        return null;
      }
      this.data = function (name) {
        var data = this.attr('data-' + name);
        try {
          return JSON.parse(data);
        } catch (e) {
          return data;
        }

      }
    }
  }
}
Inji.prototype.parseQueryString = function (string) {
  var result = {};

  string = string.indexOf('?') === 0 ? string.substr(1) : string;
  if (!string.length) {
    return {};
  }
  string = decodeURIComponent(string.replace(/\[[\"\']/g, '[').replace(/[\"\']\]/g, ']'));
  var result = {};
  var params = string.split('&');
  for (var key in params) {
    var item = params[key];
    var itemPaths = item.match(/\[([^\]]*)\]/g);
    if (itemPaths === null) {
      result[item.split('=')[0]] = item.split('=')[1];
      continue;
    }
    var rootParam = item.substr(0, item.indexOf('['));
    if (typeof result[rootParam] == 'undefined') {
      result[rootParam] = {};
    }
    var resultCurPath = result[rootParam];
    for (var itemPathKey in itemPaths) {
      var itemPath = itemPaths[itemPathKey].replace('[', '').replace(']', '');
      if (itemPath == '') {
        itemPath = Object.keys(resultCurPath).length;
      }
      if (typeof resultCurPath[itemPath] == 'undefined') {
        resultCurPath[itemPath] = parseInt(itemPathKey) + 1 < itemPaths.length ? {} : item.split('=')[1];
      }
      if (parseInt(itemPathKey) + 1 < itemPaths.length) {
        resultCurPath = resultCurPath[itemPath];
      }
    }

  }
  return result;
}
var inji = new Inji();<|endoftext|>


<commit_before>
var app = app || {};

app.AppView = Backbone.View.extend({
	el: '#todoapp',
	event: {
		'keypress #new-todo': 'creatOnenter',
		'click #clear-completed': 'clearCompleted',
		'click #toggle-all': 'toggleAllComplete'
	},
  	statsTemplate: _.template($('#stats-template').html()),
  	initialize: function(){
	  	this.allCheckbox = this.$('#toggle-all')[0];
	  	this.$input = this.$('#new-todo');
	  	this.$footer = this.$('#footer');
	  	this.$main = this.$('#main');

	  	this.listenTo(app.Todos, 'add', this.addOne);
	  	this.listenTo(app.Todos, 'reset', this.addAll);

		this.listenTo(app.Todos, 'change:completed', this.filterOne);
		this.listenTo(app.Todos, 'filter', this.filterAll);
		this.listenTo(app.Todos, 'all', this.render);

		app.Todos.fetch();
	},
	render: function() {
		var completed = app.Todos.completed().length;
		var remaining = app.Todos.remaining().length;

		if ( app.Todos.length ) {
			this.$main.show();
			this.$footer.show();

			this.$footer.html(this.statusTemplate({
				completed: completed,
				remaining: remaining
			}));

			this.$('#filters li a')
				.removeClass('selected')
				.filter('[href="#/' + (app.TodoFilter || '' ) + '"]')
				.addClass('selected');
		} else {
			this.$main.hide();
			this.$footer.hide();
		}

		this.allCheckbox.checked = !remaining;
	},
	addOne: function(todo) {
		var view = new app.TodoView({model: todo});
		$('#todo-list').append(view.render().el);
	},
	addAll:function(){
		this.$('#todo-list').html();
		app.Todos.each(this.addOne, this);
	},
	filterOne: function (todo) {
		todo.trigger('visiable');
	},
	filterAll: function(){
		app.Todos.each(this.filterOne, this);
	},
	newAttributes: function () {
		return {
			title: this.$input.val().trim(),
			order: app.Todos.nextOrder(),
			completed: false
		};
	},
	createOnEnter: function(event) {
		if (event.which !== ENTER_KEY || !this.$input.val().trim() ) {
			return;
		}

		app.Todos.create( this.newAttributes() );
		this.$input.val('');

	},
	clearCompleted: function() {
		_.invoke(app.Todos.completed(), 'destroy');
	}

});
<commit_msg>modified<commit_after>
var app = app || {};

app.AppView = Backbone.View.extend({
	el: '#todoapp',
	event: {
		'keypress #new-todo': 'creatOnenter',
		'click #clear-completed': 'clearCompleted',
		'click #toggle-all': 'toggleAllComplete'
	},
  	statsTemplate: _.template($('#stats-template').html()),
  	initialize: function(){
	  	this.allCheckbox = this.$('#toggle-all')[0];
	  	this.$input = this.$('#new-todo');
	  	this.$footer = this.$('#footer');
	  	this.$main = this.$('#main');

	  	this.listenTo(app.Todos, 'add', this.addOne);
	  	this.listenTo(app.Todos, 'reset', this.addAll);

		this.listenTo(app.Todos, 'change:completed', this.filterOne);
		this.listenTo(app.Todos, 'filter', this.filterAll);
		this.listenTo(app.Todos, 'all', this.render);

		app.Todos.fetch();
	},
	render: function() {
		var completed = app.Todos.completed().length;
		var remaining = app.Todos.remaining().length;

		if ( app.Todos.length ) {
			this.$main.show();
			this.$footer.show();

			this.$footer.html(this.statusTemplate({
				completed: completed,
				remaining: remaining
			}));

			this.$('#filters li a')
				.removeClass('selected')
				.filter('[href="#/' + (app.TodoFilter || '' ) + '"]')
				.addClass('selected');
		} else {
			this.$main.hide();
			this.$footer.hide();
		}

		this.allCheckbox.checked = !remaining;
	},
	addOne: function(todo) {
		var view = new app.TodoView({model: todo});
		$('#todo-list').append(view.render().el);
	},
	addAll:function(){
		this.$('#todo-list').html();
		app.Todos.each(this.addOne, this);
	},
	filterOne: function (todo) {
		todo.trigger('visiable');
	},
	filterAll: function(){
		app.Todos.each(this.filterOne, this);
	},
	newAttributes: function () {
		return {
			title: this.$input.val().trim(),
			order: app.Todos.nextOrder(),
			completed: false
		};
	},
	createOnEnter: function(event) {
		if (event.which !== ENTER_KEY || !this.$input.val().trim() ) {
			return;
		}

		app.Todos.create( this.newAttributes() );
		this.$input.val('');

	},
	clearCompleted: function() {
		_.invoke(app.Todos.completed(), 'destroy');
		return false;
	},
	toggleAllComplete: function() {
		var completed = this.allCheckbox.checked;

		app.Todos.each(function( todo ) {
			todo.save({
				'completed' : completed
			});
		});
	}

});
<|endoftext|>


<commit_before>'use babel'
/* eslint-env jasmine */

// Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs.
//
// To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit`
// or `fdescribe`). Remove the `f` to unfocus the block.

describe('GoSignatureStatusbar', () => {
  let goSignatureStatusbarMain
  let workspaceElement
  let goPlusPromise
  let activationPromise

  beforeEach(() => {
    runs(() => {
      atom.packages.triggerActivationHook('language-go:grammar-used')
      atom.packages.triggerActivationHook('core:loaded-shell-environment')
      workspaceElement = atom.views.getView(atom.workspace)
      jasmine.attachToDOM(workspaceElement)
      // make _.debounce work in atom < 1.9
      if (!window.Date.now.isSpy) {
        spyOn(window.Date, 'now').andCallFake(() => window.now)
      }
    })

    waitsForPromise(() => {
      return atom.packages.activatePackage('language-go')
    })

    waitsForPromise(() => {
      return atom.packages.activatePackage('status-bar')
    })

    runs(() => {
      goPlusPromise = atom.packages.activatePackage('go-plus')
      const pack = atom.packages.loadPackage('go-plus')
      atom.packages.triggerActivationHook('core:loaded-shell-environment')
      pack.activateNow()
    })

    waitsForPromise(() => {
      return goPlusPromise
    })

    runs(() => {
      activationPromise = atom.packages.activatePackage('go-signature-statusbar')
      const pack = atom.packages.loadPackage('go-signature-statusbar')
      atom.packages.triggerActivationHook('core:loaded-shell-environment')
      pack.activateNow()
    })

    waitsForPromise(() => {
      return activationPromise.then((pack) => {
        goSignatureStatusbarMain = pack.mainModule
      })
    })

    waitsFor(() => {
      return goSignatureStatusbarMain.initDone
    })

    runs(() => {
      spyOn(goSignatureStatusbarMain.goSignatureStatusbarView, 'textContent').andCallThrough()
      goSignatureStatusbarMain.addStatusBarTile()
    })
  })

  describe('when the package is activated', () => {
    it('creates a new status bar tile', () => {
      expect(workspaceElement.querySelectorAll('div.go-signature-statusbar').length).toBe(1)
    })

    it('displays no text in the status bar', () => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe(''))
  })

  describe('when navigating to a function call in a Go file', () => {
    let [editor, goSignatureStatusbarView] = []
    beforeEach(() => {
      waitsForPromise(() =>
        atom.workspace.open('main.go').then((e) => {
          editor = e
        })
      )

      goSignatureStatusbarView = goSignatureStatusbarMain.goSignatureStatusbarView
    })

    it('displays the signature of a function in the status bar', () => {
      runs(() => {
        editor.setCursorScreenPosition([9, 9])
        advanceClock(301)
      })

      waitsFor(() =>
        // First call issued on activating the package, second call issued when
        // opening the file, third call issued when navigating to the position
        goSignatureStatusbarView.textContent.calls.length === 2
      )
      runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Println(a ...interface{}) (n int, err error)'))
    })

    it('displays the signature of a function wrapped by another function in the status bar', () => {
      runs(() => {
        editor.setCursorScreenPosition([9, 23])
        advanceClock(301)
      })

      waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
      runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Sprintf(format string, a ...interface{}) string'))
    })

    describe('and the cursor is placed behind the closing bracket of a function', () =>
      it('displays the signature in the status bar', () => {
        runs(() => {
          editor.setCursorScreenPosition([9, 34])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Sprintf(format string, a ...interface{}) string'))
        runs(() => {
          editor.setCursorScreenPosition([9, 35])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 3)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Println(a ...interface{}) (n int, err error)'))
      })
    )

    describe('and the cursor is placed on a function that contains line-breaks', () =>
      it('displays the signature in the status bar', () => {
        runs(() => {
          editor.setCursorScreenPosition([11, 12])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Print(a ...interface{}) (n int, err error)'))
      })
    )

    describe('and the cursor is moved from above a call to a function to somewhere else', () =>
      it('clears the signature in the status bar', () => {
        runs(() => {
          editor.setCursorScreenPosition([9, 10])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Println(a ...interface{}) (n int, err error)'))
        runs(() => {
          editor.setCursorScreenPosition([4, 7])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 3)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe(''))
      })
    )

    describe('and the format is changed', () =>
      it('formats the output', () => {
        runs(() => {
          atom.config.set('go-signature-statusbar.format', '%R %F%A')
          editor.setCursorScreenPosition([9, 10])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('(n int, err error) Println(a ...interface{})'))
      })
    )

    describe('and the function has no return value', () =>
      it('formats the output', () => {
        runs(() => {
          editor.setCursorScreenPosition([15, 9])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Print(v ...interface{})'))
      })
    )
  })

  describe('https://github.com/wndhydrnt/go-signature-statusbar/issues/1', () => {
    let [editor, goSignatureStatusbarView] = []
    beforeEach(() => {
      waitsForPromise(() =>
        atom.workspace.open('issue-1.go').then((e) => {
          editor = e
        })
      )

      goSignatureStatusbarView = goSignatureStatusbarMain.goSignatureStatusbarView
    })

    describe('when the function spans multiple lines and "(" is not the last character of the first line', () =>
      it('displays the signature of a function in the status bar', () => {
        runs(() => {
          editor.setCursorScreenPosition([11, 9])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Println(a ...interface{}) (n int, err error)'))
      })
    )
  })

  describe('https://github.com/wndhydrnt/go-signature-statusbar/issues/2', () => {
    let [editor, goSignatureStatusbarView] = []

    beforeEach(() => {
      waitsForPromise(() =>
        atom.workspace.open('issue-2.go').then((e) => {
          editor = e
        })
      )

      goSignatureStatusbarView = goSignatureStatusbarMain.goSignatureStatusbarView
    })

    describe('when function calls are chained together on the same line', () => {
      it('displays the signature of the first function in the chain', () => {
        runs(() => {
          editor.setCursorScreenPosition([12, 12])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('NewDecoder(r io.Reader) *json.Decoder'))
      })

      it('displays the signature of a function passed as an argument to the first function in the chain', () => {
        runs(() => {
          editor.setCursorScreenPosition([12, 30])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('NewReader(s string) *strings.Reader'))
      })

      it('displays the signature of the second function in the chain', () => {
        runs(() => {
          editor.setCursorScreenPosition([12, 63])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Decode(v interface{}) error'))
      })

      it('ignores the "." of a chained call', () => {
        runs(() => {
          editor.setCursorScreenPosition([12, 57])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('NewDecoder(r io.Reader) *json.Decoder'))
      })
    })
  })

  describe('https://github.com/wndhydrnt/go-signature-statusbar/issues/5', () => {
    let [editor, goSignatureStatusbarView] = []

    beforeEach(() => {
      waitsForPromise(() =>
        atom.workspace.open('issue-5.go').then((e) => {
          editor = e
        })
      )

      goSignatureStatusbarView = goSignatureStatusbarMain.goSignatureStatusbarView
    })

    describe('when the function does not return anything', () =>
      it('does not add extra closing bracket to the end of the function', () => {
        runs(() => {
          editor.setCursorScreenPosition([5, 9])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => {
          expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).not.toBe('Print(v ...interface{}))')
          expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Print(v ...interface{})')
        })
      })
    )
  })

  describe('https://github.com/wndhydrnt/go-signature-statusbar/pull/20', () => {
    let [editor, goSignatureStatusbarView] = []

    beforeEach(() => {
      waitsForPromise(() =>
        atom.workspace.open('issue-20.go').then((e) => {
          editor = e
        })
      )

      goSignatureStatusbarView = goSignatureStatusbarMain.goSignatureStatusbarView
    })

    describe('when the cursor is above a comment', () =>
      it('displays nothing in the status bar', () => {
        runs(() => editor.setCursorScreenPosition([3, 2]))
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 3)
        runs(() => {
          expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('')
        })
      })
    )
  })
})
<commit_msg>Fix stable on macOS<commit_after>'use babel'
/* eslint-env jasmine */

// Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs.
//
// To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit`
// or `fdescribe`). Remove the `f` to unfocus the block.

describe('GoSignatureStatusbar', () => {
  let goSignatureStatusbarMain
  let workspaceElement
  let goPlusPromise
  let activationPromise

  beforeEach(() => {
    runs(() => {
      atom.packages.triggerActivationHook('language-go:grammar-used')
      atom.packages.triggerActivationHook('core:loaded-shell-environment')
      workspaceElement = atom.views.getView(atom.workspace)
      jasmine.attachToDOM(workspaceElement)
      // make _.debounce work in atom < 1.19
      if (!window.Date.now.isSpy) {
        spyOn(window.Date, 'now').andCallFake(() => window.now)
      }
    })

    waitsForPromise(() => {
      return atom.packages.activatePackage('language-go')
    })

    waitsForPromise(() => {
      return atom.packages.activatePackage('status-bar')
    })

    runs(() => {
      goPlusPromise = atom.packages.activatePackage('go-plus')
      const pack = atom.packages.loadPackage('go-plus')
      atom.packages.triggerActivationHook('core:loaded-shell-environment')
      pack.activateNow()
    })

    waitsForPromise(() => {
      return goPlusPromise
    })

    runs(() => {
      activationPromise = atom.packages.activatePackage('go-signature-statusbar')
      const pack = atom.packages.loadPackage('go-signature-statusbar')
      atom.packages.triggerActivationHook('core:loaded-shell-environment')
      pack.activateNow()
    })

    waitsForPromise(() => {
      return activationPromise.then((pack) => {
        goSignatureStatusbarMain = pack.mainModule
      })
    })

    waitsFor(() => {
      return goSignatureStatusbarMain.initDone
    })

    runs(() => {
      spyOn(goSignatureStatusbarMain.goSignatureStatusbarView, 'textContent').andCallThrough()
      goSignatureStatusbarMain.addStatusBarTile()
    })
  })

  describe('when the package is activated', () => {
    it('creates a new status bar tile', () => {
      expect(workspaceElement.querySelectorAll('div.go-signature-statusbar').length).toBe(1)
      expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('')
    })
  })

  describe('when navigating to a function call in a Go file', () => {
    let [editor, goSignatureStatusbarView] = []
    beforeEach(() => {
      waitsForPromise(() =>
        atom.workspace.open('main.go').then((e) => {
          editor = e
        })
      )

      goSignatureStatusbarView = goSignatureStatusbarMain.goSignatureStatusbarView
    })

    it('displays the signature of a function in the status bar', () => {
      runs(() => {
        editor.setCursorScreenPosition([9, 9])
        advanceClock(301)
      })

      waitsFor(() =>
        // First call issued on activating the package, second call issued when
        // opening the file, third call issued when navigating to the position
        goSignatureStatusbarView.textContent.calls.length === 2
      )
      runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Println(a ...interface{}) (n int, err error)'))
    })

    it('displays the signature of a function wrapped by another function in the status bar', () => {
      runs(() => {
        editor.setCursorScreenPosition([9, 23])
        advanceClock(301)
      })

      waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
      runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Sprintf(format string, a ...interface{}) string'))
    })

    describe('and the cursor is placed behind the closing bracket of a function', () =>
      it('displays the signature in the status bar', () => {
        runs(() => {
          editor.setCursorScreenPosition([9, 34])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Sprintf(format string, a ...interface{}) string'))
        runs(() => {
          editor.setCursorScreenPosition([9, 35])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 3)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Println(a ...interface{}) (n int, err error)'))
      })
    )

    describe('and the cursor is placed on a function that contains line-breaks', () =>
      it('displays the signature in the status bar', () => {
        runs(() => {
          editor.setCursorScreenPosition([11, 12])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Print(a ...interface{}) (n int, err error)'))
      })
    )

    describe('and the cursor is moved from above a call to a function to somewhere else', () =>
      it('clears the signature in the status bar', () => {
        runs(() => {
          editor.setCursorScreenPosition([9, 10])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Println(a ...interface{}) (n int, err error)'))
        runs(() => {
          editor.setCursorScreenPosition([4, 7])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 3)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe(''))
      })
    )

    describe('and the format is changed', () =>
      it('formats the output', () => {
        runs(() => {
          atom.config.set('go-signature-statusbar.format', '%R %F%A')
          editor.setCursorScreenPosition([9, 10])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('(n int, err error) Println(a ...interface{})'))
      })
    )

    describe('and the function has no return value', () =>
      it('formats the output', () => {
        runs(() => {
          editor.setCursorScreenPosition([15, 9])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Print(v ...interface{})'))
      })
    )
  })

  describe('https://github.com/wndhydrnt/go-signature-statusbar/issues/1', () => {
    let [editor, goSignatureStatusbarView] = []
    beforeEach(() => {
      waitsForPromise(() =>
        atom.workspace.open('issue-1.go').then((e) => {
          editor = e
        })
      )

      goSignatureStatusbarView = goSignatureStatusbarMain.goSignatureStatusbarView
    })

    describe('when the function spans multiple lines and "(" is not the last character of the first line', () =>
      it('displays the signature of a function in the status bar', () => {
        runs(() => {
          editor.setCursorScreenPosition([11, 9])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Println(a ...interface{}) (n int, err error)'))
      })
    )
  })

  describe('https://github.com/wndhydrnt/go-signature-statusbar/issues/2', () => {
    let [editor, goSignatureStatusbarView] = []

    beforeEach(() => {
      waitsForPromise(() =>
        atom.workspace.open('issue-2.go').then((e) => {
          editor = e
        })
      )

      goSignatureStatusbarView = goSignatureStatusbarMain.goSignatureStatusbarView
    })

    describe('when function calls are chained together on the same line', () => {
      it('displays the signature of the first function in the chain', () => {
        runs(() => {
          editor.setCursorScreenPosition([12, 12])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('NewDecoder(r io.Reader) *json.Decoder'))
      })

      it('displays the signature of a function passed as an argument to the first function in the chain', () => {
        runs(() => {
          editor.setCursorScreenPosition([12, 30])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('NewReader(s string) *strings.Reader'))
      })

      it('displays the signature of the second function in the chain', () => {
        runs(() => {
          editor.setCursorScreenPosition([12, 63])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Decode(v interface{}) error'))
      })

      it('ignores the "." of a chained call', () => {
        runs(() => {
          editor.setCursorScreenPosition([12, 57])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('NewDecoder(r io.Reader) *json.Decoder'))
      })
    })
  })

  describe('https://github.com/wndhydrnt/go-signature-statusbar/issues/5', () => {
    let [editor, goSignatureStatusbarView] = []

    beforeEach(() => {
      waitsForPromise(() =>
        atom.workspace.open('issue-5.go').then((e) => {
          editor = e
        })
      )

      goSignatureStatusbarView = goSignatureStatusbarMain.goSignatureStatusbarView
    })

    describe('when the function does not return anything', () =>
      it('does not add extra closing bracket to the end of the function', () => {
        runs(() => {
          editor.setCursorScreenPosition([5, 9])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => {
          expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).not.toBe('Print(v ...interface{}))')
          expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('Print(v ...interface{})')
        })
      })
    )
  })

  describe('https://github.com/wndhydrnt/go-signature-statusbar/pull/20', () => {
    let [editor, goSignatureStatusbarView] = []

    beforeEach(() => {
      waitsForPromise(() =>
        atom.workspace.open('issue-20.go').then((e) => {
          editor = e
        })
      )

      goSignatureStatusbarView = goSignatureStatusbarMain.goSignatureStatusbarView
    })

    describe('when the cursor is above a comment', () =>
      it('displays nothing in the status bar', () => {
        runs(() => {
          editor.setCursorScreenPosition([3, 2])
          advanceClock(301)
        })
        waitsFor(() => goSignatureStatusbarView.textContent.calls.length === 2)
        runs(() => {
          expect(workspaceElement.querySelector('div.go-signature-statusbar').textContent).toBe('')
        })
      })
    )
  })
})
<|endoftext|>


<commit_before>(function () {
    "use strict";
    angular.module('hippo.essentials')

        //############################################
        // MENU DATA
        //############################################
            .service('menuService', function () {
                this.getMenu = function () {
                    return [
                        {name: "Plugins", link: "#/plugins"},
                        {name: "Tools", link: "#/tools"}
                    ];
                };

            })

        //############################################
        // PLUGINS CONTROLLER LOADER
        //############################################
            .controller('pluginLoaderCtrl',function ($scope, $sce, $log, $rootScope, $http, MyHttpInterceptor) {

            }).controller('toolCtrl', function ($scope, $sce, $log, $rootScope, $http, MyHttpInterceptor) {
                // does nothing for time being
            })
            .controller('pluginCtrl', function ($scope, $location, $sce, $log, $rootScope, $http) {

                $scope.allPluginsInstalled = "No additional plugins could be found";
                $scope.plugins = [];
                $scope.pluginNeedsInstall = [];
                $scope.selectedPlugin = null;
                $scope.tabs = [
                    {name: "Installed Plugins", link: "/plugins"},
                    {name: "Find additional", link: "/find-plugins"}
                ];
                $scope.isPageSelected = function (path) {
                    return $location.path() == path;
                };
                $scope.isTabSelected = function (path) {
                    var myPath = $location.path();
                    return  myPath.indexOf(path) != -1;
                };
                $scope.isMenuSelected = function (path) {
                    var myPath = $location.path();
                    return  myPath.indexOf(path) != -1;
                };

                $scope.showPluginDetail = function (pluginClass) {
                    $scope.selectedPlugin  = extracted(pluginClass);
                };
                $scope.installPlugin = function (pluginClass) {
                    $rootScope.pluginsCache = null;
                    $scope.selectedPlugin  = extracted(pluginClass);
                    if($scope.selectedPlugin){
                        $http.post($rootScope.REST.pluginInstall+pluginClass).success(function (data) {
                            // we'll get error message or
                            $scope.init();
                        });
                    }
                };

                //fetch plugin list
                $scope.init = function () {

                    if ($rootScope.pluginsCache) {
                        processItems($rootScope.pluginsCache);
                    } else {
                        $http.get($rootScope.REST.plugins).success(function (data) {
                            $rootScope.pluginsCache = data.items;
                            processItems(data.items);
                        });
                    }

                    function processItems(items) {
                        $scope.plugins = items;
                        $scope.pluginNeedsInstall = [];
                        for (var i = 0; i < items.length; i++) {
                            var obj = items[i];
                            if (obj.needsInstallation) {
                                $scope.pluginNeedsInstall.push(obj);
                            }
                        }
                    }

                };
                $scope.init();
                function extracted(pluginClass) {
                    for (var i = 0; i < $scope.plugins.length; i++) {
                        var selected = $scope.plugins[i];
                        if (selected.pluginClass == pluginClass) {
                            return selected;
                        }

                    }
                    return null;
                }

            })

        /*
         //############################################
         // ON LOAD CONTROLLER
         //############################################
         */
            .controller('homeCtrl', function ($scope, $http, $rootScope) {
                $scope.plugins = [];
                $scope.init = function () {
                    $http.get($rootScope.REST.plugins).success(function (data) {
                        $scope.plugins =  [];
                        var items = data.items;
                        for (var i = 0; i < items.length; i++) {
                            var plugin = items[i];

                            if(plugin.dateInstalled){
                                $scope.plugins.push(plugin);
                            }

                        }
                    });

                };
                $scope.init();

            })

        /*
         //############################################
         // MENU CONTROLLER
         //############################################
         */
            .controller('mainMenuCtrl', ['$scope', '$location', '$rootScope',  'menuService', function ($scope, $location, $rootScope, menuService) {

                $scope.$watch(function () {
                    return $rootScope.busyLoading;
                }, function () {
                    $scope.menu = menuService.getMenu();
                });

                $scope.isPageSelected = function (path) {
                    var myPath = $location.path();
                    // stay in plugins for all /plugin paths
                    if (myPath == "/find-plugins" || myPath.indexOf("/plugins") != -1) {
                        myPath = '/plugins';
                    }
                    else if (myPath.slice(0, "/tools".length) == "/tools") {
                        myPath = '/tools';
                    }
                    return  '#' + myPath == path;
                };

                $scope.onMenuClick = function (menuItem) {
                   //
                };

            }]);

})();<commit_msg>- use angular for each loops<commit_after>(function () {
    "use strict";
    angular.module('hippo.essentials')

        //############################################
        // MENU DATA
        //############################################
            .service('menuService', function () {
                this.getMenu = function () {
                    return [
                        {name: "Plugins", link: "#/plugins"},
                        {name: "Tools", link: "#/tools"}
                    ];
                };

            })

        //############################################
        // PLUGINS CONTROLLER LOADER
        //############################################
            .controller('pluginLoaderCtrl',function ($scope, $sce, $log, $rootScope, $http, MyHttpInterceptor) {

            }).controller('toolCtrl', function ($scope, $sce, $log, $rootScope, $http, MyHttpInterceptor) {
                // does nothing for time being
            })
            .controller('pluginCtrl', function ($scope, $location, $sce, $log, $rootScope, $http) {

                $scope.allPluginsInstalled = "No additional plugins could be found";
                $scope.plugins = [];
                $scope.pluginNeedsInstall = [];
                $scope.selectedPlugin = null;
                $scope.tabs = [
                    {name: "Installed Plugins", link: "/plugins"},
                    {name: "Find additional", link: "/find-plugins"}
                ];
                $scope.isPageSelected = function (path) {
                    return $location.path() == path;
                };
                $scope.isTabSelected = function (path) {
                    var myPath = $location.path();
                    return  myPath.indexOf(path) != -1;
                };
                $scope.isMenuSelected = function (path) {
                    var myPath = $location.path();
                    return  myPath.indexOf(path) != -1;
                };

                $scope.showPluginDetail = function (pluginClass) {
                    $scope.selectedPlugin  = extracted(pluginClass);
                };
                $scope.installPlugin = function (pluginClass) {
                    $rootScope.pluginsCache = null;
                    $scope.selectedPlugin  = extracted(pluginClass);
                    if($scope.selectedPlugin){
                        $http.post($rootScope.REST.pluginInstall+pluginClass).success(function (data) {
                            // we'll get error message or
                            $scope.init();
                        });
                    }
                };

                //fetch plugin list
                $scope.init = function () {
                    if ($rootScope.pluginsCache) {
                        processItems($rootScope.pluginsCache);
                    } else {
                        $http.get($rootScope.REST.plugins).success(function (data) {
                            $rootScope.pluginsCache = data.items;
                            processItems(data.items);
                        });
                    }

                    function processItems(items) {
                        $scope.plugins = items;
                        $scope.pluginNeedsInstall = [];
                        angular.forEach(items, function (obj) {
                            if (obj.needsInstallation) {
                                $scope.pluginNeedsInstall.push(obj);
                            }
                        });
                    }
                };
                $scope.init();
                function extracted(pluginClass) {
                    angular.forEach($scope.plugins, function (selected) {
                        if (selected.pluginClass == pluginClass) {
                            return selected;
                        }
                    });
                    return null;
                }
            })

        /*
         //############################################
         // ON LOAD CONTROLLER
         //############################################
         */
            .controller('homeCtrl', function ($scope, $http, $rootScope) {
                $scope.plugins = [];
                $scope.init = function () {
                    $http.get($rootScope.REST.plugins).success(function (data) {
                        $scope.plugins =  [];
                        var items = data.items;
                        angular.forEach(items, function (plugin) {
                            if (plugin.dateInstalled) {
                                $scope.plugins.push(plugin);
                            }
                        });
                    });

                };
                $scope.init();

            })

        /*
         //############################################
         // MENU CONTROLLER
         //############################################
         */
            .controller('mainMenuCtrl', ['$scope', '$location', '$rootScope',  'menuService', function ($scope, $location, $rootScope, menuService) {

                $scope.$watch(function () {
                    return $rootScope.busyLoading;
                }, function () {
                    $scope.menu = menuService.getMenu();
                });

                $scope.isPageSelected = function (path) {
                    var myPath = $location.path();
                    // stay in plugins for all /plugin paths
                    if (myPath == "/find-plugins" || myPath.indexOf("/plugins") != -1) {
                        myPath = '/plugins';
                    }
                    else if (myPath.slice(0, "/tools".length) == "/tools") {
                        myPath = '/tools';
                    }
                    return  '#' + myPath == path;
                };

                $scope.onMenuClick = function (menuItem) {
                   //
                };

            }]);

})();<|endoftext|>


<commit_before>"use strict";
var etg = require("../etg");
var Cards = require("../Cards");
var Actives = require("../Actives");
var etgutil = require("../etgutil");
module.exports = function(level) {
	if (!Cards.loaded){
		return;
	}
	var uprate = level == 0 ? 0 : level == 1 ? .1 : .3;
	function upCode(x) {
		return uprate ? etgutil.asUpped(x, Math.random() < uprate) : x;
	}
	var cardcount = {};
	var eles = [etg.PlayerRng.uptoceil(12), etg.PlayerRng.uptoceil(12)], ecost = new Array(13);
	for (var i = 0;i < 13;i++) {
		ecost[i] = 0;
	}
	ecost[eles[1]] -= 5 * (level > 1 ? 2 : 1);
	var deck = [], banned = [Cards.Give, Cards.GiveUp, Cards.Reinforce];
	var anyshield = 0, anyweapon = 0;
	eles.forEach(function(ele, j){
		for (var i = 20-j*10; i>0; i--) {
			var maxRarity = level == 0 ? 2 : (level == 1 ? 3 : 4);
			var card = etg.PlayerRng.randomcard(Math.random() < uprate, function(x) {
				return x.element == ele && x.type != etg.PillarEnum && x.rarity <= maxRarity && cardcount[x.code] != 6 &&
					!(x.type == etg.ShieldEnum && anyshield == 3) && !(x.type == etg.WeaponEnum && anyweapon == 3) && !~banned.indexOf(x);
			});
			deck.push(card.code);
			cardcount[card.code] = (cardcount[card.code] || 0) + 1;
			if (!(((card.type == etg.WeaponEnum && !anyweapon) || (card.type == etg.ShieldEnum && !anyshield)) && cardcount[card.code])) {
				ecost[card.costele] += card.cost;
			}
			if (card.cast) {
				ecost[card.castele] += card.cast * 1.5;
			}
			if (card.isOf(Cards.Nova)) {
				for (var k = 1;k < 13;k++) {
					ecost[k]--;
				}
			}else if (card.isOf(Cards.GiftofOceanus)){
				ecost[etg.Water] -= 3;
				ecost[eles[1]] -= 2;
			}else if (card.type == etg.CreatureEnum){
				var auto = card.active.auto;
				if (auto == Actives.light) ecost[etg.Light]--;
				else if (auto == Actives.fire) ecost[etg.Fire]--;
				else if (auto == Actives.air) ecost[etg.Air]--;
				else if (auto == Actives.earth) ecost[etg.Earth]--;
			}else if (card.type == etg.ShieldEnum) anyshield++;
			else if (card.type == etg.WeaponEnum) anyweapon++;
		}
	});
	if (!anyshield) {
		var card = Cards.Codes[deck[0]];
		ecost[card.costele] -= card.cost;
		deck[0] = upCode(Cards.Shield.code);
	}
	if (!anyweapon) {
		var card = Cards.Codes[deck[1]];
		ecost[card.costele] -= card.cost;
		deck[1] = upCode((eles[1] == etg.Air || eles[1] == etg.Light ? Cards.ShortBow :
			eles[1] == etg.Gravity || eles[1] == etg.Earth ? Cards.Hammer :
			eles[1] == etg.Water || eles[1] == etg.Life ? Cards.Wand :
			eles[1] == etg.Darkness || eles[1] == etg.Death ? Cards.Dagger :
			eles[1] == etg.Entropy || eles[1] == etg.Aether ? Cards.Disc :
			Cards.ShortSword).code);
	}
	var pillarstart = deck.length, qpe = 0, qpemin = 99;
	for (var i = 1;i < 13;i++) {
		if (!ecost[i]) continue;
		qpe++;
		qpemin = Math.min(qpemin, ecost[i]);
	}
	if (qpe >= 4) {
		for (var i = 0;i < qpemin * .8;i++) {
			deck.push(upCode(Cards.QuantumPillar.code));
			qpe++;
		}
	} else qpemin = 0;
	for (var i = 1;i < 13;i++) {
		if (ecost[i] > 0){
			for (var j = 0;j < Math.round((ecost[i] - qpemin) / 5); j++) {
				deck.push(upCode(etg.PillarList[i]));
			}
		}
	}
	deck.push(etg.toTrueMark(eles[1]));
	return etgutil.encodedeck(deck);
}<commit_msg>Allow unupped Reinforce in AI decks<commit_after>"use strict";
var etg = require("../etg");
var Cards = require("../Cards");
var Actives = require("../Actives");
var etgutil = require("../etgutil");
module.exports = function(level) {
	if (!Cards.loaded){
		return;
	}
	var uprate = level == 0 ? 0 : level == 1 ? .1 : .3;
	function upCode(x) {
		return uprate ? etgutil.asUpped(x, Math.random() < uprate) : x;
	}
	var cardcount = {};
	var eles = [etg.PlayerRng.uptoceil(12), etg.PlayerRng.uptoceil(12)], ecost = new Array(13);
	for (var i = 0;i < 13;i++) {
		ecost[i] = 0;
	}
	ecost[eles[1]] -= 5 * (level > 1 ? 2 : 1);
	var deck = [];
	var anyshield = 0, anyweapon = 0;
	eles.forEach(function(ele, j){
		for (var i = 20-j*10; i>0; i--) {
			var maxRarity = level == 0 ? 2 : (level == 1 ? 3 : 4);
			var card = etg.PlayerRng.randomcard(Math.random() < uprate, function(x) {
				return x.element == ele && x.type != etg.PillarEnum && x.rarity <= maxRarity && cardcount[x.code] != 6 &&
					!(x.type == etg.ShieldEnum && anyshield == 3) && !(x.type == etg.WeaponEnum && anyweapon == 3) && !x.isOf(Cards.Give);
			});
			deck.push(card.code);
			cardcount[card.code] = (cardcount[card.code] || 0) + 1;
			if (!(((card.type == etg.WeaponEnum && !anyweapon) || (card.type == etg.ShieldEnum && !anyshield)) && cardcount[card.code])) {
				ecost[card.costele] += card.cost;
			}
			if (card.cast) {
				ecost[card.castele] += card.cast * 1.5;
			}
			if (card.isOf(Cards.Nova)) {
				for (var k = 1;k < 13;k++) {
					ecost[k]--;
				}
			}else if (card.isOf(Cards.GiftofOceanus)){
				ecost[etg.Water] -= 3;
				ecost[eles[1]] -= 2;
			}else if (card.type == etg.CreatureEnum){
				var auto = card.active.auto;
				if (auto == Actives.light) ecost[etg.Light]--;
				else if (auto == Actives.fire) ecost[etg.Fire]--;
				else if (auto == Actives.air) ecost[etg.Air]--;
				else if (auto == Actives.earth) ecost[etg.Earth]--;
			}else if (card.type == etg.ShieldEnum) anyshield++;
			else if (card.type == etg.WeaponEnum) anyweapon++;
		}
	});
	if (!anyshield) {
		var card = Cards.Codes[deck[0]];
		ecost[card.costele] -= card.cost;
		deck[0] = upCode(Cards.Shield.code);
	}
	if (!anyweapon) {
		var card = Cards.Codes[deck[1]];
		ecost[card.costele] -= card.cost;
		deck[1] = upCode((eles[1] == etg.Air || eles[1] == etg.Light ? Cards.ShortBow :
			eles[1] == etg.Gravity || eles[1] == etg.Earth ? Cards.Hammer :
			eles[1] == etg.Water || eles[1] == etg.Life ? Cards.Wand :
			eles[1] == etg.Darkness || eles[1] == etg.Death ? Cards.Dagger :
			eles[1] == etg.Entropy || eles[1] == etg.Aether ? Cards.Disc :
			Cards.ShortSword).code);
	}
	var pillarstart = deck.length, qpe = 0, qpemin = 99;
	for (var i = 1;i < 13;i++) {
		if (!ecost[i]) continue;
		qpe++;
		qpemin = Math.min(qpemin, ecost[i]);
	}
	if (qpe >= 4) {
		for (var i = 0;i < qpemin * .8;i++) {
			deck.push(upCode(Cards.QuantumPillar.code));
			qpe++;
		}
	} else qpemin = 0;
	for (var i = 1;i < 13;i++) {
		if (ecost[i] > 0){
			for (var j = 0;j < Math.round((ecost[i] - qpemin) / 5); j++) {
				deck.push(upCode(etg.PillarList[i]));
			}
		}
	}
	deck.push(etg.toTrueMark(eles[1]));
	return etgutil.encodedeck(deck);
}<|endoftext|>


<commit_before>function main()
{
  // Create the "engine" object with the main components
  var e = TankJS.addObject("Engine").addComponents("InputManager, Canvas, CollisionManager, RenderManager, GameLogic");

  // Point the render manager's context to the canvas one
  // Would be nice not to require this somehow?
  e.attr("RenderManager", {context: e.getComponent("Canvas").context})

  // Create a bullet object prefab
  TankJS.addPrefab("Bullet",
  {
    "ColoredBox": { width: 5, height: 5 },
    "Velocity": {},
    "Collider": { width: 5, height: 5 },
    "DeleteOnCollide": {},
    "DeleteOutOfBounds": {},
    "InvokeOnCollide": {invokeOther: "TakeDamage", argOther: 1}
  });

  // Create a player object
  TankJS.addObject("Player").addComponents("Text, Image, TopDownMovement, RotateController, ObjectSpawner, Collider, Health, CustomUpdate")
                            .attr("2D", {x: 150, y: 100})
                            .attr("Image", {imagePath: "res/BlueBall.png"})
                            .attr("Health", {max: 50, value: 1})
                            .attr("Text", {color: "#000", text: "50", zdepth: 1, offsetX: -5, offsetY: 4})
                            .attr("ObjectSpawner", {objectPrefab: "Bullet", triggerKey: TankJS.SPACE})
                            .attr("CustomUpdate", {func: function(dt)
                              {
                                this.getComponent("Text").text = this.getComponent("Health").value;
                              }});

  // Create AI object
  TankJS.addObject("AI").addComponents("Text, Image, KlangAI, ObjectSpawner, Collider, Health, CustomUpdate")
                        .attr("2D", {x: 450, y: 400})
                        .attr("Image", {imagePath: "res/RedBall.png"})
                        .attr("Health", {max: 50, value: 50})
                        .attr("Text", {color: "#000", text: "50", zdepth: 1, offsetX: -5, offsetY: 4})
                        .attr("ObjectSpawner", {objectPrefab: "Bullet"})
                        .attr("CustomUpdate", {func: function(dt)
                          {
                            this.getComponent("Text").text = this.getComponent("Health").value;
                          }});

  // Create walls around edges
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 640 / 2, y: -25}).attr("Collider", {isStatic: true, width: 640});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 640 / 2, y: 480 + 25}).attr("Collider", {isStatic: true, width: 640});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: -25, y: 480 / 2}).attr("Collider", {isStatic: true, height: 480});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 640 + 25, y: 480 / 2}).attr("Collider", {isStatic: true, height: 480});

  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 100, y: 150}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 150, y: 150}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 200, y: 150}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 200, y: 100}).attr("Collider", {isStatic: true});

  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 400, y: 350}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 450, y: 350}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 500, y: 350}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 500, y: 400}).attr("Collider", {isStatic: true});

  TankJS.start();
}

// Custom game logic component to manage general state of game
TankJS.addComponent("GameLogic")

.initFunction(function()
{
  TankJS.addEventListener("OnEnterFrame", this);
})

.uninitFunction(function()
{
  TankJS.removeEventListener("OnEnterFrame", this);
})

.addFunction("OnEnterFrame", function(dt)
{
  if (!TankJS.getNamedObject("Player") || !TankJS.getNamedObject("AI"))
  {
    TankJS.reset();
  }
});

// Custom component to implement AI for the other player
TankJS.addComponent("KlangAI")

.includes("2D")

.initFunction(function()
{
  this._desiredAngle = 0;
  this._rotateTimer = 0;
  this._rotateAmount = 0.5;
  this._movementSpeed = 50;
  this._left = false;
  this._up = false;
  this._right = false;
  this._down = false;

  TankJS.addEventListener("OnEnterFrame", this);
})

.uninitFunction(function()
{
  TankJS.removeEventListener("OnEnterFrame", this);
})

.addFunction("OnEnterFrame", function(dt)
{
  this._rotateTimer -= dt;

  var player = TankJS.getNamedObject("Player");
  if (!player)
    return;

  var playerPos = player.getComponent("2D");
  var pos = this.parent.getComponent("2D");
  var gun = this.parent.getComponent("ObjectSpawner");

  // Shoot randomly
  if (Math.random() < 0.05)
    gun.spawn();

  // Move around semi-randomly
  if (Math.random() < 0.01)
    this._up = true;
  if (Math.random() < 0.01)
    this._left = true;
  if (Math.random() < 0.01)
    this._right = true;
  if (Math.random() < 0.01)
    this._down = true;
  if (Math.random() < 0.01)
    this._up = false;
  if (Math.random() < 0.01)
    this._left = false;
  if (Math.random() < 0.01)
    this._right = false;
  if (Math.random() < 0.01)
    this._down = false;

  // Apply movement
  if (this._left)
    pos.x -= this._movementSpeed * dt;
  if (this._up)
    pos.y -= this._movementSpeed * dt;
  if (this._right)
    pos.x += this._movementSpeed * dt;
  if (this._down)
    pos.y += this._movementSpeed * dt;

  // Aim at player
  var angle = TankJS.Math.angleToPoint([pos.x, pos.y], [playerPos.x, playerPos.y]);
  if (this._rotateTimer <= this._rotateAmount)
  {
    if (pos.rotation < angle)
      pos.rotation += 0.1;
    else
      pos.rotation -= 0.1;
  }
  if (this._rotateTimer <= 0)
  {
    this._rotateTimer = this._rotateAmount + Math.random() * 3 + 0.5;
    this._rotateAmount = 0.1 + Math.random() * 1;
  }
});<commit_msg>Modify Klang sample health<commit_after>function main()
{
  // Create the "engine" object with the main components
  var e = TankJS.addObject("Engine").addComponents("InputManager, Canvas, CollisionManager, RenderManager, GameLogic");

  // Point the render manager's context to the canvas one
  // Would be nice not to require this somehow?
  e.attr("RenderManager", {context: e.getComponent("Canvas").context})

  // Create a bullet object prefab
  TankJS.addPrefab("Bullet",
  {
    "ColoredBox": { width: 5, height: 5 },
    "Velocity": {},
    "Collider": { width: 5, height: 5 },
    "DeleteOnCollide": {},
    "DeleteOutOfBounds": {},
    "InvokeOnCollide": {invokeOther: "TakeDamage", argOther: 1}
  });

  // Create a player object
  TankJS.addObject("Player").addComponents("Text, Image, TopDownMovement, RotateController, ObjectSpawner, Collider, Health, CustomUpdate")
                            .attr("2D", {x: 150, y: 100})
                            .attr("Image", {imagePath: "res/BlueBall.png"})
                            .attr("Health", {max: 20, value: 20})
                            .attr("Text", {color: "#000", zdepth: 1, offsetX: -5, offsetY: 4})
                            .attr("ObjectSpawner", {objectPrefab: "Bullet", triggerKey: TankJS.SPACE})
                            .attr("CustomUpdate", {func: function(dt)
                              {
                                this.getComponent("Text").text = this.getComponent("Health").value;
                              }});

  // Create AI object
  TankJS.addObject("AI").addComponents("Text, Image, KlangAI, ObjectSpawner, Collider, Health, CustomUpdate")
                        .attr("2D", {x: 450, y: 400})
                        .attr("Image", {imagePath: "res/RedBall.png"})
                        .attr("Health", {max: 20, value: 20})
                        .attr("Text", {color: "#000", zdepth: 1, offsetX: -5, offsetY: 4})
                        .attr("ObjectSpawner", {objectPrefab: "Bullet"})
                        .attr("CustomUpdate", {func: function(dt)
                          {
                            this.getComponent("Text").text = this.getComponent("Health").value;
                          }});

  // Create walls around edges
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 640 / 2, y: -25}).attr("Collider", {isStatic: true, width: 640});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 640 / 2, y: 480 + 25}).attr("Collider", {isStatic: true, width: 640});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: -25, y: 480 / 2}).attr("Collider", {isStatic: true, height: 480});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 640 + 25, y: 480 / 2}).attr("Collider", {isStatic: true, height: 480});

  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 100, y: 150}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 150, y: 150}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 200, y: 150}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 200, y: 100}).attr("Collider", {isStatic: true});

  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 400, y: 350}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 450, y: 350}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 500, y: 350}).attr("Collider", {isStatic: true});
  TankJS.addObject().addComponents("ColoredBox, Collider").attr("2D", {x: 500, y: 400}).attr("Collider", {isStatic: true});

  TankJS.start();
}

// Custom game logic component to manage general state of game
TankJS.addComponent("GameLogic")

.initFunction(function()
{
  TankJS.addEventListener("OnEnterFrame", this);
})

.uninitFunction(function()
{
  TankJS.removeEventListener("OnEnterFrame", this);
})

.addFunction("OnEnterFrame", function(dt)
{
  if (!TankJS.getNamedObject("Player") || !TankJS.getNamedObject("AI"))
  {
    TankJS.reset();
  }
});

// Custom component to implement AI for the other player
TankJS.addComponent("KlangAI")

.includes("2D")

.initFunction(function()
{
  this._desiredAngle = 0;
  this._rotateTimer = 0;
  this._rotateAmount = 0.5;
  this._movementSpeed = 50;
  this._left = false;
  this._up = false;
  this._right = false;
  this._down = false;

  TankJS.addEventListener("OnEnterFrame", this);
})

.uninitFunction(function()
{
  TankJS.removeEventListener("OnEnterFrame", this);
})

.addFunction("OnEnterFrame", function(dt)
{
  this._rotateTimer -= dt;

  var player = TankJS.getNamedObject("Player");
  if (!player)
    return;

  var playerPos = player.getComponent("2D");
  var pos = this.parent.getComponent("2D");
  var gun = this.parent.getComponent("ObjectSpawner");

  // Shoot randomly
  if (Math.random() < 0.05)
    gun.spawn();

  // Move around semi-randomly
  if (Math.random() < 0.01)
    this._up = true;
  if (Math.random() < 0.01)
    this._left = true;
  if (Math.random() < 0.01)
    this._right = true;
  if (Math.random() < 0.01)
    this._down = true;
  if (Math.random() < 0.01)
    this._up = false;
  if (Math.random() < 0.01)
    this._left = false;
  if (Math.random() < 0.01)
    this._right = false;
  if (Math.random() < 0.01)
    this._down = false;

  // Apply movement
  if (this._left)
    pos.x -= this._movementSpeed * dt;
  if (this._up)
    pos.y -= this._movementSpeed * dt;
  if (this._right)
    pos.x += this._movementSpeed * dt;
  if (this._down)
    pos.y += this._movementSpeed * dt;

  // Aim at player
  var angle = TankJS.Math.angleToPoint([pos.x, pos.y], [playerPos.x, playerPos.y]);
  if (this._rotateTimer <= this._rotateAmount)
  {
    if (pos.rotation < angle)
      pos.rotation += 0.1;
    else
      pos.rotation -= 0.1;
  }
  if (this._rotateTimer <= 0)
  {
    this._rotateTimer = this._rotateAmount + Math.random() * 3 + 0.5;
    this._rotateAmount = 0.1 + Math.random() * 1;
  }
});<|endoftext|>


<commit_before>$.backstretch([
  	"/static/images/lockscreen/1.jpg",
  	"/static/images/lockscreen/2.jpg",
  	"/static/images/lockscreen/3.jpg",
  	"/static/images/lockscreen/4.jpg",
  	"/static/images/lockscreen/5.jpg",
  	"/static/images/lockscreen/6.jpg",
  	"/static/images/lockscreen/7.jpg",
  	"/static/images/lockscreen/8.jpg",
  	"/static/images/lockscreen/9.jpg",
  	"/static/images/lockscreen/10.jpg",
  	"/static/images/lockscreen/11.jpg",
  	"/static/images/lockscreen/12.jpg",
  	"/static/images/lockscreen/13.jpg"
], {
    fade: 1000,
    duration: 16000
});
<commit_msg>js lockscreen cleansing<commit_after>$.backstretch([
 	"/static/images/lockscreen/1.jpg",
 	"/static/images/lockscreen/2.jpg",
 	"/static/images/lockscreen/3.jpg",
 	"/static/images/lockscreen/4.jpg",
 	"/static/images/lockscreen/5.jpg",
 	"/static/images/lockscreen/6.jpg",
 	"/static/images/lockscreen/7.jpg",
 	"/static/images/lockscreen/8.jpg",
 	"/static/images/lockscreen/9.jpg",
 	"/static/images/lockscreen/10.jpg",
 	"/static/images/lockscreen/11.jpg",
 	"/static/images/lockscreen/12.jpg",
  	"/static/images/lockscreen/13.jpg",
], {
    fade: 1000,
    duration: 4000
});
<|endoftext|>


<commit_before>import { triggerAnims } from '@bolt/components-animate/utils';

export function enableAnimDemos() {
  function setTriggerText({ trigger, totalAnims, stage }) {
    trigger.innerText = `Trigger ${totalAnims} Animations ${stage}`;
  }

  setTimeout(() => {
    document.querySelectorAll('.demo-animate').forEach(animDemo => {
      let triggeredIn = false;
      const trigger = animDemo.querySelector('.demo-animate__trigger');
      const wrapper = animDemo.querySelector('.demo-animate__wrapper');
      let animEls = Array.from(animDemo.querySelectorAll('bolt-animate'));
      setTriggerText({ trigger, stage: 'IN', totalAnims: animEls.length });

      trigger.addEventListener('click', () => {
        animEls = Array.from(animDemo.querySelectorAll('bolt-animate'));
        const stage = triggeredIn ? 'OUT' : 'IN';
        triggerAnims({ animEls, stage, debug: false }).then(() => {
          // console.log('all done');
        });
        triggeredIn = !triggeredIn;
        setTriggerText({ trigger, stage, totalAnims: animEls.length });
      });
    });
  }, 0);
}
<commit_msg>docs(animate): adjust trigger demo anim JS<commit_after>import { polyfillLoader } from '@bolt/core/polyfills';
import { triggerAnims } from '@bolt/components-animate/utils';

export function enableAnimDemos() {
  polyfillLoader.then(() => {
    function setTriggerText({ trigger, totalAnims, stage }) {
      trigger.innerText = `Trigger ${totalAnims} Animations ${stage}`;
    }

    setTimeout(() => {
      document.querySelectorAll('.demo-animate').forEach(animDemo => {
        let triggeredIn = false;
        const trigger = animDemo.querySelector('.demo-animate__trigger');
        const wrapper = animDemo.querySelector('.demo-animate__wrapper');
        let animEls = Array.from(animDemo.querySelectorAll('bolt-animate'));
        setTriggerText({ trigger, stage: 'IN', totalAnims: animEls.length });
        animEls.forEach(x => x.classList.add('found-it'));

        trigger.addEventListener('click', () => {
          animEls.forEach(x => x.classList.add('ran-it'));
          animEls = Array.from(animDemo.querySelectorAll('bolt-animate'));
          const stage = triggeredIn ? 'OUT' : 'IN';
          triggerAnims({ animEls, stage, debug: false }).then(() => {
            // console.log('all done');
          });
          triggeredIn = !triggeredIn;
          setTriggerText({ trigger, stage, totalAnims: animEls.length });
        });
      });
    }, 1000);
  });
}
<|endoftext|>