<commit_before>const mix = require('laravel-mix');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const CopyWebpackPlugin = require('copy-webpack-plugin');
const imageminMozjpeg = require('imagemin-mozjpeg');

require('laravel-mix-tailwind');
require('laravel-mix-purgecss');

/**
 * Webpack config
 */

mix.webpackConfig({
    plugins: [
        new CopyWebpackPlugin([{ from: 'resources/img', to: 'img' }]),
        new ImageminPlugin({
            test: /\.(jpe?g|png|gif)$/i,
            plugins: [imageminMozjpeg({ quality: 70 })]
        })
    ]
});

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css')
    .tailwind()
    .options({
        processCssUrls: false
    })
    .purgeCss();

if (mix.inProduction()) {
    mix.version();
}
<commit_msg>Fixed bug where purgecss removed css for community inviter<commit_after>const mix = require('laravel-mix');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const CopyWebpackPlugin = require('copy-webpack-plugin');
const imageminMozjpeg = require('imagemin-mozjpeg');

require('laravel-mix-tailwind');
require('laravel-mix-purgecss');

/**
 * Webpack config
 */

mix.webpackConfig({
    plugins: [
        new CopyWebpackPlugin([{ from: 'resources/img', to: 'img' }]),
        new ImageminPlugin({
            test: /\.(jpe?g|png|gif)$/i,
            plugins: [imageminMozjpeg({ quality: 70 })]
        })
    ]
});

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css')
    .tailwind()
    .options({ processCssUrls: false })
    .purgeCss({ whitelistPatternsChildren: [/CommunityInviter$/] });

if (mix.inProduction()) {
    mix.version();
}
<|endoftext|>


<commit_before>var webshot = require('webshot');

var url = "http://campusbab.com/api/root/foodTotal.php",
    collegeSeq = "275";

var request = require('request');
var querystring = require('querystring');

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        var info = JSON.parse(body);
        console.log(body);
        console.log(info.stargazers_count + " Stars");
        console.log(info.forks_count + " Forks");
    }
}

function getJson() {
    var options = {
        method: 'POST',
        url: 'http://campusbab.com/api/root/foodTotal.php',
        form: { 'collegeSeq': collegeSeq,
                'udid': '6AE7EAF5-5D16-4FE3-B406-BB01D354074E',
        },
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'User-Agent:': 'Cambab/1.5.0 (iPhone; iOS 8.1.1; Scale/2.00)',
        },
    };

    request(options, callback);

    console.log("END");
}

getJson();
<commit_msg>update<commit_after>var webshot = require('webshot');

var url = "http://campusbab.com/api/root/foodTotal.php",
    collegeSeq = "275";

var request = require('request');
var querystring = require('querystring');

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        var info = JSON.parse(body);

        max_main_length = 0;

        for (var idx in j['shopList']) {
            shop = j['shopList'][idx];

            name = shop['name'];
            location = shop['locName'];

            main = [];
            others = [];

            for (var jdx in shop['foodList']) {
                i = shop['foodList'][jdx];

                if (i['section'] == target_section) {
                    main.push(i['mainFood']);
                    others.push(i['foods'].split(','));

                    console.log(main[0]);
                }

                if (len(main) > max_main_length) {
                    max_main_length = len(main);
                }

                max_length = 0;
                for (var other in others) {
                    if (len(other) > max_length)
                        max_length = len(other);
                }

                new_others = [];
                for (var k in range(max_length)) {
                    subs = [];
                    for (var i in others) {
                        other = others[i];
                        try:
                            subs.push(other[k]);
                        except:
                            subs.push(' ');
                    }
                    new_others.push(subs);
                }

                menu = Menu(name, location, main, new_others);
                menus.push(menu);
            }
        }
    }
}

function getJson() {
    var options = {
        method: 'POST',
        url: 'http://campusbab.com/api/root/foodTotal.php',
        form: { 'collegeSeq': collegeSeq,
                'udid': '6AE7EAF5-5D16-4FE3-B406-BB01D354074E',
        },
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'User-Agent:': 'Cambab/1.5.0 (iPhone; iOS 8.1.1; Scale/2.00)',
        },
    };

    request(options, callback);

    console.log("END");
}

getJson();
<|endoftext|>


<commit_before>// Design Basic Game Solo Challenge

// This is a solo challenge

// Your mission description:
// Overall mission: build barricades before zombies come
// Goals: Create 5 barricades, don't encounter zombies
// Characters: Survivor (barricades built, positionZ, positionY), Zombies (positionX, positionY)
// Objects: Survivor, Zombie 1, Zombie 2, Zombie 3
// Functions: Move, build

// Pseudocode
// create survivor object with attributes of position and barricades built
// create zombie objects with position attributes
// create move function which allows player to change position on axes
// create build function, which increases the number of barricades by one
// if barricades == 5, player wins. If zombie position == player position, player gets bitten and dies

// Initial Code
var survivor = {
positionX: 0,
positionY: 0,
barricades: 0,

move: function(where){
  if (where == "up")
  this.positionY += 5;
  else if (where == "down")
    this.positionY -= 5;
  else if (where == "left")
    this.positionX -= 5;
  else if (where == "right")
    this.positionX += 5;
  else if (where == "stay")
    this.positionX += 0;

zombieOne.positionX = Math.floor((Math.random()*12)+1)
zombieOne.positionY = Math.floor((Math.random()*12)+1)

zombieTwo.positionX = Math.floor((Math.random()*12)+1)
zombieTwo.positionY = Math.floor((Math.random()*12)+1)

zombieThree.positionX = Math.floor((Math.random()*12)+1)
zombieThree.positionY = Math.floor((Math.random()*12)+1)

console.log("Survivor is at (" + survivor.positionX + "," + survivor.positionY + ")! ε=ε=(っ*´□`)っ" )

console.log("Zombie One is at (" + zombieOne.positionX + "," + zombieOne.positionY + ")! [¬º-°]¬")

console.log("Zombie Two is at (" + zombieTwo.positionX + "," + zombieTwo.positionY + ")! [¬º-°]¬")

console.log("Zombie Three is at (" + zombieThree.positionX + "," + zombieThree.positionY + ")! [¬º-°]¬")

if(survivor.positionX === zombieOne.positionX && survivor.positionY === zombieOne.positionY)
  console.log("Ouch! Zombie One bit you! Game Over (×□×；)");

if(survivor.positionX === zombieTwo.positionX && survivor.positionY === zombieTwo.positionY)
  console.log("Ouch! Zombie Two bit you! Game Over (×□×；)");

  if(survivor.positionX === zombieThree.positionX && survivor.positionY === zombieThree.positionY)
  console.log("Ouch! Zombie 3 bit you!! Game Over (×□×；)");

},

build: function(){
    this.barricades += 1;
    console.log("Survivor barricades increased by 1 ٩(^ᴗ^)۶")

      if(survivor.barricades === 3)
        console.log("You successfully barricaded the building! You are safe! ヽ(^o^)丿")
    }
}

var zombieOne = {
posX: Math.floor((Math.random()*12)+1),
posY: Math.floor((Math.random()*12)+1)
}
var zombieTwo = {
posX: Math.floor((Math.random()*12)+1),
posY: Math.floor((Math.random()*12)+1)
}

var zombieThree = {
posX: Math.floor((Math.random()*12)+1),
posY: Math.floor((Math.random()*12)+1)
}

survivor.build(1)
console.log(survivor.barricades)
survivor.move("up")
survivor.move("right")
survivor.move("down")
survivor.build(1)
survivor.move("right")
survivor.move("right")
survivor.move("up")
survivor.build(1)
console.log(survivor.barricades)

// Refactored Code

var survivor = {
pX: 1,
pY: 1,
barricades: 0,

move: function(where){ //survivor movement
  if (where == "up")
  this.pY += 2;

  else if (where == "down")
    this.pY -= 2;

  else if (where == "left")
    this.pX -= 2;

  else if (where == "right")
    this.pX += 2;

  else if (where == "stay")
    this.pX += 0;
// zombie movement
zombieOne.pX = Math.floor((Math.random()*12)+1)
zombieOne.pY = Math.floor((Math.random()*12)+1)

zombieTwo.pX = Math.floor((Math.random()*12)+1)
zombieTwo.pY = Math.floor((Math.random()*12)+1)

zombieThree.pX = Math.floor((Math.random()*12)+1)
zombieThree.pY = Math.floor((Math.random()*12)+1)

console.log("Survivor is at (" + survivor.pX + "," + survivor.pY + ")! ε=ε=(っ*´□`)っ" )

console.log("Zombie One is at (" + zombieOne.pX + "," + zombieOne.pY + ")! [¬º-°]¬")

console.log("Zombie Two is at (" + zombieTwo.pX + "," + zombieTwo.pY + ")! [¬º-°]¬")

console.log("Zombie Three is at (" + zombieThree.pX + "," + zombieThree.pY + ")! [¬º-°]¬")

if(survivor.pX === zombieOne.pX && survivor.pY === zombieOne.pY)
  console.log("Ouch! Zombie One bit you! Game Over (×□×；)")

else if(survivor.pX === zombieTwo.pX && survivor.pY === zombieTwo.pY)
  console.log("Ouch! Zombie Two bit you! Game Over (×□×；)")

  else if(survivor.pX === zombieThree.pX && survivor.pY === zombieThree.pY)
  console.log("Ouch! Zombie Three bit you!! Game Over (×□×；)");

},

build: function(){
    this.barricades += 1;
    console.log("Survivor barricades increased by 1 ٩(^ᴗ^)۶")

      if(survivor.barricades === 5)
        console.log("You successfully barricaded the building! You won! ヽ(^o^)丿")
    }
}

var zombieOne = {
pX: Math.floor((Math.random()*12)+1),
pY: Math.floor((Math.random()*12)+1)
}
var zombieTwo = {
pX: Math.floor((Math.random()*12)+1),
pY: Math.floor((Math.random()*12)+1)
}

var zombieThree = {
pX: Math.floor((Math.random()*12)+1),
pY: Math.floor((Math.random()*12)+1)
}

// I needed to research .floor and "this" in order to complete my initial solution. I was unable to refactor my solution any more, so I shortened the positionx and positiony variables to make the program look a little neater. I wish I could find a way to loop the zombie movement and test for zombie bite, but any attempts at this were unsuccessful. Also, I am aware I borrowed heavily for the basic concept of the game based on the example, but I hope I was able to change it enough to demonstrate my learning and proficiency with JavaScript.

// Reflection
// What was the most difficult part of this challenge?

// Honestly? Coming up with a game idea. I spent the first two hours trying to make a Shakespearean insult generator, but I couldn't get it to work propery and was just confusing myself, so I conuslted the provided example for more direction with what my game should be. This is why my game resembes that one so much, because I struggled to think of a game that could be run in JavaScript and I was proficient enough to write myself. So, I thought about a zombie game. I know that in terms of positioning my game is similar, but that's where I tried to stop my borrowing and demonstrate my own work.

// What did you learn about creating objects and functions that interact with one another?

// I'm seeing them more like Ruby classes now. While they aren't exactly the same, I think it is a helpful metaphor to contextualize what funcitons and objects are doing. I'm getting a better sense of flow control between functions, but I'm sure I could use more practice.

// Did you learn about any new built-in methods you could use in your refactored solution? If so, what were they and how do they work?
// I could not figure out a different way to generate positioning, so I researched the floor method that the example used in order to figure out how it works for myself. Similarly, I did not know a different way than using this. so I researched and implemented that as well. I could not find anything that I could use in my refactor.

// How can you access and manipulate properties of objects?

// I didn't realize that functions can be properties of objects, which really opened things up for me in terms of what I could do with my program. You can access properties within different properties, and change them even outside of the funtion, like I did with my barricades. I think it is cool that you can nest properties and functions, which is something I never experimented with before. You can call properties of objects just like you do methods, and you create them very similarly to how you create methods in classes. Again, not an exact metaphor, but it helps my brain figure out what the different pieces of the code are doing. My JavaScript certainly could use more work, but I feel pretty accomplished, especially concerning my build property of my survivor object.<commit_msg>Small spelling errors fix<commit_after>// Design Basic Game Solo Challenge

// This is a solo challenge

// Your mission description:
// Overall mission: build barricades before zombies come
// Goals: Create 5 barricades, don't encounter zombies
// Characters: Survivor (barricades built, positionZ, positionY), Zombies (positionX, positionY)
// Objects: Survivor, Zombie 1, Zombie 2, Zombie 3
// Functions: Move, build

// Pseudocode
// create survivor object with attributes of position and barricades built
// create zombie objects with position attributes
// create move function which allows player to change position on axes
// create build function, which increases the number of barricades by one
// if barricades == 5, player wins. If zombie position == player position, player gets bitten and dies

// Initial Code
var survivor = {
positionX: 0,
positionY: 0,
barricades: 0,

move: function(where){
  if (where == "up")
  this.positionY += 5;
  else if (where == "down")
    this.positionY -= 5;
  else if (where == "left")
    this.positionX -= 5;
  else if (where == "right")
    this.positionX += 5;
  else if (where == "stay")
    this.positionX += 0;

zombieOne.positionX = Math.floor((Math.random()*12)+1)
zombieOne.positionY = Math.floor((Math.random()*12)+1)

zombieTwo.positionX = Math.floor((Math.random()*12)+1)
zombieTwo.positionY = Math.floor((Math.random()*12)+1)

zombieThree.positionX = Math.floor((Math.random()*12)+1)
zombieThree.positionY = Math.floor((Math.random()*12)+1)

console.log("Survivor is at (" + survivor.positionX + "," + survivor.positionY + ")! ε=ε=(っ*´□`)っ" )

console.log("Zombie One is at (" + zombieOne.positionX + "," + zombieOne.positionY + ")! [¬º-°]¬")

console.log("Zombie Two is at (" + zombieTwo.positionX + "," + zombieTwo.positionY + ")! [¬º-°]¬")

console.log("Zombie Three is at (" + zombieThree.positionX + "," + zombieThree.positionY + ")! [¬º-°]¬")

if(survivor.positionX === zombieOne.positionX && survivor.positionY === zombieOne.positionY)
  console.log("Ouch! Zombie One bit you! Game Over (×□×；)");

if(survivor.positionX === zombieTwo.positionX && survivor.positionY === zombieTwo.positionY)
  console.log("Ouch! Zombie Two bit you! Game Over (×□×；)");

  if(survivor.positionX === zombieThree.positionX && survivor.positionY === zombieThree.positionY)
  console.log("Ouch! Zombie 3 bit you!! Game Over (×□×；)");

},

build: function(){
    this.barricades += 1;
    console.log("Survivor barricades increased by 1 ٩(^ᴗ^)۶")

      if(survivor.barricades === 3)
        console.log("You successfully barricaded the building! You are safe! ヽ(^o^)丿")
    }
}

var zombieOne = {
posX: Math.floor((Math.random()*12)+1),
posY: Math.floor((Math.random()*12)+1)
}
var zombieTwo = {
posX: Math.floor((Math.random()*12)+1),
posY: Math.floor((Math.random()*12)+1)
}

var zombieThree = {
posX: Math.floor((Math.random()*12)+1),
posY: Math.floor((Math.random()*12)+1)
}

survivor.build(1)
console.log(survivor.barricades)
survivor.move("up")
survivor.move("right")
survivor.move("down")
survivor.build(1)
survivor.move("right")
survivor.move("right")
survivor.move("up")
survivor.build(1)
console.log(survivor.barricades)

// Refactored Code

var survivor = {
pX: 1,
pY: 1,
barricades: 0,

move: function(where){ //survivor movement
  if (where == "up")
  this.pY += 2;

  else if (where == "down")
    this.pY -= 2;

  else if (where == "left")
    this.pX -= 2;

  else if (where == "right")
    this.pX += 2;

  else if (where == "stay")
    this.pX += 0;
// zombie movement
zombieOne.pX = Math.floor((Math.random()*12)+1)
zombieOne.pY = Math.floor((Math.random()*12)+1)

zombieTwo.pX = Math.floor((Math.random()*12)+1)
zombieTwo.pY = Math.floor((Math.random()*12)+1)

zombieThree.pX = Math.floor((Math.random()*12)+1)
zombieThree.pY = Math.floor((Math.random()*12)+1)

console.log("Survivor is at (" + survivor.pX + "," + survivor.pY + ")! ε=ε=(っ*´□`)っ" )

console.log("Zombie One is at (" + zombieOne.pX + "," + zombieOne.pY + ")! [¬º-°]¬")

console.log("Zombie Two is at (" + zombieTwo.pX + "," + zombieTwo.pY + ")! [¬º-°]¬")

console.log("Zombie Three is at (" + zombieThree.pX + "," + zombieThree.pY + ")! [¬º-°]¬")

if(survivor.pX === zombieOne.pX && survivor.pY === zombieOne.pY)
  console.log("Ouch! Zombie One bit you! Game Over (×□×；)")

else if(survivor.pX === zombieTwo.pX && survivor.pY === zombieTwo.pY)
  console.log("Ouch! Zombie Two bit you! Game Over (×□×；)")

  else if(survivor.pX === zombieThree.pX && survivor.pY === zombieThree.pY)
  console.log("Ouch! Zombie Three bit you!! Game Over (×□×；)");

},

build: function(){
    this.barricades += 1;
    console.log("Survivor barricades increased by 1 ٩(^ᴗ^)۶")

      if(survivor.barricades === 5)
        console.log("You successfully barricaded the building! You won! ヽ(^o^)丿")
    }
}

var zombieOne = {
pX: Math.floor((Math.random()*12)+1),
pY: Math.floor((Math.random()*12)+1)
}
var zombieTwo = {
pX: Math.floor((Math.random()*12)+1),
pY: Math.floor((Math.random()*12)+1)
}

var zombieThree = {
pX: Math.floor((Math.random()*12)+1),
pY: Math.floor((Math.random()*12)+1)
}

// I needed to research .floor and "this" in order to complete my initial solution. I was unable to refactor my solution any more, so I shortened the positionx and positiony variables to make the program look a little neater. I wish I could find a way to loop the zombie movement and test for zombie bite, but any attempts at this were unsuccessful. Also, I am aware I borrowed heavily for the basic concept of the game based on the example, but I hope I was able to change it enough to demonstrate my learning and proficiency with JavaScript.

// Reflection
// What was the most difficult part of this challenge?

// Honestly? Coming up with a game idea. I spent the first two hours trying to make a Shakespearean insult generator, but I couldn't get it to work properly and I was just confusing myself, so I conuslted the provided example for more direction with what my game should be. This is why my game resembes that one so much, because I struggled to think of a game that could be run in JavaScript and I was proficient enough to write myself. For my own game design, I thought about a zombie game. I know that in terms of positioning my game is similar, but that's where I tried to stop my borrowing and demonstrate my own work.

// What did you learn about creating objects and functions that interact with one another?

// I'm seeing them more like Ruby classes now. While they aren't exactly the same, I think it is a helpful metaphor to contextualize what funcitons and objects are doing. I'm getting a better sense of flow control between functions, but I'm sure I could use more practice.

// Did you learn about any new built-in methods you could use in your refactored solution? If so, what were they and how do they work?
// I could not figure out a different way to generate positioning, so I researched the floor method that the example used in order to figure out how it works for myself. Similarly, I did not know a different way than using this. so I researched and implemented that as well. I could not find anything that I could use in my refactor.

// How can you access and manipulate properties of objects?

// I didn't realize that functions can be properties of objects, which really opened things up for me in terms of what I could do with my program. You can access properties within different properties, and change them even outside of the funtion, like I did with my barricades. I think it is cool that you can nest properties and functions, which is something I never experimented with before. You can call properties of objects just like you do methods, and you create them very similarly to how you create methods in classes. Again, not an exact metaphor, but it helps my brain figure out what the different pieces of the code are doing. My JavaScript certainly could use more work, but I feel pretty accomplished, especially concerning my build property of my survivor object.<|endoftext|>


<commit_before>// Design Basic Game Solo Challenge

// This is a solo challenge

// Your mission description:
// Overall mission: Fight and defeat a dragon using your wits and strength
// Goals: Defeat the dragon
// Characters: Dragon, Hero
// Objects: Combatant
// Functions: Fight, LevelUp

// Pseudocode
//
//Create an object called COMBATANT, that has HEALTH, ATTACK POWER, DEFENSE, and LEVEL attributes. Create two instances of this called HERO, and DRAGON.
//
//Initialize the game by explaining the situation you are in, and the actions you have available to you. You are then prompted for a course of action. You have the option to attack or defend. The resulting attack takes your attack power, minus the dragon's defense power and subtracts that from dragon health. The same is true if the dragon attacks. You can either win by recuding the dragon's hit points to zero, or lose by your own hit points reaching zero. Upon winning you level up and DEFENSE is changed.
//

  // Initial Code
  function Combatant(health, attack, defense, level, weapon){
    this.health = health;
    this.attack = attack;
    this.defense = defense;
    this.level = level;
    this.weapon = weapon;
  }

  function Weapon(strength){
    this.strength = strength;
  }

  var Hero = new Combatant(150, 10, 0, 1);
  var Dragon = new Combatant(200, 5, 0, 1);
  var Sword = new Weapon(5);
  var Bow = new Weapon(1);

  var levelup = function(){
    console.log("*trumpets blaring* Your level has grown to 2! Your defense is now 1. Hot dog!");
    Hero.defense = 1;
    Hero.level = 2;
  }

  var gameover = function(){
    console.log("*Really sad downer music plays* The Dragon utterly decimated you. Tough luck bro. Did you ever really think there was a chance?")
  }

  var dracofight = function(){

    var weaponchoice = prompt("You have two weapons to choose from. Which do you pick? (1 for a broadsword of 5 attack power, and 2 for a bow of 1 attack power.")

      if(weaponchoice == 1){
        console.log("You chose to use the mighty broadsword. Very practical.")
        Hero.weapon = Sword;
      }

      else{
        console.log("You chose....the bow? Well hopefully you don't come to regret that decision.")
        Hero.weapon = Bow;
      }

      var choice = prompt("You are now inside a well lit chamber. There is a rather large chandelier above what appears to be a hungry dragon. This doesn't look good. What do you do? (1 to attack, 2 to defend, 3 to choose arrow target(if bow was chosen))", "type here");

      if(choice == 1){

        console.log("You attack the dragon with all your might!")
        Dragon.health = Dragon.health - (Hero.attack + Hero.weapon.strength - Dragon.defense);
        console.log("Dragon Health:" + Dragon.health)

        if(Dragon.health <= 0){
          console.log("YOU DEFEATED THE DRAGON. LONG LIVE THE CHAMPION!!!");
          levelup();
        }

        else{
          console.log("It's the Dragon's turn. It takes a swipe at you and hits hard.");
          Hero.health = Hero.health - (Dragon.attack - Hero.defense);
          console.log("Player Health:" + Hero.health);
          if(Hero.health <= 0){
            gameover();
          }
          else{
            dracofight();
          }

        }
      }

      else if(choice == 2){
        console.log("You choose to brace for impact.");
        Hero.health = Hero.health - (Dragon.attack - Hero.defense);
        console.log("Player Health:" + Hero.health);

      }

      else if(choice == 3 && Hero.weapon == Bow){
        console.log("Where would you like to aim? Oh and just fyi, the dragon is preparing to breathe some fire. This may be your only chance so use it well...")
        var target = prompt("Specify a location for the arrow. Use lowercase., target here")

        if(target == "chandelier"){
          console.log("Well too bad friend, the arrow....wait what? No way! You chose to shoot at the chandelier, which resulted in your arrow cutting the rope it was hanging by. The chandelier fell and killed the mighty dragon. Don't ask how. Just enjoy the victory.")
          levelup();
        }
        else{
          console.log("Your arrow doesn't hit anything. This doesn't look good...")
        }

      }
      else{
        console.log("Invalid input. Remember to only select 3 if you have the bow.")
      }
    }
    dracofight();
//

// Refactored Code

/*

// Reflection
//
What was the most difficult part of this challenge?

The most difficult thing was getting my initial idea to work properly. After that, it became a matter of how far I wanted to go with it.

What did you learn about creating objects and functions that interact with one another?

Creating objects and functions that work with each other is pretty intuitive, though incorporating a user into the mix with their own inputs took some research to figure out.

Did you learn about any new built-in methods you could use in your refactored solution? If so, what were they and how do they work?

I learned about prompt, which facilitates user input. It pulls up a field that allows the user to type a response, which then will affect the code in some way.

How can you access and manipulate properties of objects?

You can access them by writing the object name and the parameter you want.

*/
//
//
//
//
//
//<commit_msg>add explanation for game ending with missed arrow<commit_after>// Design Basic Game Solo Challenge

// This is a solo challenge

// Your mission description:
// Overall mission: Fight and defeat a dragon using your wits and strength
// Goals: Defeat the dragon
// Characters: Dragon, Hero
// Objects: Combatant
// Functions: Fight, LevelUp

// Pseudocode
//
//Create an object called COMBATANT, that has HEALTH, ATTACK POWER, DEFENSE, and LEVEL attributes. Create two instances of this called HERO, and DRAGON.
//
//Initialize the game by explaining the situation you are in, and the actions you have available to you. You are then prompted for a course of action. You have the option to attack or defend. The resulting attack takes your attack power, minus the dragon's defense power and subtracts that from dragon health. The same is true if the dragon attacks. You can either win by recuding the dragon's hit points to zero, or lose by your own hit points reaching zero. Upon winning you level up and DEFENSE is changed.
//

  // Initial Code
  function Combatant(health, attack, defense, level, weapon){
    this.health = health;
    this.attack = attack;
    this.defense = defense;
    this.level = level;
    this.weapon = weapon;
  }

  function Weapon(strength){
    this.strength = strength;
  }

  var Hero = new Combatant(150, 10, 0, 1);
  var Dragon = new Combatant(200, 5, 0, 1);
  var Sword = new Weapon(5);
  var Bow = new Weapon(1);

  var levelup = function(){
    console.log("*trumpets blaring* Your level has grown to 2! Your defense is now 1. Hot dog!");
    Hero.defense = 1;
    Hero.level = 2;
  }

  var gameover = function(){
    console.log("*Really sad downer music plays* The Dragon utterly decimated you. Tough luck bro. Did you ever really think there was a chance?")
  }

  var dracofight = function(){

    var weaponchoice = prompt("You have two weapons to choose from. Which do you pick? (1 for a broadsword of 5 attack power, and 2 for a bow of 1 attack power.")

      if(weaponchoice == 1){
        console.log("You chose to use the mighty broadsword. Very practical.")
        Hero.weapon = Sword;
      }

      else{
        console.log("You chose....the bow? Well hopefully you don't come to regret that decision.")
        Hero.weapon = Bow;
      }

      var choice = prompt("You are now inside a well lit chamber. There is a rather large chandelier above what appears to be a hungry dragon. This doesn't look good. What do you do? (1 to attack, 2 to defend, 3 to choose arrow target(if bow was chosen))", "type here");

      if(choice == 1){

        console.log("You attack the dragon with all your might!")
        Dragon.health = Dragon.health - (Hero.attack + Hero.weapon.strength - Dragon.defense);
        console.log("Dragon Health:" + Dragon.health)

        if(Dragon.health <= 0){
          console.log("YOU DEFEATED THE DRAGON. LONG LIVE THE CHAMPION!!!");
          levelup();
        }

        else{
          console.log("It's the Dragon's turn. It takes a swipe at you and hits hard.");
          Hero.health = Hero.health - (Dragon.attack - Hero.defense);
          console.log("Player Health:" + Hero.health);
          if(Hero.health <= 0){
            gameover();
          }
          else{
            dracofight();
          }

        }
      }

      else if(choice == 2){
        console.log("You choose to brace for impact.");
        Hero.health = Hero.health - (Dragon.attack - Hero.defense);
        console.log("Player Health:" + Hero.health);

      }

      else if(choice == 3 && Hero.weapon == Bow){
        console.log("Where would you like to aim? Oh and just fyi, the dragon is preparing to breathe some fire. This may be your only chance so use it well...")
        var target = prompt("Specify a location for the arrow. Use lowercase., target here")

        if(target == "chandelier"){
          console.log("Well too bad friend, the arrow....wait what? No way! You chose to shoot at the chandelier, which resulted in your arrow cutting the rope it was hanging by. The chandelier fell and killed the mighty dragon. Don't ask how. Just enjoy the victory.")
          levelup();
        }
        else{
          console.log("Your arrow doesn't hit anything. This doesn't look good...")
          gameover();
        }

      }
      else{
        console.log("Invalid input. Remember to only select 3 if you have the bow.")
      }
    }
    dracofight();
//

// Refactored Code

/*

// Reflection
//
What was the most difficult part of this challenge?

The most difficult thing was getting my initial idea to work properly. After that, it became a matter of how far I wanted to go with it.

What did you learn about creating objects and functions that interact with one another?

Creating objects and functions that work with each other is pretty intuitive, though incorporating a user into the mix with their own inputs took some research to figure out.

Did you learn about any new built-in methods you could use in your refactored solution? If so, what were they and how do they work?

I learned about prompt, which facilitates user input. It pulls up a field that allows the user to type a response, which then will affect the code in some way.

How can you access and manipulate properties of objects?

You can access them by writing the object name and the parameter you want.

*/
//
//
//
//
//
//<|endoftext|>


<commit_before>// Design Basic Game Solo Challenge

// This is a solo challenge

// Your mission description:
// Overall mission: Leprechaun collects 5 gold coins to have a full pot of gold
// Goals: collect gold coins, avoid trap
// Characters: leprechaun, gold coins, trap
// Objects: leprechaun(position, health, success, potOfGold, move), gold coins(name, position), trap(position)
// Functions: move for leprechaun, constructor function for coins, display coins

// Pseudocode
// CREATE a function to build a GoldCoin class that takes a name and creates random position coordinates
// SET 10 coin variables to new instances of the GoldCoin class
// SET a goldCoins variable equal to a list of the coins
// CREATE a function to display the coordinates for each coin
// SET a trap variable to random position coordinates
//
// SET a leprechaun variable to have a position of 0 for X & Y, potOfGold to 0, health to true,
// success false, and a move method
// CREATE a move method that takes a direction & number for the amount to move
//   UPDATE the leprechaun's coordinates based on the direction & number
//   DISPLAY the leprechaun's coordinates
//   IF the leprechaun's coordinates are equal to the trap's coordinates
//     UPDATE the leprechaun's health & display "Game Over"
//   ELSE IF the leprechaun's potOfGold is equal to 5
//     UPDATE the leprechaun's success & display "You Win"
//   ELSE iterate through the goldCoins list
//     IF the leprechaun's coordinates are equal to a coin's coordinates
//     DISPLAY "You found a coin"
//     INCREMENT the leprechaun's potOfGold by 1

// Initial Code
// function GoldCoin(coin) {
//   this.coin = coin;
//   this.posX = Math.floor(Math.random()*6 + 1),
//   this.posY = Math.floor(Math.random()*6 + 1)
// }

// var coin1 = new GoldCoin("Coin 1");
// var coin2 = new GoldCoin("Coin 2");
// var coin3 = new GoldCoin("Coin 3");
// var coin4 = new GoldCoin("Coin 4");
// var coin5 = new GoldCoin("Coin 5");
// var coin6 = new GoldCoin("Coin 6");
// var coin7 = new GoldCoin("Coin 7");
// var coin8 = new GoldCoin("Coin 8");
// var coin9 = new GoldCoin("Coin 9");
// var coin10 = new GoldCoin("Coin 10");

// var goldCoins = [ coin1, coin2, coin3, coin4, coin5, coin6, coin7, coin8, coin9, coin10];

// var displayCoins = function () {
//      for (var i = 0; i < goldCoins.length; i++) {
//       console.log(goldCoins[i].coin + "'s position is " + goldCoins[i].posX + "," + goldCoins[i].posY)
//     }
// }

// var trap = {
//   posX: Math.floor(Math.random()*6 + 1),
//   posY: Math.floor(Math.random()*6 + 1)
// };

// var leprechaun = {
//   posX: 0,
//   posY: 0,
//   potOfGold: 0,
//   health: true,
//   success: false,
//   move: function(direction, amount) {
//     if(direction === 'left'){
//       this.posX -= amount;
//     }
//     else if(direction === 'right'){
//       this.posX += amount;
//     }
//     else if(direction === 'up'){
//       this.posY -= amount;
//     }
//     else if(direction === 'down'){
//       this.posY += amount;
//     }

//     console.log("The leprechaun's position is " + this.posX + "," + this.posY);

//     if(this.posX === trap.posX && this.posY === trap.posY){
//       this.health = false;
//       return console.log("You're trapped and hurt. Game Over!");
//     }
//     else if(this.potOfGold === 5){
//       this.success = true;
//       return console.log("You're pot of gold is full, you win!!");
//     }
//     else {
//       for (var i = 0; i < goldCoins.length; i++) {
//         if (this.posX === goldCoins[i].posX && this.posY === goldCoins[i].posY) {
//           console.log("You found a gold coin!");
//           this.potOfGold += 1;
//         }
//       }
//     }

//   }

// };

// Refactored Code
function GoldCoin(coin) {
  this.coin = coin;
  this.posX = Math.floor(Math.random()*6 + 1),
  this.posY = Math.floor(Math.random()*6 + 1)
}

var coin1 = new GoldCoin("Coin 1");
var coin2 = new GoldCoin("Coin 2");
var coin3 = new GoldCoin("Coin 3");
var coin4 = new GoldCoin("Coin 4");
var coin5 = new GoldCoin("Coin 5");
var coin6 = new GoldCoin("Coin 6");
var coin7 = new GoldCoin("Coin 7");
var coin8 = new GoldCoin("Coin 8");
var coin9 = new GoldCoin("Coin 9");
var coin10 = new GoldCoin("Coin 10");

var goldCoins = [ coin1, coin2, coin3, coin4, coin5, coin6, coin7, coin8, coin9, coin10];

var displayCoins = function () {
     for (var i = 0; i < goldCoins.length; i++) {
      console.log(goldCoins[i].coin + "'s position is " + goldCoins[i].posX + "," + goldCoins[i].posY)
    }
}

var trap = {
  posX: Math.floor(Math.random()*6 + 1),
  posY: Math.floor(Math.random()*6 + 1)
};

var leprechaun = {
  posX: 0,
  posY: 0,
  potOfGold: 0,
  health: true,
  success: false,
  move: function(direction, amount) {
    switch(direction){
      case 'left': this.posX -= amount; break;
      case'right': this.posX += amount; break;
      case 'up': this.posY -= amount; break;
      case 'down': this.posY += amount; break;
    }

    console.log("The leprechaun's position is " + this.posX + "," + this.posY);

    if(this.posX === trap.posX && this.posY === trap.posY){
      this.health = false;
      console.log("You're trapped and hurt. Game Over!");
    }

    if(this.potOfGold === 5){
      this.success = true;
      console.log("You're pot of gold is full, you win!!");
    }

    for (var i = 0; i < goldCoins.length; i++) {
      if (this.posX === goldCoins[i].posX && this.posY === goldCoins[i].posY) {
        console.log("You found a gold coin!");
        this.potOfGold += 1;
      }
    }
  }

};

displayCoins();
leprechaun.move('down', 2);
leprechaun.move('right', 2);
leprechaun.move('right', 3);
leprechaun.move('left', 1);
leprechaun.move('down', 3);
leprechaun.move('left', 1);
leprechaun.move('left', 1);
leprechaun.move('up', 1);
leprechaun.move('up', 1);
leprechaun.move('right', 4);
displayCoins();
console.log(leprechaun.potOfGold);
console.log(leprechaun.success);
console.log(leprechaun.health);

// Reflection
/*
What was the most difficult part of this challenge?
Using the correct syntax and semantics was the most difficult part of this challenge.  When I would
test the code I would frequently receive the message 'SyntaxError: Unexpected token' or 'TypeError'.

What did you learn about creating objects and functions that interact with one another?
This challenge helped me to practice creating objects with functions as properties and using the
properties of other objects to update the value's in the object's properties.

Did you learn about any new built-in methods you could use in your refactored solution?
If so, what were they and how do they work?
Some methods I researched were filter, forEach, and findIndex but I wasn't able to successfully
implement them, so I focused on refactoring for readability and DRYness.

How can you access and manipulate properties of objects?
You can access properties of objects using dot or bracket notation and once you've accessed the object's
property you can update the value.  Using control flow techniques and functions you can manipulate
properties of objects based on the properties you accessed in your conditional statements and
change properties' values.
*/<commit_msg>Add changes based on feedback<commit_after>// Design Basic Game Solo Challenge

// This is a solo challenge

// Your mission description:
// Overall mission: Leprechaun collects 5 gold coins to have a full pot of gold
// Goals: collect gold coins, avoid trap
// Characters: leprechaun, gold coins, trap
// Objects: leprechaun(position, health, success, potOfGold, move), gold coins(name, position), trap(position)
// Functions: move for leprechaun, constructor function for coins, display coins

// Pseudocode
// CREATE a function to build a GoldCoin class that takes a name and creates random position coordinates
// SET 10 coin variables to new instances of the GoldCoin class
// SET a goldCoins variable equal to a list of the coins
// CREATE a function to display the coordinates for each coin
// SET a trap variable to random position coordinates
//
// SET a leprechaun variable to have a position of 0 for X & Y, potOfGold to 0, health to true,
// success false, and a move method
// CREATE a move method that takes a direction & number for the amount to move
//   UPDATE the leprechaun's coordinates based on the direction & number
//   DISPLAY the leprechaun's coordinates
//   IF the leprechaun's coordinates are equal to the trap's coordinates
//     UPDATE the leprechaun's health & display "Game Over"
//   ELSE IF the leprechaun's potOfGold is equal to 5
//     UPDATE the leprechaun's success & display "You Win"
//   ELSE iterate through the goldCoins list
//     IF the leprechaun's coordinates are equal to a coin's coordinates
//     DISPLAY "You found a coin"
//     INCREMENT the leprechaun's potOfGold by 1

// Initial Code
// function GoldCoin(coin) {
//   this.coin = coin;
//   this.posX = Math.floor(Math.random()*6 + 1),
//   this.posY = Math.floor(Math.random()*6 + 1)
// }

// var coin1 = new GoldCoin("Coin 1");
// var coin2 = new GoldCoin("Coin 2");
// var coin3 = new GoldCoin("Coin 3");
// var coin4 = new GoldCoin("Coin 4");
// var coin5 = new GoldCoin("Coin 5");
// var coin6 = new GoldCoin("Coin 6");
// var coin7 = new GoldCoin("Coin 7");
// var coin8 = new GoldCoin("Coin 8");
// var coin9 = new GoldCoin("Coin 9");
// var coin10 = new GoldCoin("Coin 10");

// var goldCoins = [ coin1, coin2, coin3, coin4, coin5, coin6, coin7, coin8, coin9, coin10];

// var displayCoins = function () {
//      for (var i = 0; i < goldCoins.length; i++) {
//       console.log(goldCoins[i].coin + "'s position is " + goldCoins[i].posX + "," + goldCoins[i].posY)
//     }
// }

// var trap = {
//   posX: Math.floor(Math.random()*6 + 1),
//   posY: Math.floor(Math.random()*6 + 1)
// };

// var leprechaun = {
//   posX: 0,
//   posY: 0,
//   potOfGold: 0,
//   health: true,
//   success: false,
//   move: function(direction, amount) {
//     if(direction === 'left'){
//       this.posX -= amount;
//     }
//     else if(direction === 'right'){
//       this.posX += amount;
//     }
//     else if(direction === 'up'){
//       this.posY -= amount;
//     }
//     else if(direction === 'down'){
//       this.posY += amount;
//     }

//     console.log("The leprechaun's position is " + this.posX + "," + this.posY);

//     if(this.posX === trap.posX && this.posY === trap.posY){
//       this.health = false;
//       return console.log("You're trapped and hurt. Game Over!");
//     }
//     else if(this.potOfGold === 5){
//       this.success = true;
//       return console.log("You're pot of gold is full, you win!!");
//     }
//     else {
//       for (var i = 0; i < goldCoins.length; i++) {
//         if (this.posX === goldCoins[i].posX && this.posY === goldCoins[i].posY) {
//           console.log("You found a gold coin!");
//           this.potOfGold += 1;
//         }
//       }
//     }

//   }

// };

// Refactored Code
function GoldCoin() {
  this.posX = Math.floor(Math.random()*6 + 1),
  this.posY = Math.floor(Math.random()*6 + 1)
}

var goldCoins = [];
var createCoins= function(num) {
  for (var i = 0; i < num; i++) {
    goldCoins.push(new GoldCoin());
  }
  return goldCoins
}

var displayCoins = function () {
     for (var i = 0; i < goldCoins.length; i++) {
      console.log("The coin's position is " + goldCoins[i].posX + "," + goldCoins[i].posY)
    }
}

function Trap() {
  this.posX = Math.floor(Math.random()*6 + 1),
  this.posY = Math.floor(Math.random()*6 + 1)
}
var traps = [];
var createTraps = function(num){
  for (var i = 0; i < num; i++) {
    traps.push(new Trap());
  }
  return traps
}

var leprechaun = {
  posX: 0,
  posY: 0,
  potOfGold: 0,
  health: 100,
  success: false,
  move: function(direction, amount) {
    switch(direction){
      case 'left': this.posX -= amount; break;
      case'right': this.posX += amount; break;
      case 'up': this.posY -= amount; break;
      case 'down': this.posY += amount; break;
    }

    console.log("The leprechaun's position is " + this.posX + "," + this.posY);
    if (this.health > 0) {
      for (var i = 0; i < traps.length; i++) {
        if(this.posX === traps[i].posX && this.posY === traps[i].posY){
          this.health -= 10;
        }
      }
    } else {
      console.log("Game Over!");
    }

    if(this.potOfGold === 5){
      this.success = true;
      console.log("You're pot of gold is full, you win!!");
    }

    for (var i = 0; i < goldCoins.length; i++) {
      if (this.posX === goldCoins[i].posX && this.posY === goldCoins[i].posY) {
        console.log("You found a gold coin!");
        this.potOfGold += 1;
      }
    }
  }

};

createCoins(10);
createTraps(5);
displayCoins();
leprechaun.move('down', 2);
leprechaun.move('right', 2);
leprechaun.move('right', 3);
leprechaun.move('left', 1);
leprechaun.move('down', 3);
leprechaun.move('left', 1);
leprechaun.move('left', 1);
leprechaun.move('up', 1);
leprechaun.move('up', 1);
leprechaun.move('right', 4);
displayCoins();
console.log(leprechaun.potOfGold);
console.log(leprechaun.success);
console.log(leprechaun.health);

// Reflection
/*
What was the most difficult part of this challenge?
Using the correct syntax and semantics was the most difficult part of this challenge.  When I would
test the code I would frequently receive the message 'SyntaxError: Unexpected token' or 'TypeError'.

What did you learn about creating objects and functions that interact with one another?
This challenge helped me to practice creating objects with functions as properties and using the
properties of other objects to update the value's in the object's properties.

Did you learn about any new built-in methods you could use in your refactored solution?
If so, what were they and how do they work?
Some methods I researched were filter, forEach, and findIndex but I wasn't able to successfully
implement them, so I focused on refactoring for readability and DRYness.

How can you access and manipulate properties of objects?
You can access properties of objects using dot or bracket notation and once you've accessed the object's
property you can update the value.  Using control flow techniques and functions you can manipulate
properties of objects based on the properties you accessed in your conditional statements and
change properties' values.
*/<|endoftext|>


<commit_before>/**********************************************************************
Game Rules

The rules of the game.

//********************************************************************/

const util = require('util');

///////////////////////////////////////////////////////////////////////

function GamePhase() {};

///////////////////////////////////////////////////////////////////////

function DrawPhase() {
    GamePhase.call(this);
};
util.inherits(DrawPhase, GamePhase);

///////////////////////////////////////////////////////////////////////

// jlu is working on this
function JudgePhase() {
    JudgePhase.call(this);
};
util.inherits(JudgePhase, GamePhase);

///////////////////////////////////////////////////////////////////////

function GameRules() {
    this.phases = [new DrawPhase(), new JudgePhase()];
};

GameRules.prototype = {};

module.exports.game_rules = GameRules;
<commit_msg>created empty prototype for Game phase<commit_after>/**********************************************************************
Game Rules

The rules of the game.

//********************************************************************/

const util = require('util');

///////////////////////////////////////////////////////////////////////

function GamePhase() {
};

GamePhase.prototype = {
    // todo
};

///////////////////////////////////////////////////////////////////////

function DrawPhase() {
    GamePhase.call(this);
};
util.inherits(DrawPhase, GamePhase);

///////////////////////////////////////////////////////////////////////

function JudgePhase() {
    JudgePhase.call(this);
};
util.inherits(JudgePhase, GamePhase);
JudgePhase.prototype = {
    // todo
};

///////////////////////////////////////////////////////////////////////

function GameRules() {
    this.phases = [new DrawPhase(), new JudgePhase()];
};

GameRules.prototype = {};

module.exports.game_rules = GameRules;
<|endoftext|>


<commit_before>import expenseStatus from '../constants/expense_status';
import { TransactionTypes } from '../constants/transactions';
import models, { Op, sequelize } from '../models';

import { getFxRate } from './currency';

const { CREDIT } = TransactionTypes;
const { PROCESSING, SCHEDULED_FOR_PAYMENT } = expenseStatus;

/* Versions of the balance algorithm:
 - v0: sum everything in the netAmountInCollectiveCurrency column then assume it's in Collective's currency - DELETED
 - v1: sum by currency based on netAmountInCollectiveCurrency then convert to Collective's currency using the Fx Rate of the day
 - v2: sum by currency based on amountInHostCurrency then convert to Collective's currency using the Fx Rate of the day
 - v3: sum by currency based on amountInHostCurrency, limit to entries with a HostCollectiveId, then convert Collective's currency using the Fx Rate of the day
*/

export async function getBalanceAmount(collective, { startDate, endDate, currency, version, loaders } = {}) {
  version = version || collective.settings?.budget?.version || 'v1';
  currency = currency || collective.currency;

  // Optimized version using loaders
  if (loaders && version === 'v1') {
    const result = await loaders.Collective.balance.load(collective.id);
    const fxRate = await getFxRate(result.currency, currency);
    return {
      value: Math.round(result.value * fxRate),
      currency,
    };
  }

  return sumCollectiveTransactions(collective, {
    startDate,
    endDate,
    currency,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    excludeRefunds: false,
    withBlockedFunds: false,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
  });
}

export async function getBalanceWithBlockedFundsAmount(
  collective,
  { startDate, endDate, currency, version, loaders } = {},
) {
  version = version || collective.settings?.budget?.version || 'v1';
  currency = currency || collective.currency;

  // Optimized version using loaders
  if (loaders && version === 'v1') {
    const result = await loaders.Collective.balanceWithBlockedFunds.load(collective.id);
    const fxRate = await getFxRate(result.currency, currency);
    return {
      value: Math.round(result.value * fxRate),
      currency,
    };
  }

  return sumCollectiveTransactions(collective, {
    startDate,
    endDate,
    currency: currency,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    excludeRefunds: false,
    withBlockedFunds: true,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
  });
}

export function getBalances(collectiveIds, { startDate, endDate, currency, version = 'v1' } = {}) {
  return sumCollectivesTransactions(collectiveIds, {
    startDate,
    endDate,
    currency,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    excludeRefunds: false,
    withBlockedFunds: false,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
  });
}

export function getBalancesWithBlockedFunds(collectiveIds, { startDate, endDate, currency, version = 'v1' } = {}) {
  return sumCollectivesTransactions(collectiveIds, {
    startDate,
    endDate,
    currency,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    excludeRefunds: false,
    withBlockedFunds: true,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
  });
}

export function getTotalAmountReceivedAmount(collective, { startDate, endDate, currency, version } = {}) {
  version = version || collective.settings?.budget?.version || 'v1';
  currency = currency || collective.currency;
  return sumCollectiveTransactions(collective, {
    startDate,
    endDate,
    currency,
    column: ['v0', 'v1'].includes(version) ? 'amountInCollectiveCurrency' : 'amountInHostCurrency',
    transactionType: CREDIT,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
    excludeInternals: true,
  });
}

export function getTotalNetAmountReceivedAmount(collective, { startDate, endDate, currency, version } = {}) {
  version = version || collective.settings?.budget?.version || 'v1';
  currency = currency || collective.currency;
  return sumCollectiveTransactions(collective, {
    startDate,
    endDate,
    currency,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    transactionType: CREDIT,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
    excludeInternals: true,
  });
}

export async function getTotalMoneyManagedAmount(host, { startDate, endDate, currency, version } = {}) {
  version = version || host.settings?.budget?.version || 'v1';
  currency = currency || host.currency;

  const hostedCollectives = await host.getHostedCollectives();
  const ids = hostedCollectives.map(c => c.id);
  if (host.isActive) {
    ids.push(host.id);
  }
  if (ids.length === 0) {
    return { value: 0, currency };
  }

  const results = await sumCollectivesTransactions(ids, {
    startDate,
    endDate,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    hostCollectiveId: host.id,
  });

  let total = 0;

  for (const result of Object.values(results)) {
    const fxRate = await getFxRate(result.currency, currency);
    total += Math.round(result.value * fxRate);
  }

  // Sum and convert to final currency
  return { value: total, currency };
}

async function sumCollectiveTransactions(collective, options) {
  const results = await sumCollectivesTransactions([collective.id], options);

  const result = results[collective.id];

  if (options.currency) {
    const fxRate = await getFxRate(result.currency, options.currency);
    result.value = Math.round(result.value * fxRate);
    result.currency = options.currency;
  }

  return result;
}

async function sumCollectivesTransactions(
  ids,
  {
    column,
    startDate = null,
    endDate = null,
    transactionType = null,
    excludeRefunds = true,
    withBlockedFunds = false,
    hostCollectiveId = null,
    excludeInternals = false,
  } = {},
) {
  const groupBy = ['amountInHostCurrency', 'netAmountInHostCurrency'].includes(column) ? 'hostCurrency' : 'currency';

  const where = {
    CollectiveId: ids,
  };
  if (transactionType) {
    where.type = transactionType;
  }
  if (startDate) {
    where.createdAt = where.createdAt || {};
    where.createdAt[Op.gte] = startDate;
  }
  if (endDate) {
    where.createdAt = where.createdAt || {};
    where.createdAt[Op.lt] = endDate;
  }
  if (excludeRefunds) {
    // Exclude refunded transactions
    where.RefundTransactionId = { [Op.is]: null };
  }
  if (hostCollectiveId) {
    // Only transactions that are marked under a Fiscal Host
    where.HostCollectiveId = hostCollectiveId;
  }
  if (excludeInternals) {
    // Exclude internal transactions (we can tag some Transactions like "Switching Host" as internal)
    where.data = { internal: { [Op.not]: true } };
  }

  const totals = {};

  // Initialize total
  for (const CollectiveId of ids) {
    totals[CollectiveId] = { CollectiveId, currency: 'USD', value: 0 };
  }

  const results = await models.Transaction.findAll({
    attributes: [
      'CollectiveId',
      groupBy,
      [sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('amount')), 0), 'amountInCollectiveCurrency'],
      [
        sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('netAmountInCollectiveCurrency')), 0),
        'netAmountInCollectiveCurrency',
      ],
      [sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('amountInHostCurrency')), 0), 'amountInHostCurrency'],
      [
        sequelize.fn(
          'COALESCE',
          sequelize.literal(
            'SUM(COALESCE("amountInHostCurrency", 0)) + SUM(COALESCE("platformFeeInHostCurrency", 0)) + SUM(COALESCE("hostFeeInHostCurrency", 0)) + SUM(COALESCE("paymentProcessorFeeInHostCurrency", 0)) + SUM(COALESCE("taxAmount" * "hostCurrencyFxRate", 0))',
          ),
          0,
        ),
        'netAmountInHostCurrency',
      ],
    ],
    where,
    group: ['CollectiveId', groupBy],
    raw: true,
  });

  for (const result of results) {
    const CollectiveId = result['CollectiveId'];
    const value = result[column];

    // If it's the first total collected, set the currency
    if (totals[CollectiveId].value === 0) {
      totals[CollectiveId].currency = result[groupBy];
    }

    const fxRate = await getFxRate(result[groupBy], totals[CollectiveId].currency);
    totals[CollectiveId].value += Math.round(value * fxRate);
  }

  if (withBlockedFunds) {
    const blockedFundsWhere = {
      CollectiveId: ids,
      [Op.or]: [{ status: SCHEDULED_FOR_PAYMENT }, { status: PROCESSING, 'data.payout_batch_id': { [Op.not]: null } }],
    };
    if (startDate) {
      blockedFundsWhere.createdAt = blockedFundsWhere.createdAt || {};
      blockedFundsWhere.createdAt[Op.gte] = startDate;
    }
    if (endDate) {
      blockedFundsWhere.createdAt = blockedFundsWhere.createdAt || {};
      blockedFundsWhere.createdAt[Op.lt] = endDate;
    }

    const blockedFundResults = await models.Expense.findAll({
      attributes: [
        'CollectiveId',
        'currency',
        [sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('amount')), 0), 'amount'],
      ],
      where: blockedFundsWhere,
      group: ['CollectiveId', 'currency'],
      raw: true,
    });

    for (const blockedFundResult of blockedFundResults) {
      const CollectiveId = blockedFundResult['CollectiveId'];
      const value = blockedFundResult['amount'];

      // If it's the first total collected, set the currency
      if (totals[CollectiveId].value === 0) {
        totals[CollectiveId].currency = blockedFundResult['currency'];
      }

      const fxRate = await getFxRate(blockedFundResult['currency'], totals[CollectiveId].currency);
      totals[CollectiveId].value -= Math.round(value * fxRate);
    }
  }

  return totals;
}

export async function getYearlyIncome(collective) {
  // Three cases:
  // 1) All active monthly subscriptions. Multiply by 12
  // 2) All one-time and yearly subscriptions
  // 3) All inactive monthly subscriptions that have contributed in the past

  // TODO: support netAmountInHostCurrency
  const result = await sequelize.query(
    `
      WITH "activeMonthlySubscriptions" as (
        SELECT DISTINCT d."SubscriptionId", t."netAmountInCollectiveCurrency"
        FROM "Transactions" t
        LEFT JOIN "Orders" d ON d.id = t."OrderId"
        LEFT JOIN "Subscriptions" s ON s.id = d."SubscriptionId"
        WHERE t."CollectiveId"=:CollectiveId
          AND t."RefundTransactionId" IS NULL
          AND s."isActive" IS TRUE
          AND s.interval = 'month'
          AND s."deletedAt" IS NULL
      )
      SELECT
        (SELECT
          COALESCE(SUM("netAmountInCollectiveCurrency"*12),0) FROM "activeMonthlySubscriptions")
        +
        (SELECT
          COALESCE(SUM(t."netAmountInCollectiveCurrency"),0) FROM "Transactions" t
          LEFT JOIN "Orders" d ON t."OrderId" = d.id
          LEFT JOIN "Subscriptions" s ON d."SubscriptionId" = s.id
          WHERE t."CollectiveId" = :CollectiveId
            AND t."RefundTransactionId" IS NULL
            AND CAST(("t"."data"#>>'{internal}') AS BOOLEAN) IS NOT true
            AND t.type = 'CREDIT'
            AND t."deletedAt" IS NULL
            AND t."createdAt" > (current_date - INTERVAL '12 months')
            AND ((s.interval = 'year' AND s."isActive" IS TRUE AND s."deletedAt" IS NULL) OR s.interval IS NULL))
        +
        (SELECT
          COALESCE(SUM(t."netAmountInCollectiveCurrency"),0) FROM "Transactions" t
          LEFT JOIN "Orders" d ON t."OrderId" = d.id
          LEFT JOIN "Subscriptions" s ON d."SubscriptionId" = s.id
          WHERE t."CollectiveId" = :CollectiveId
            AND t."RefundTransactionId" IS NULL
            AND t.type = 'CREDIT'
            AND t."deletedAt" IS NULL
            AND t."createdAt" > (current_date - INTERVAL '12 months')
            AND s.interval = 'month' AND s."isActive" IS FALSE AND s."deletedAt" IS NULL)
        "yearlyIncome"
      `.replace(/\s\s+/g, ' '), // this is to remove the new lines and save log space.
    {
      replacements: { CollectiveId: collective.id },
      type: sequelize.QueryTypes.SELECT,
    },
  );

  return parseInt(result[0].yearlyIncome, 10);
}
<commit_msg>fix(getYearlyIncome): Better grouping for subscriptions<commit_after>import expenseStatus from '../constants/expense_status';
import { TransactionTypes } from '../constants/transactions';
import models, { Op, sequelize } from '../models';

import { getFxRate } from './currency';

const { CREDIT } = TransactionTypes;
const { PROCESSING, SCHEDULED_FOR_PAYMENT } = expenseStatus;

/* Versions of the balance algorithm:
 - v0: sum everything in the netAmountInCollectiveCurrency column then assume it's in Collective's currency - DELETED
 - v1: sum by currency based on netAmountInCollectiveCurrency then convert to Collective's currency using the Fx Rate of the day
 - v2: sum by currency based on amountInHostCurrency then convert to Collective's currency using the Fx Rate of the day
 - v3: sum by currency based on amountInHostCurrency, limit to entries with a HostCollectiveId, then convert Collective's currency using the Fx Rate of the day
*/

export async function getBalanceAmount(collective, { startDate, endDate, currency, version, loaders } = {}) {
  version = version || collective.settings?.budget?.version || 'v1';
  currency = currency || collective.currency;

  // Optimized version using loaders
  if (loaders && version === 'v1') {
    const result = await loaders.Collective.balance.load(collective.id);
    const fxRate = await getFxRate(result.currency, currency);
    return {
      value: Math.round(result.value * fxRate),
      currency,
    };
  }

  return sumCollectiveTransactions(collective, {
    startDate,
    endDate,
    currency,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    excludeRefunds: false,
    withBlockedFunds: false,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
  });
}

export async function getBalanceWithBlockedFundsAmount(
  collective,
  { startDate, endDate, currency, version, loaders } = {},
) {
  version = version || collective.settings?.budget?.version || 'v1';
  currency = currency || collective.currency;

  // Optimized version using loaders
  if (loaders && version === 'v1') {
    const result = await loaders.Collective.balanceWithBlockedFunds.load(collective.id);
    const fxRate = await getFxRate(result.currency, currency);
    return {
      value: Math.round(result.value * fxRate),
      currency,
    };
  }

  return sumCollectiveTransactions(collective, {
    startDate,
    endDate,
    currency: currency,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    excludeRefunds: false,
    withBlockedFunds: true,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
  });
}

export function getBalances(collectiveIds, { startDate, endDate, currency, version = 'v1' } = {}) {
  return sumCollectivesTransactions(collectiveIds, {
    startDate,
    endDate,
    currency,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    excludeRefunds: false,
    withBlockedFunds: false,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
  });
}

export function getBalancesWithBlockedFunds(collectiveIds, { startDate, endDate, currency, version = 'v1' } = {}) {
  return sumCollectivesTransactions(collectiveIds, {
    startDate,
    endDate,
    currency,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    excludeRefunds: false,
    withBlockedFunds: true,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
  });
}

export function getTotalAmountReceivedAmount(collective, { startDate, endDate, currency, version } = {}) {
  version = version || collective.settings?.budget?.version || 'v1';
  currency = currency || collective.currency;
  return sumCollectiveTransactions(collective, {
    startDate,
    endDate,
    currency,
    column: ['v0', 'v1'].includes(version) ? 'amountInCollectiveCurrency' : 'amountInHostCurrency',
    transactionType: CREDIT,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
    excludeInternals: true,
  });
}

export function getTotalNetAmountReceivedAmount(collective, { startDate, endDate, currency, version } = {}) {
  version = version || collective.settings?.budget?.version || 'v1';
  currency = currency || collective.currency;
  return sumCollectiveTransactions(collective, {
    startDate,
    endDate,
    currency,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    transactionType: CREDIT,
    hostCollectiveId: version === 'v3' ? { [Op.not]: null } : null,
    excludeInternals: true,
  });
}

export async function getTotalMoneyManagedAmount(host, { startDate, endDate, currency, version } = {}) {
  version = version || host.settings?.budget?.version || 'v1';
  currency = currency || host.currency;

  const hostedCollectives = await host.getHostedCollectives();
  const ids = hostedCollectives.map(c => c.id);
  if (host.isActive) {
    ids.push(host.id);
  }
  if (ids.length === 0) {
    return { value: 0, currency };
  }

  const results = await sumCollectivesTransactions(ids, {
    startDate,
    endDate,
    column: ['v0', 'v1'].includes(version) ? 'netAmountInCollectiveCurrency' : 'netAmountInHostCurrency',
    hostCollectiveId: host.id,
  });

  let total = 0;

  for (const result of Object.values(results)) {
    const fxRate = await getFxRate(result.currency, currency);
    total += Math.round(result.value * fxRate);
  }

  // Sum and convert to final currency
  return { value: total, currency };
}

async function sumCollectiveTransactions(collective, options) {
  const results = await sumCollectivesTransactions([collective.id], options);

  const result = results[collective.id];

  if (options.currency) {
    const fxRate = await getFxRate(result.currency, options.currency);
    result.value = Math.round(result.value * fxRate);
    result.currency = options.currency;
  }

  return result;
}

async function sumCollectivesTransactions(
  ids,
  {
    column,
    startDate = null,
    endDate = null,
    transactionType = null,
    excludeRefunds = true,
    withBlockedFunds = false,
    hostCollectiveId = null,
    excludeInternals = false,
  } = {},
) {
  const groupBy = ['amountInHostCurrency', 'netAmountInHostCurrency'].includes(column) ? 'hostCurrency' : 'currency';

  const where = {
    CollectiveId: ids,
  };
  if (transactionType) {
    where.type = transactionType;
  }
  if (startDate) {
    where.createdAt = where.createdAt || {};
    where.createdAt[Op.gte] = startDate;
  }
  if (endDate) {
    where.createdAt = where.createdAt || {};
    where.createdAt[Op.lt] = endDate;
  }
  if (excludeRefunds) {
    // Exclude refunded transactions
    where.RefundTransactionId = { [Op.is]: null };
  }
  if (hostCollectiveId) {
    // Only transactions that are marked under a Fiscal Host
    where.HostCollectiveId = hostCollectiveId;
  }
  if (excludeInternals) {
    // Exclude internal transactions (we can tag some Transactions like "Switching Host" as internal)
    where.data = { internal: { [Op.not]: true } };
  }

  const totals = {};

  // Initialize total
  for (const CollectiveId of ids) {
    totals[CollectiveId] = { CollectiveId, currency: 'USD', value: 0 };
  }

  const results = await models.Transaction.findAll({
    attributes: [
      'CollectiveId',
      groupBy,
      [sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('amount')), 0), 'amountInCollectiveCurrency'],
      [
        sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('netAmountInCollectiveCurrency')), 0),
        'netAmountInCollectiveCurrency',
      ],
      [sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('amountInHostCurrency')), 0), 'amountInHostCurrency'],
      [
        sequelize.fn(
          'COALESCE',
          sequelize.literal(
            'SUM(COALESCE("amountInHostCurrency", 0)) + SUM(COALESCE("platformFeeInHostCurrency", 0)) + SUM(COALESCE("hostFeeInHostCurrency", 0)) + SUM(COALESCE("paymentProcessorFeeInHostCurrency", 0)) + SUM(COALESCE("taxAmount" * "hostCurrencyFxRate", 0))',
          ),
          0,
        ),
        'netAmountInHostCurrency',
      ],
    ],
    where,
    group: ['CollectiveId', groupBy],
    raw: true,
  });

  for (const result of results) {
    const CollectiveId = result['CollectiveId'];
    const value = result[column];

    // If it's the first total collected, set the currency
    if (totals[CollectiveId].value === 0) {
      totals[CollectiveId].currency = result[groupBy];
    }

    const fxRate = await getFxRate(result[groupBy], totals[CollectiveId].currency);
    totals[CollectiveId].value += Math.round(value * fxRate);
  }

  if (withBlockedFunds) {
    const blockedFundsWhere = {
      CollectiveId: ids,
      [Op.or]: [{ status: SCHEDULED_FOR_PAYMENT }, { status: PROCESSING, 'data.payout_batch_id': { [Op.not]: null } }],
    };
    if (startDate) {
      blockedFundsWhere.createdAt = blockedFundsWhere.createdAt || {};
      blockedFundsWhere.createdAt[Op.gte] = startDate;
    }
    if (endDate) {
      blockedFundsWhere.createdAt = blockedFundsWhere.createdAt || {};
      blockedFundsWhere.createdAt[Op.lt] = endDate;
    }

    const blockedFundResults = await models.Expense.findAll({
      attributes: [
        'CollectiveId',
        'currency',
        [sequelize.fn('COALESCE', sequelize.fn('SUM', sequelize.col('amount')), 0), 'amount'],
      ],
      where: blockedFundsWhere,
      group: ['CollectiveId', 'currency'],
      raw: true,
    });

    for (const blockedFundResult of blockedFundResults) {
      const CollectiveId = blockedFundResult['CollectiveId'];
      const value = blockedFundResult['amount'];

      // If it's the first total collected, set the currency
      if (totals[CollectiveId].value === 0) {
        totals[CollectiveId].currency = blockedFundResult['currency'];
      }

      const fxRate = await getFxRate(blockedFundResult['currency'], totals[CollectiveId].currency);
      totals[CollectiveId].value -= Math.round(value * fxRate);
    }
  }

  return totals;
}

export async function getYearlyIncome(collective) {
  // Three cases:
  // 1) All active monthly subscriptions. Multiply by 12
  // 2) All one-time and yearly subscriptions
  // 3) All inactive monthly subscriptions that have contributed in the past

  // TODO: support netAmountInHostCurrency
  const result = await sequelize.query(
    `
      WITH "activeMonthlySubscriptions" as (
        SELECT d."SubscriptionId", ROUND(AVG(t."netAmountInCollectiveCurrency")) AS "netAmountInCollectiveCurrency"
        FROM "Transactions" t
        LEFT JOIN "Orders" d ON d.id = t."OrderId"
        LEFT JOIN "Subscriptions" s ON s.id = d."SubscriptionId"
        WHERE t."CollectiveId"=:CollectiveId
          AND t."RefundTransactionId" IS NULL
          AND s."isActive" IS TRUE
          AND s.interval = 'month'
          AND s."deletedAt" IS NULL
        GROUP BY d."SubscriptionId"
      )
      SELECT
        (SELECT
          COALESCE(SUM("netAmountInCollectiveCurrency"*12),0) FROM "activeMonthlySubscriptions")
        +
        (SELECT
          COALESCE(SUM(t."netAmountInCollectiveCurrency"),0) FROM "Transactions" t
          LEFT JOIN "Orders" d ON t."OrderId" = d.id
          LEFT JOIN "Subscriptions" s ON d."SubscriptionId" = s.id
          WHERE t."CollectiveId" = :CollectiveId
            AND t."RefundTransactionId" IS NULL
            AND CAST(("t"."data"#>>'{internal}') AS BOOLEAN) IS NOT true
            AND t.type = 'CREDIT'
            AND t."deletedAt" IS NULL
            AND t."createdAt" > (current_date - INTERVAL '12 months')
            AND ((s.interval = 'year' AND s."isActive" IS TRUE AND s."deletedAt" IS NULL) OR s.interval IS NULL))
        +
        (SELECT
          COALESCE(SUM(t."netAmountInCollectiveCurrency"),0) FROM "Transactions" t
          LEFT JOIN "Orders" d ON t."OrderId" = d.id
          LEFT JOIN "Subscriptions" s ON d."SubscriptionId" = s.id
          WHERE t."CollectiveId" = :CollectiveId
            AND t."RefundTransactionId" IS NULL
            AND t.type = 'CREDIT'
            AND t."deletedAt" IS NULL
            AND t."createdAt" > (current_date - INTERVAL '12 months')
            AND s.interval = 'month' AND s."isActive" IS FALSE AND s."deletedAt" IS NULL)
        "yearlyIncome"
      `.replace(/\s\s+/g, ' '), // this is to remove the new lines and save log space.
    {
      replacements: { CollectiveId: collective.id },
      type: sequelize.QueryTypes.SELECT,
    },
  );

  return parseInt(result[0].yearlyIncome, 10);
}
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var render = require('./render');
var User = require('./user');
var rank = require('./elo');

/**
 * Render index html page.
 */

exports.index = function *() {
  return this.body = yield render('index');
};

/**
 * List users.
 */

exports.list = function *() {
  return this.body = yield User.find({});
};

/**
 * Create user
 */

exports.create = function *() {
  var load = this.request.body;
  return this.body = yield User.create(load.player);
};

/**
 * Delete user
 */

exports.remove = function *(name) {
  return this.body = yield User.remove({ name: name });
};

/**
 * Submit results.
 */

exports.results = function *() {
  var load = this.request.body;
  return this.body = yield rank(load.winner, load.loser);
};
<commit_msg>updated server/lib/routes.js<commit_after>
/**
 * Module dependencies.
 */

var tools = require('./tools');

/**
 * Render index html page.
 */

exports.index = function *() {
  return this.body = yield tools.get();
};
<|endoftext|>


<commit_before>(function() {
	// Variables globales
	var ToDos = []; // Aqui tendremos un array de objectos. Cada objecto será una tarea.
	var storage = localStorage; // Tecnología que utilizaremos para guardar los datos.
	var prefix = "ToDo";

	// Capturamos los elementos que necesitamos
	var newTodoInput = document.getElementById("todoInput");
	var addTodoBtn = document.getElementById("addBtn");
	var todoList = document.getElementById("todoList");

	// Funciones
	var getToDos = function() {
		if (storage.length > 0) {
			for(var i = 0; i < storage.length; i++) {
				if (storage.key(i) === prefix) {
					ToDos = JSON.parse(storage.getItem(storage.key(i)));
				}
			}
			//success(); // Callback. Si hay tareas guardadas en local mostrarlas.
			showToDoList();
		}
	};
	var showToDoList = function() {
		if (ToDos.length > 0) {
			for (var i = 0; i < ToDos.length; i++) {
				addToDoToList(ToDos[i].text, ToDos[i].isDone)
			};
		}
	};
	var addTodo = function(e) {
		e.preventDefault();
		if (newTodoInput.value.trim() !== '') {
			addToDoToList(newTodoInput.value.trim(), false);
			saveTodo(newTodoInput.value.trim());
			newTodoInput.value = ""; // Limpiamos el input para nuevas tareas
		}
	};
	var addToDoToList = function(text, isDone) {
		// Creamos un checkbox, que servirá para marcar que la tarea esta completada.
		var newCheckbox = document.createElement("input");
		newCheckbox.type = "checkbox";
		newCheckbox.classList.add("delete");

		// Creamos un span para meter en él la descripción de la tarea.
		var newTodoText = document.createElement("span");
		newTodoText.innerText = text;

		// Creamos un botón para eliminar la tarea
		var newDeleteBtn = document.createElement("button");
		newDeleteBtn.classList.add("deleteBtn");
		newDeleteBtn.innerText = "-";

		// Comprobamos si la tarea esta hecha o no
		if (isDone) {
			newTodoText.classList.add("todoDone") // Aparecerá tachada
			newCheckbox.checked = true; // El checkbox aparecera 'checked'
		}

		// Creamos un nuevo elemento (li) para la lista e insertamos en él los elementos de arriba.
		var newTodo = document.createElement("li");
		newTodo.appendChild(newCheckbox);
		newTodo.appendChild(newTodoText);
		newTodo.appendChild(newDeleteBtn);

		// Insertamos en el UL el nuevo elemento LI que hemos creado.
		todoList.appendChild(newTodo);
	};
	var saveTodo = function(text) {
		var ToDo = {
			text : text,
			isDone : false
		};
		ToDos.push(ToDo); // Update de array of ToDos
		updateLocalToDos(); // Actualizar el array guardado localmente
	};
	var updateLocalToDos = function() {
		storage.setItem(prefix, JSON.stringify(ToDos));
	};
	var deleteTodo = function(e) {
		if (e.target.type === "submit") {
			var li = e.target.parentNode;
			var span = e.target.parentNode.getElementsByTagName("span");
			var text = span[0].innerText;
			var posicion;
			for (var i = 0; i < ToDos.length; i++) {
				if (ToDos[i].text === text) {
					posicion = i;
					i = ToDos.length;
				}
			}
			if (posicion >= 0) {
				todoList.removeChild(li); // Eliminar el li
				ToDos.splice(posicion, 1); // Eliminar el objeto del array
				updateLocalToDos(); // Actualizar el array guardado localmente
			}
		}
	};
	var toggleDoneUndone = function(e) {
		if (e.target.type === "checkbox") {
			var span = e.target.parentNode.getElementsByTagName("span");
			var text = span[0].innerText;
			var posicion;
			if (e.target.checked) {
				span[0].classList.add("todoDone");
				findToDoPosition(text, updateToDoStatus({"status": 1}))

				for (var i = 0; i < ToDos.length; i++) {
					if (ToDos[i].text === text) {
						posicion = i;
						i = ToDos.length;
					}
				}
				if (posicion >= 0) {
					ToDos[posicion].isDone = true;
					updateLocalToDos();
				}
			} else {
				span[0].classList.remove("todoDone");
				for (var i = 0; i < ToDos.length; i++) {
					if (ToDos[i].text === text) {
						posicion = i;
						i = ToDos.length;
					}
				}
				if (posicion >= 0) {
					ToDos[posicion].isDone = false;
					updateLocalToDos();
				}
			}
		}
	};
	var findToDoPosition = function(text, success) {
		var position;
		for (var i = 0; i < ToDos.length; i++) {
			if (ToDos[i].text === text) {
				position = i;
				i = ToDos.length;
			}
		}
		if (position >= 0) {
			success({"position": position});
		}
	};
	var updateToDoStatus = function(data) {
		console.log("El elemento esta en " + data.position + " y su estado es " + data.status);
	};

	// Listeners
	window.addEventListener("load", getToDos, false);
	addTodoBtn.addEventListener("click", addTodo, false);
	todoList.addEventListener("click", deleteTodo, false);
	todoList.addEventListener("click", toggleDoneUndone, false);
})();<commit_msg>Actualización<commit_after>(function() {
	// Variables globales
	var ToDos = []; // Aqui tendremos un array de objectos. Cada objecto será una tarea.
	var storage = localStorage; // Tecnología que utilizaremos para guardar los datos.
	var prefix = "ToDo";

	// Capturamos los elementos que necesitamos
	var newTodoInput = document.getElementById("todoInput");
	var addTodoBtn = document.getElementById("addBtn");
	var todoList = document.getElementById("todoList");

	// Funciones
	var getToDos = function() {
		if (storage.length > 0) {
			for(var i = 0; i < storage.length; i++) {
				if (storage.key(i) === prefix) {
					ToDos = JSON.parse(storage.getItem(storage.key(i)));
				}
			}
			//success(); // Callback. Si hay tareas guardadas en local mostrarlas.
			showToDoList();
		}
	};
	var showToDoList = function() {
		if (ToDos.length > 0) {
			for (var i = 0; i < ToDos.length; i++) {
				addToDoToList(ToDos[i].text, ToDos[i].isDone);
			}
		}
	};
	var addTodo = function(e) {
		e.preventDefault();
		if (newTodoInput.value.trim() !== '') {
			addToDoToList(newTodoInput.value.trim(), false);
			saveTodo(newTodoInput.value.trim());
			newTodoInput.value = ""; // Limpiamos el input para nuevas tareas
		}
	};
	var addToDoToList = function(text, isDone) {
		// Creamos un checkbox, que servirá para marcar que la tarea esta completada.
		var newCheckbox = document.createElement("input");
		newCheckbox.type = "checkbox";
		newCheckbox.classList.add("delete");

		// Creamos un span para meter en él la descripción de la tarea.
		var newTodoText = document.createElement("span");
		newTodoText.innerText = text;

		// Creamos un botón para eliminar la tarea
		var newDeleteBtn = document.createElement("button");
		newDeleteBtn.classList.add("deleteBtn");
		newDeleteBtn.innerText = "-";

		// Comprobamos si la tarea esta hecha o no
		if (isDone) {
			newTodoText.classList.add("todoDone"); // Aparecerá tachada
			newCheckbox.checked = true; // El checkbox aparecera 'checked'
		}

		// Creamos un nuevo elemento (li) para la lista e insertamos en él los elementos de arriba.
		var newTodo = document.createElement("li");
		newTodo.appendChild(newCheckbox);
		newTodo.appendChild(newTodoText);
		newTodo.appendChild(newDeleteBtn);

		// Insertamos en el UL el nuevo elemento LI que hemos creado.
		todoList.appendChild(newTodo);
	};
	var saveTodo = function(text) {
		var ToDo = {
			text : text,
			isDone : false
		};
		ToDos.push(ToDo); // Update de array of ToDos
		updateLocalToDos(); // Actualizar el array guardado localmente
	};
	var updateLocalToDos = function() {
		storage.setItem(prefix, JSON.stringify(ToDos));
	};
	var deleteTodo = function(e) {
		if (e.target.type === "submit") {
			var li = e.target.parentNode;
			var span = e.target.parentNode.getElementsByTagName("span");
			var text = span[0].innerText;
			var posicion;
			for (var i = 0; i < ToDos.length; i++) {
				if (ToDos[i].text === text) {
					posicion = i;
					i = ToDos.length;
				}
			}
			if (posicion >= 0) {
				todoList.removeChild(li); // Eliminar el li
				ToDos.splice(posicion, 1); // Eliminar el objeto del array
				updateLocalToDos(); // Actualizar el array guardado localmente
			}
		}
	};
	var toggleDoneUndone = function(e) {
		if (e.target.type === "checkbox") {
			var span = e.target.parentNode.getElementsByTagName("span");
			var text = span[0].innerText;
			var posicion;
			if (e.target.checked) {
				span[0].classList.add("todoDone");
				findToDoPosition(text, updateToDoStatus({"status": 1}));

				for (var i = 0; i < ToDos.length; i++) {
					if (ToDos[i].text === text) {
						posicion = i;
						i = ToDos.length;
					}
				}
				if (posicion >= 0) {
					ToDos[posicion].isDone = true;
					updateLocalToDos();
				}
			} else {
				span[0].classList.remove("todoDone");
				for (var i = 0; i < ToDos.length; i++) {
					if (ToDos[i].text === text) {
						posicion = i;
						i = ToDos.length;
					}
				}
				if (posicion >= 0) {
					ToDos[posicion].isDone = false;
					updateLocalToDos();
				}
			}
		}
	};
	var findToDoPosition = function(text, success) {
		var position;
		for (var i = 0; i < ToDos.length; i++) {
			if (ToDos[i].text === text) {
				position = i;
				i = ToDos.length;
			}
		}
		if (position >= 0) {
			success({"position": position});
		}
	};
	var updateToDoStatus = function(data) {
		console.log("El elemento esta en " + data.position + " y su estado es " + data.status);
	};

	// Listeners
	window.addEventListener("load", getToDos, false);
	addTodoBtn.addEventListener("click", addTodo, false);
	todoList.addEventListener("click", deleteTodo, false);
	todoList.addEventListener("click", toggleDoneUndone, false);

	// Dataset
	// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset
})();<|endoftext|>


<commit_before><commit_msg>Update SuperOrangeMovement.js<commit_after><|endoftext|>


<commit_before>'use strict';

angular.module('emuwebApp')
	.service('Appcachehandler', function Appcachehandler($http, modalService) {
		// shared service object
		var sServObj = {};

		var appCache = window.applicationCache;

		// var cacheProperties = {
		// 	filesDownloaded: 0,
		// 	totalFiles: 0
		// };

		// function getTotalFiles() {
		// 	// First, reset the total file count and download count.
		// 	cacheProperties.filesDownloaded = 0;
		// 	cacheProperties.totalFiles = 0;

		// 	$http.get('manifest.appcache').success(function (content) {
		// 		// console.log(content);
		// 		content = content.replace(
		// 			new RegExp(
		// 				'(NETWORK|FALLBACK):' +
		// 				'((?!(NETWORK|FALLBACK|CACHE):)[\\w\\W]*)',
		// 				'gi'
		// 			),
		// 			''
		// 		);

		// 		// Strip out all comments.
		// 		content = content.replace(
		// 			new RegExp('#[^\\r\\n]*(\\r\\n?|\\n)', 'g'),
		// 			''
		// 		);

		// 		// Strip out the cache manifest header and
		// 		// trailing slashes.
		// 		content = content.replace(
		// 			new RegExp('CACHE MANIFEST\\s*|\\s*$', 'g'),
		// 			''
		// 		);

		// 		// Strip out extra line breaks and replace with
		// 		// a hash sign that we can break on.
		// 		content = content.replace(
		// 			new RegExp('[\\r\\n]+', 'g'),
		// 			'#'
		// 		);

		// 		// Get the total number of files.
		// 		var totalFiles = content.split('#').length;

		// 		// Store the total number of files. Here, we are
		// 		// adding one for *THIS* file, which is cached
		// 		// implicitly as it points to the manifest.
		// 		cacheProperties.totalFiles = (totalFiles + 1);
		// 		// console.log('##########################');
		// 		// alert('INFO: appcache update of: ' + cacheProperties.totalFiles + ' files');
		// 	});

		// }

		// function handleCheckingEvent(e) {
		// 	console.log('###### handleCheckingEvent ##########');
		// 	console.log(e);
		// }

		// function handleNoupdateEvent(e) {
		// 	console.log('###### handleNoupdateEvent ##########');
		// 	console.log(e);
		// }

		// function handleDownloadingEvent(e) {
		// 	console.log('######## handleDownloadingEvent ##########');
		// 	console.log(e);
		// 	getTotalFiles();
		// }

		// function handleProgressEvent(e) {
		// 	console.log('###### handleProgressEvent ##########');
		// 	console.log(e);
		// }

		/**
		 *
		 */
		// function handleCachedEvent(e) {
		// 	console.log('###### handleCachedEvent ##########');
		// 	console.log(e);
		// }

		/**
		 *
		 */
		sServObj.handleUpdatereadyEvent = function () {
			modalService.open('views/confirmModal.html', 'A new version of the EMU-WebApp is available and has already been downloaded and cached in your browser. Would you like to use it? CAUTION: A reload will delete all current changes... TIP: the next time you use the EMU-webApp you will automatically use the updated version)').then(function (res) {
				if (res) {
					appCache.swapCache();
					window.location.reload();
				}
			});
		};

		// function handleObsoleteEvent(e) {
		// 	console.log('###### handleObsoleteEvent ##########');
		// 	console.log(e);
		// }

		// function handleErrorEvent(e) {
		// 	console.log('###### handleErrorEvent ##########');
		// 	console.log(e);
		// }

		// // bind evts
		// // appCache.addEventListener('progress', handleProgressEvent, false);

		// appCache.addEventListener('checking', handleCheckingEvent, false);
		// appCache.addEventListener('noupdate', handleNoupdateEvent, false);
		// appCache.addEventListener('downloading', handleDownloadingEvent, false);
		// appCache.addEventListener('progress', handleProgressEvent, false);
		// appCache.addEventListener('cached', handleCachedEvent, false);
		appCache.addEventListener('updateready', sServObj.handleUpdatereadyEvent, false);
		// appCache.addEventListener('obsolete', handleObsoleteEvent, false);
		// appCache.addEventListener('error', handleErrorEvent, false);

		// /////////////////////////////////////////////////
		// // public api

		sServObj.checkForNewVersion = function () {
			// console.log('check for new version');
			if((appCache.status !== 0 && appCache.status !== 3)){ // uncached == 0 & downloading == 3
				console.log('INFO: appCache.status: '+ appCache.status);
				appCache.update();
			}
		};

		return sServObj;
	});<commit_msg>remove localStorage haveShownWelcomeModal entry on new<commit_after>'use strict';

angular.module('emuwebApp')
	.service('Appcachehandler', function Appcachehandler($http, modalService) {
		// shared service object
		var sServObj = {};

		var appCache = window.applicationCache;

		// var cacheProperties = {
		// 	filesDownloaded: 0,
		// 	totalFiles: 0
		// };

		// function getTotalFiles() {
		// 	// First, reset the total file count and download count.
		// 	cacheProperties.filesDownloaded = 0;
		// 	cacheProperties.totalFiles = 0;

		// 	$http.get('manifest.appcache').success(function (content) {
		// 		// console.log(content);
		// 		content = content.replace(
		// 			new RegExp(
		// 				'(NETWORK|FALLBACK):' +
		// 				'((?!(NETWORK|FALLBACK|CACHE):)[\\w\\W]*)',
		// 				'gi'
		// 			),
		// 			''
		// 		);

		// 		// Strip out all comments.
		// 		content = content.replace(
		// 			new RegExp('#[^\\r\\n]*(\\r\\n?|\\n)', 'g'),
		// 			''
		// 		);

		// 		// Strip out the cache manifest header and
		// 		// trailing slashes.
		// 		content = content.replace(
		// 			new RegExp('CACHE MANIFEST\\s*|\\s*$', 'g'),
		// 			''
		// 		);

		// 		// Strip out extra line breaks and replace with
		// 		// a hash sign that we can break on.
		// 		content = content.replace(
		// 			new RegExp('[\\r\\n]+', 'g'),
		// 			'#'
		// 		);

		// 		// Get the total number of files.
		// 		var totalFiles = content.split('#').length;

		// 		// Store the total number of files. Here, we are
		// 		// adding one for *THIS* file, which is cached
		// 		// implicitly as it points to the manifest.
		// 		cacheProperties.totalFiles = (totalFiles + 1);
		// 		// console.log('##########################');
		// 		// alert('INFO: appcache update of: ' + cacheProperties.totalFiles + ' files');
		// 	});

		// }

		// function handleCheckingEvent(e) {
		// 	console.log('###### handleCheckingEvent ##########');
		// 	console.log(e);
		// }

		// function handleNoupdateEvent(e) {
		// 	console.log('###### handleNoupdateEvent ##########');
		// 	console.log(e);
		// }

		// function handleDownloadingEvent(e) {
		// 	console.log('######## handleDownloadingEvent ##########');
		// 	console.log(e);
		// 	getTotalFiles();
		// }

		// function handleProgressEvent(e) {
		// 	console.log('###### handleProgressEvent ##########');
		// 	console.log(e);
		// }

		/**
		 *
		 */
		// function handleCachedEvent(e) {
		// 	console.log('###### handleCachedEvent ##########');
		// 	console.log(e);
		// }

		/**
		 *
		 */
		sServObj.handleUpdatereadyEvent = function () {
			modalService.open('views/confirmModal.html', 'A new version of the EMU-WebApp is available and has already been downloaded and cached in your browser. Would you like to use it? CAUTION: A reload will delete all current changes... TIP: the next time you use the EMU-webApp you will automatically use the updated version)').then(function (res) {
				if (res) {
					localStorage.removeItem("haveShownWelcomeModal");
					appCache.swapCache();
					window.location.reload();
				}else{
					localStorage.removeItem("haveShownWelcomeModal");
				}
			});
		};

		// function handleObsoleteEvent(e) {
		// 	console.log('###### handleObsoleteEvent ##########');
		// 	console.log(e);
		// }

		// function handleErrorEvent(e) {
		// 	console.log('###### handleErrorEvent ##########');
		// 	console.log(e);
		// }

		// // bind evts
		// // appCache.addEventListener('progress', handleProgressEvent, false);

		// appCache.addEventListener('checking', handleCheckingEvent, false);
		// appCache.addEventListener('noupdate', handleNoupdateEvent, false);
		// appCache.addEventListener('downloading', handleDownloadingEvent, false);
		// appCache.addEventListener('progress', handleProgressEvent, false);
		// appCache.addEventListener('cached', handleCachedEvent, false);
		appCache.addEventListener('updateready', sServObj.handleUpdatereadyEvent, false);
		// appCache.addEventListener('obsolete', handleObsoleteEvent, false);
		// appCache.addEventListener('error', handleErrorEvent, false);

		// /////////////////////////////////////////////////
		// // public api

		sServObj.checkForNewVersion = function () {
			// console.log('check for new version');
			if((appCache.status !== 0 && appCache.status !== 3)){ // uncached == 0 & downloading == 3
				console.log('INFO: appCache.status: '+ appCache.status);
				appCache.update();
			}
		};

		return sServObj;
	});<|endoftext|>


<commit_before>var db = require("../db")

var JobSchema = new db.Schema({
    'type': String,
    'company': String,
    'position': String,
    'deadline': Date,
    'status': String
    // required: true,
});

  module.exports = db.model('Job', JobSchema);
<commit_msg>change<commit_after>var db = require("../db")

var JobSchema = new db.Schema({
<<<<<<< 93d59c03d456086ab372e17aa3fe23c4330d7ed0
    'type': String,
    'company': String,
    'position': String,
    'deadline': Date,
    'status': String
    // required: true,
});

  module.exports = db.model('Job', JobSchema);
<|endoftext|>