<commit_before>import * as utils from '~/utils'

const PERM_SETCHANNEL = 'setChannel'
const PERM_SETLOBBY = 'setLobby'
const PERM_SETVOICE = 'setVoice'
const PERM_DELETECHANNEL = 'deleteChannel'
const PERM_CHANNELS = 'channels'

const TEAM_NAMES = {
  team1: 'Team 1',
  team2: 'Team 2'
}
const TEAM_NAMES_LIST = Object.keys(TEAM_NAMES).map(x => '`' + x + '`').join(', ')

const commands = (api) => ({

  setChannel(bot, message, args) {
    const { author } = message

    api.permissions.checkPermission(message, PERM_SETCHANNEL).or(PERM_CHANNELS)
      .then((granted) => {
        if (granted) {
          const query = { guildId: message.guild.id, setting: 'commandChannels' }

          api.db.collection('guilds').update(query, { $addToSet: { values: message.channel.id } }, { upsert: true }, (err, numAffected) => {
            if (err) {
              console.log('setChannel DB ERROR', err)

              message.channel.send('An error occured while trying to set the command channel')

              return
            }

            message.channel.send('Command channel successfully set', undefined, (err, confirmationMsg) => {
              if (err) {
                console.log('setChannel FAILED TO SEND SUCCESS MESSAGE')
                return
              }
            })
          })
        } else {
          message.channel.send('You don\'t have permission to set the command channel')
        }
      })
  },

  deleteChannel(bot, message, args) {
    const { author } = message

    api.permissions.checkPermission(message, PERM_DELETECHANNEL).or(PERM_CHANNELS)
      .then((granted) => {
        if (granted) {
          const query = { guildId: message.guild.id, setting: 'commandChannels' }

          api.db.collection('guilds').update(query, { $pull: { values: message.channel.id } })
            .then((e) => {
              if (e.result.nModified === 0) {
                message.channel.send('This text channel is not a registered command channel')
                return false
              }
              else {
                const query = { guildId: message.guild.id, cmdChannelId: message.channel.id, setting: 'voiceChannel' }
                return api.db.collection('guilds').deleteMany(query)
              }
            })
            .catch((err) => {
              console.log('deleteChannel DB ERROR 1', err)
              message.channel.send('An error occured while trying to delete the command channel')
            })
            .then((e) => {
              if (!e) {
                return
              }
              message.channel.send('Command channel successfully deleted')
            })
            .catch((err) => {
              console.log('deleteChannel DB ERROR 2', err)
              message.channel.send('An error occured while trying to delete the associated voice channels')
            })
        } else {
          message.channel.send('You don\'t have permission to remove command channels')
        }
      })
  },

  setLobby(bot, message, args) {
    const { author } = message

    api.permissions.checkPermission(message, PERM_SETLOBBY).or(PERM_CHANNELS)
      .then((granted) => {
        if (granted) {
          const voiceChannel = utils.getUserVoiceChannel(bot, message.guild, message.author)

          const cmdChannelQuery = { guildId: message.guild.id, setting: 'commandChannels', values: { $all: [message.channel.id] } }

          api.db.collection('guilds').findOne(cmdChannelQuery, (err, doc) => {

            if (err) {
              console.log('setLobby DB ERROR 1', err)
              return
            }

            if (doc == null) {
              message.channel.send('This text channel is not a registered command channel')
              return
            }

            if (voiceChannel == null) {
              message.channel.send('You must be connected to a voice channel to set the lobby voice channel')
              return
            }

            const lobbyChannelQuery = { guildId: message.guild.id, cmdChannelId: message.channel.id, setting: 'lobbyChannel' }

            api.db.collection('guilds').update(lobbyChannelQuery, { $set: { value: voiceChannel.id } }, { upsert: true }, (err, numAffected) => {
              if (err) {
                console.log('setLobby DB ERROR 2', err)

                message.channel.send('An error occured while trying to set the lobby voice channel')

                return
              }

              message.channel.send('Lobby voice channel successfully set', undefined, (err) => {
                if (err) {
                  console.log('setLobby FAILED TO SEND SUCCESS MESSAGE')
                  return
                }
              })
            })

          })
        } else {
          message.channel.send('You don\'t have permission to set the lobby channel')
        }
      })
  },

  setVoice(bot, message, args) {
    const { author } = message

    api.permissions.checkPermission(message, PERM_SETVOICE).or(PERM_CHANNELS)
      .then((granted) => {
        if (granted) {
          const voiceChannel = utils.getUserVoiceChannel(bot, message.guild, message.author)

          const cmdChannelQuery = { guildId: message.guild.id, setting: 'commandChannels', values: { $all: [message.channel.id] } }

          api.db.collection('guilds').findOne(cmdChannelQuery, (err, doc) => {

            if (err) {
              console.log('setLobby DB ERROR 1', err)
              return
            }

            if (doc == null) {
              message.channel.send('This text channel is not a registered command channel')
              return
            }

            if (args.length === 0) {
              message.channel.send('You must specify the name of the team you want to set the voice channel for. Possible values: ' + TEAM_NAMES_LIST)
              return
            }

            const team = args[0]
            if (TEAM_NAMES[team] == null) {
              message.channel.send('The specified team name is invalid. Possible values: ' + TEAM_NAMES_LIST)
              return
            }

            if (voiceChannel == null) {
              message.channel.send('You must be connected to a voice channel to set the voice channel for ' + TEAM_NAMES[team])
              return
            }

            const voiceChannelQuery = { guildId: message.guild.id, cmdChannelId: message.channel.id, setting: 'voiceChannel', teamName: team }

            api.db.collection('guilds').update(voiceChannelQuery, { $set: { value: voiceChannel.id } }, { upsert: true }, (err, numAffected) => {
              if (err) {
                console.log('setVoice DB ERROR 2', err)

                message.channel.send('An error occured while trying to set the lobby voice channel')

                return
              }

              message.channel.send('Team voice channel successfully set for ' + TEAM_NAMES[team], undefined, (err) => {
                if (err) {
                  console.log('setVoice FAILED TO SEND SUCCESS MESSAGE')
                  return
                }
              })
            })

          })
        } else {
          message.channel.send('You don\'t have permission to set the lobby channel')
        }
      })
  }

})

export default function load(api) {
  const { registerCommand: register, permissions } = api
  const cmds = commands(api)

  permissions.registerPermission(PERM_SETCHANNEL, 'Allows using the !setchannel command')
  permissions.registerPermission(PERM_SETLOBBY, 'Allows using the !setlobby command')
  permissions.registerPermission(PERM_SETVOICE, 'Allows using the !setvoice command')
  permissions.registerPermission(PERM_CHANNELS, 'Allows using all the commands related to channel configuration')

  register('setchannel', 'Sets the channel to use to control and administrate the 6v6 lobby', cmds.setChannel)
  register('setlobby', 'Sets the current voice channel as the lobby for regrouping players before and after games', cmds.setLobby)
  register('setvoice', 'Sets the current voice channel as the voice channel for a specified team', cmds.setVoice)
  register('deletechannel', 'Unregisters the channel as a 6v6 lobby command channel', cmds.deleteChannel)
}
<commit_msg>Register PERM_DELETECHANNEL permission<commit_after>import * as utils from '~/utils'

const PERM_SETCHANNEL = 'setChannel'
const PERM_SETLOBBY = 'setLobby'
const PERM_SETVOICE = 'setVoice'
const PERM_DELETECHANNEL = 'deleteChannel'
const PERM_CHANNELS = 'channels'

const TEAM_NAMES = {
  team1: 'Team 1',
  team2: 'Team 2'
}
const TEAM_NAMES_LIST = Object.keys(TEAM_NAMES).map(x => '`' + x + '`').join(', ')

const commands = (api) => ({

  setChannel(bot, message, args) {
    const { author } = message

    api.permissions.checkPermission(message, PERM_SETCHANNEL).or(PERM_CHANNELS)
      .then((granted) => {
        if (granted) {
          const query = { guildId: message.guild.id, setting: 'commandChannels' }

          api.db.collection('guilds').update(query, { $addToSet: { values: message.channel.id } }, { upsert: true }, (err, numAffected) => {
            if (err) {
              console.log('setChannel DB ERROR', err)

              message.channel.send('An error occured while trying to set the command channel')

              return
            }

            message.channel.send('Command channel successfully set', undefined, (err, confirmationMsg) => {
              if (err) {
                console.log('setChannel FAILED TO SEND SUCCESS MESSAGE')
                return
              }
            })
          })
        } else {
          message.channel.send('You don\'t have permission to set the command channel')
        }
      })
  },

  deleteChannel(bot, message, args) {
    const { author } = message

    api.permissions.checkPermission(message, PERM_DELETECHANNEL).or(PERM_CHANNELS)
      .then((granted) => {
        if (granted) {
          const query = { guildId: message.guild.id, setting: 'commandChannels' }

          api.db.collection('guilds').update(query, { $pull: { values: message.channel.id } })
            .then((e) => {
              if (e.result.nModified === 0) {
                message.channel.send('This text channel is not a registered command channel')
                return false
              }
              else {
                const query = { guildId: message.guild.id, cmdChannelId: message.channel.id, setting: 'voiceChannel' }
                return api.db.collection('guilds').deleteMany(query)
              }
            })
            .catch((err) => {
              console.log('deleteChannel DB ERROR 1', err)
              message.channel.send('An error occured while trying to delete the command channel')
            })
            .then((e) => {
              if (!e) {
                return
              }
              message.channel.send('Command channel successfully deleted')
            })
            .catch((err) => {
              console.log('deleteChannel DB ERROR 2', err)
              message.channel.send('An error occured while trying to delete the associated voice channels')
            })
        } else {
          message.channel.send('You don\'t have permission to remove command channels')
        }
      })
  },

  setLobby(bot, message, args) {
    const { author } = message

    api.permissions.checkPermission(message, PERM_SETLOBBY).or(PERM_CHANNELS)
      .then((granted) => {
        if (granted) {
          const voiceChannel = utils.getUserVoiceChannel(bot, message.guild, message.author)

          const cmdChannelQuery = { guildId: message.guild.id, setting: 'commandChannels', values: { $all: [message.channel.id] } }

          api.db.collection('guilds').findOne(cmdChannelQuery, (err, doc) => {

            if (err) {
              console.log('setLobby DB ERROR 1', err)
              return
            }

            if (doc == null) {
              message.channel.send('This text channel is not a registered command channel')
              return
            }

            if (voiceChannel == null) {
              message.channel.send('You must be connected to a voice channel to set the lobby voice channel')
              return
            }

            const lobbyChannelQuery = { guildId: message.guild.id, cmdChannelId: message.channel.id, setting: 'lobbyChannel' }

            api.db.collection('guilds').update(lobbyChannelQuery, { $set: { value: voiceChannel.id } }, { upsert: true }, (err, numAffected) => {
              if (err) {
                console.log('setLobby DB ERROR 2', err)

                message.channel.send('An error occured while trying to set the lobby voice channel')

                return
              }

              message.channel.send('Lobby voice channel successfully set', undefined, (err) => {
                if (err) {
                  console.log('setLobby FAILED TO SEND SUCCESS MESSAGE')
                  return
                }
              })
            })

          })
        } else {
          message.channel.send('You don\'t have permission to set the lobby channel')
        }
      })
  },

  setVoice(bot, message, args) {
    const { author } = message

    api.permissions.checkPermission(message, PERM_SETVOICE).or(PERM_CHANNELS)
      .then((granted) => {
        if (granted) {
          const voiceChannel = utils.getUserVoiceChannel(bot, message.guild, message.author)

          const cmdChannelQuery = { guildId: message.guild.id, setting: 'commandChannels', values: { $all: [message.channel.id] } }

          api.db.collection('guilds').findOne(cmdChannelQuery, (err, doc) => {

            if (err) {
              console.log('setLobby DB ERROR 1', err)
              return
            }

            if (doc == null) {
              message.channel.send('This text channel is not a registered command channel')
              return
            }

            if (args.length === 0) {
              message.channel.send('You must specify the name of the team you want to set the voice channel for. Possible values: ' + TEAM_NAMES_LIST)
              return
            }

            const team = args[0]
            if (TEAM_NAMES[team] == null) {
              message.channel.send('The specified team name is invalid. Possible values: ' + TEAM_NAMES_LIST)
              return
            }

            if (voiceChannel == null) {
              message.channel.send('You must be connected to a voice channel to set the voice channel for ' + TEAM_NAMES[team])
              return
            }

            const voiceChannelQuery = { guildId: message.guild.id, cmdChannelId: message.channel.id, setting: 'voiceChannel', teamName: team }

            api.db.collection('guilds').update(voiceChannelQuery, { $set: { value: voiceChannel.id } }, { upsert: true }, (err, numAffected) => {
              if (err) {
                console.log('setVoice DB ERROR 2', err)

                message.channel.send('An error occured while trying to set the lobby voice channel')

                return
              }

              message.channel.send('Team voice channel successfully set for ' + TEAM_NAMES[team], undefined, (err) => {
                if (err) {
                  console.log('setVoice FAILED TO SEND SUCCESS MESSAGE')
                  return
                }
              })
            })

          })
        } else {
          message.channel.send('You don\'t have permission to set the lobby channel')
        }
      })
  }

})

export default function load(api) {
  const { registerCommand: register, permissions } = api
  const cmds = commands(api)

  permissions.registerPermission(PERM_SETCHANNEL, 'Allows using the !setchannel command')
  permissions.registerPermission(PERM_SETLOBBY, 'Allows using the !setlobby command')
  permissions.registerPermission(PERM_SETVOICE, 'Allows using the !setvoice command')
  permissions.registerPermission(PERM_DELETECHANNEL, 'Allows using the !deletechannel command')
  permissions.registerPermission(PERM_CHANNELS, 'Allows using all the commands related to channel configuration')

  register('setchannel', 'Sets the channel to use to control and administrate the 6v6 lobby', cmds.setChannel)
  register('setlobby', 'Sets the current voice channel as the lobby for regrouping players before and after games', cmds.setLobby)
  register('setvoice', 'Sets the current voice channel as the voice channel for a specified team', cmds.setVoice)
  register('deletechannel', 'Unregisters the channel as a 6v6 lobby command channel', cmds.deleteChannel)
}
<|endoftext|>


<commit_before>ig.module(
    'game.entities.player'
)
.requires(
    'impact.entity',
    'game.entities.projectiles.demonfang',
    'game.entities.projectiles.lightning',
    'game.entities.projectiles.fiercedemonfang'
)
.defines(function(){
    EntityPlayer = ig.Entity.extend({
        /* Collision Properties
         * type: What group does the player belong to?
         *  TYPE.A: Friendly
         *  TYPE.B: Enemy
         * checkAgainst: What entities do we check against?
         * collides: What happens if we collide with an entity?
        */
        type: ig.Entity.TYPE.A,
        checkAgainst: ig.Entity.TYPE.NONE,
        collides: ig.Entity.COLLIDES.ACTIVE,

        name: 'Kratos',

        /* Setup player properties */
        animSheet: new ig.AnimationSheet('media/kratos-d.png', 140, 100), // Animation sheet
        size: {x: 40, y: 50}, // Size of collision bounding box
        flip: true, // Set flip property to true
        accelGround: 200, // How fast we accelerate for movement on the ground
        accelAir: 310, // How fast we accelerate in the air
        jump: 360, // How high can we jump?
        friction: {x: 500, y: 0}, // Resistance against movement
        maxVel: {x: 100, y: 160}, // Cap our maximum velocity from acceleration
        attacking: false, // Boolean to control when we can attack
        startPosition: null, // Our starting position in the game world, used for respawning
        offset: {x: 50, y: 30},
        running: false,

        /* Player stats */
        // Just temporary for now
        stats : {
            str: 10,
            mag: 5,
            def: 9,
            spd: 10,
            totalExp: 0,
            nextExp: 10,
            level: 1,
            hp: 150,
            tp: 100,
            maxHP: 150,
            maxTP: 100,
        },

        skillPoints: 10, // How many skill points we have to allocate
        health: 150, // Override base health value
        tp: 100, // Technical Points

        init: function(x, y, settings){
            this.parent(x, y, settings);
            /* Set up player animations */

            /* this.addAnim(name, speed, frames)
             * name: string
             *  - the identifier for this animation
             * speed: number
             *  - how fast to iterate through frame cycle
             * frames: array
             *  - array of what frames to animate
            */

            this.addAnim('idle', 1, [1]);
            this.addAnim('walk', 0.10, [14, 15, 16, 17, 18, 19, 20]);
            this.addAnim('run', 0.10, [28, 29, 30, 31, 32, 33]);
            this.addAnim('jump', 1, [6]);
            this.addAnim('fall', 0.4, [5]);

            this.atkTimer = new ig.Timer(1.5);
            this.startPosition = {x:x, y:y};
            this.parent(x, y, settings);
        },

        update: function(){
            // Set up movement cases
            var accel = this.standing ? this.accelGround : this.accelAir;
            if(ig.input.state('left') && !ig.game.menuVisible){
                this.accel.x = -accel;
                this.flip = false;
                /*
                 *  Lightning blade framework
                 *  -------------------------
                 * Pressing left/right in combination with 'a' will trigger
                 * the lightning blade attack.
                 *
                 * Implementation
                 * --------------
                 * 1. Put timer on attack. This is to:
                 *      - Prevent spamming of arte (cooldown)
                 *      - Allow animations to finish
                 *      - Lock player into specific animation
                 * 2. If player has not attacked (!this.attacking):
                 *      - Initiate attack. Reset timer.
                 * 3. Until timer expires, we set attacking = true, preventing
                 *    additional triggers of Lightning Blade.
                 * 4. Once the timer expires, we reset the attacking boolean flag.
                 *
                 * TODO
                 * ----
                 * 1. Setup animation frames for Lightning blade
                */
                // Trigger Lightning blade facing left
                if(ig.input.state('attack') && !this.attacking){
                    this.atkTimer.reset();
                     ig.game.spawnEntity(EntityDemonFang, this.pos.x - 20, this.pos.y + 7, {flip: !this.flip});
                     this.tp -= 5;
                    // ig.game.spawnEntity(EntityFierceDemonFang, this.pos.x - 30, this.pos.y + 4, {flip: !this.flip});
                    console.log('Lightning blade');
                    if(this.atkTimer.delta() < 0){
                        this.attacking = true;
                    }
                }
            } else if(ig.input.state('right') && !ig.game.menuVisible){
                this.accel.x = accel;
                this.flip = true;
                // Trigger lightning blade facing right
                if(ig.input.state('attack') && !this.attacking){
                    this.atkTimer.reset();
                    ig.game.spawnEntity(EntityDemonFang, this.pos.x + 20, this.pos.y + 7, {flip: !this.flip});
                    // ig.game.spawnEntity(EntityFierceDemonFang, this.pos.x + 20, this.pos.y + 4, {flip: !this.flip});
                    console.log('Lightning blade');
                    if(this.atkTimer.delta() < 0){
                        this.attacking = true;
                    }
                }
            } else if(ig.input.state('down') && !ig.game.menuVisible){
                if(ig.input.state('attack') && !this.attacking){
                    this.atkTimer.reset();
                    console.log('Casting Spell');
                    ig.game.spawnEntity(EntityLightning, this.pos.x + 40, this.pos.y - 40, {flip: !this.flip});
                    ig.game.spawnEntity(EntityLightning, this.pos.x + 30, this.pos.y - 40, {flip: !this.flip});
                    ig.game.spawnEntity(EntityLightning, this.pos.x + 20, this.pos.y - 40, {flip: !this.flip});
                    if(this.atkTimer.delta() < 0){
                        this.attacking = true;
                    }
                }

             } else if(ig.input.state('up') && !ig.game.menuVisible){
                // Stop the player
                this.accel.x = 0;
                if(ig.input.state('attack') && !this.attacking){
                    this.atkTimer.reset();
                    console.log('Hell Pyre');
                    if(this.atkTimer.delta() < 0){
                        this.attacking = true;
                    }
                }

             } else {
                // If we aren't moving in any direction, we must
                // be standing still. Therefore, accel = 0
                this.accel.x = 0;
            }

            // Used to reset attack timer after time has elasped.
            // Once the timer has expired, we can attack again
            if(this.atkTimer.delta() > 0){
                this.attacking = false;
            }

            // If the player is using an arte, stop them in place
            // The player will be stopped based on this.atkTimer
            // NOTE: this is also useful for spell casting cooldowns
            if(this.attacking){
                // Stop the player
                this.accel.x = 0;
            }

            // Jumping logic: CASE 1
            if(this.standing && ig.input.state('jump') && !ig.game.menuVisible) {
                if(this.vel.y == 0) {
                    this.vel.y = -this.jump;
                    this.falling = false;
                }
            }

            // Jumping logic: CASE 2
            else if(!this.standing && !ig.input.state('jump') && !this.falling && !ig.game.menuVisible){
                this.vel.y = Math.floor(this.vel.y/3);
                this.falling = true;
            }

            // Flip the player based on left/right movement
            this.currentAnim.flip.x = this.flip;

            this.parent();

            // Animate player based on velocity
            // This may be refactored later

            // CASE 1: Y-velocity is negative and we aren't standing...
            //         therefore we are jumping.
            if(this.vel.y < 0 && !this.standing)
                this.currentAnim = this.anims.jump;
            // CASE 2: Y-velocity is positive and we aren't standing...
            //         Y-velocity is only positive when falling
            else if(this.vel.y > 0 && !this.standing)
                this.currentAnim = this.anims.fall;
            // CASE 3: X-velocity is not zero, we must be moving
            else if(this.vel.x > 0 && this.vel.x < 100 || this.vel.x < 0 && this.vel.x > -100) {
                this.currentAnim = this.anims.walk;
            }
            else if(this.vel.x >= 100 || this.vel.x <= -100) {
                this.currentAnim = this.anims.run;
            }
            // CASE 4: We are not moving, play idle animation
            else if (this.vel.y === 0 && this.vel.x == 0) {
                this.currentAnim = this.anims.idle;

            }
            console.log(this.vel.x)
            //console.log(this.currentAnim === this.anims.walk && this.currentAnim.frame === 6);

        },

        // This method is called on player's death
        kill: function() {
            this.parent();
            ig.game.respawnPlayerAtLastCheckpoint(this.pos.x, this.pos.y);
        },

        // On a player's death, this method checks # of lives and displays the proper screen
        // If lives > 0, respawn the player, else show game over screen
        onDeath: function() {
            ig.game.lives --;
            if(ig.game.lives < 0)
                ig.game.gameOver();
        },

    });
});
<commit_msg>Adding jumping and falling animation<commit_after>ig.module(
    'game.entities.player'
)
.requires(
    'impact.entity',
    'game.entities.projectiles.demonfang',
    'game.entities.projectiles.lightning',
    'game.entities.projectiles.fiercedemonfang'
)
.defines(function(){
    EntityPlayer = ig.Entity.extend({
        /* Collision Properties
         * type: What group does the player belong to?
         *  TYPE.A: Friendly
         *  TYPE.B: Enemy
         * checkAgainst: What entities do we check against?
         * collides: What happens if we collide with an entity?
        */
        type: ig.Entity.TYPE.A,
        checkAgainst: ig.Entity.TYPE.NONE,
        collides: ig.Entity.COLLIDES.ACTIVE,

        name: 'Kratos',

        /* Setup player properties */
        animSheet: new ig.AnimationSheet('media/kratos-d.png', 140, 100), // Animation sheet
        size: {x: 40, y: 50}, // Size of collision bounding box
        flip: true, // Set flip property to true
        accelGround: 200, // How fast we accelerate for movement on the ground
        accelAir: 310, // How fast we accelerate in the air
        jump: 360, // How high can we jump?
        friction: {x: 500, y: 0}, // Resistance against movement
        maxVel: {x: 100, y: 160}, // Cap our maximum velocity from acceleration
        attacking: false, // Boolean to control when we can attack
        startPosition: null, // Our starting position in the game world, used for respawning
        offset: {x: 50, y: 30},
        running: false,

        /* Player stats */
        // Just temporary for now
        stats : {
            str: 10,
            mag: 5,
            def: 9,
            spd: 10,
            totalExp: 0,
            nextExp: 10,
            level: 1,
            hp: 150,
            tp: 100,
            maxHP: 150,
            maxTP: 100,
        },

        skillPoints: 10, // How many skill points we have to allocate
        health: 150, // Override base health value
        tp: 100, // Technical Points

        init: function(x, y, settings){
            this.parent(x, y, settings);
            /* Set up player animations */

            /* this.addAnim(name, speed, frames)
             * name: string
             *  - the identifier for this animation
             * speed: number
             *  - how fast to iterate through frame cycle
             * frames: array
             *  - array of what frames to animate
            */

            this.addAnim('idle', 1, [1]);
            this.addAnim('walk', 0.10, [14, 15, 16, 17, 18, 19, 20]);
            this.addAnim('run', 0.10, [28, 29, 30, 31, 32, 33]);
            this.addAnim('jump', 0.10, [48]);
            this.addAnim('fall', 0.10, [48]);

            this.atkTimer = new ig.Timer(1.5);
            this.startPosition = {x:x, y:y};
            this.parent(x, y, settings);
        },

        update: function(){
            // Set up movement cases
            var accel = this.standing ? this.accelGround : this.accelAir;
            if(ig.input.state('left') && !ig.game.menuVisible){
                this.accel.x = -accel;
                this.flip = false;
                /*
                 *  Lightning blade framework
                 *  -------------------------
                 * Pressing left/right in combination with 'a' will trigger
                 * the lightning blade attack.
                 *
                 * Implementation
                 * --------------
                 * 1. Put timer on attack. This is to:
                 *      - Prevent spamming of arte (cooldown)
                 *      - Allow animations to finish
                 *      - Lock player into specific animation
                 * 2. If player has not attacked (!this.attacking):
                 *      - Initiate attack. Reset timer.
                 * 3. Until timer expires, we set attacking = true, preventing
                 *    additional triggers of Lightning Blade.
                 * 4. Once the timer expires, we reset the attacking boolean flag.
                 *
                 * TODO
                 * ----
                 * 1. Setup animation frames for Lightning blade
                */
                // Trigger Lightning blade facing left
                if(ig.input.state('attack') && !this.attacking){
                    this.atkTimer.reset();
                     ig.game.spawnEntity(EntityDemonFang, this.pos.x - 20, this.pos.y + 7, {flip: !this.flip});
                     this.tp -= 5;
                    // ig.game.spawnEntity(EntityFierceDemonFang, this.pos.x - 30, this.pos.y + 4, {flip: !this.flip});
                    console.log('Lightning blade');
                    if(this.atkTimer.delta() < 0){
                        this.attacking = true;
                    }
                }
            } else if(ig.input.state('right') && !ig.game.menuVisible){
                this.accel.x = accel;
                this.flip = true;
                // Trigger lightning blade facing right
                if(ig.input.state('attack') && !this.attacking){
                    this.atkTimer.reset();
                    ig.game.spawnEntity(EntityDemonFang, this.pos.x + 20, this.pos.y + 7, {flip: !this.flip});
                    // ig.game.spawnEntity(EntityFierceDemonFang, this.pos.x + 20, this.pos.y + 4, {flip: !this.flip});
                    console.log('Lightning blade');
                    if(this.atkTimer.delta() < 0){
                        this.attacking = true;
                    }
                }
            } else if(ig.input.state('down') && !ig.game.menuVisible){
                if(ig.input.state('attack') && !this.attacking){
                    this.atkTimer.reset();
                    console.log('Casting Spell');
                    ig.game.spawnEntity(EntityLightning, this.pos.x + 40, this.pos.y - 40, {flip: !this.flip});
                    ig.game.spawnEntity(EntityLightning, this.pos.x + 30, this.pos.y - 40, {flip: !this.flip});
                    ig.game.spawnEntity(EntityLightning, this.pos.x + 20, this.pos.y - 40, {flip: !this.flip});
                    if(this.atkTimer.delta() < 0){
                        this.attacking = true;
                    }
                }

             } else if(ig.input.state('up') && !ig.game.menuVisible){
                // Stop the player
                this.accel.x = 0;
                if(ig.input.state('attack') && !this.attacking){
                    this.atkTimer.reset();
                    console.log('Hell Pyre');
                    if(this.atkTimer.delta() < 0){
                        this.attacking = true;
                    }
                }

             } else {
                // If we aren't moving in any direction, we must
                // be standing still. Therefore, accel = 0
                this.accel.x = 0;
            }

            // Used to reset attack timer after time has elasped.
            // Once the timer has expired, we can attack again
            if(this.atkTimer.delta() > 0){
                this.attacking = false;
            }

            // If the player is using an arte, stop them in place
            // The player will be stopped based on this.atkTimer
            // NOTE: this is also useful for spell casting cooldowns
            if(this.attacking){
                // Stop the player
                this.accel.x = 0;
            }

            // Jumping logic: CASE 1
            if(this.standing && ig.input.state('jump') && !ig.game.menuVisible) {
                if(this.vel.y == 0) {
                    this.vel.y = -this.jump;
                    this.falling = false;
                }
            }

            // Jumping logic: CASE 2
            else if(!this.standing && !ig.input.state('jump') && !this.falling && !ig.game.menuVisible){
                this.vel.y = Math.floor(this.vel.y/3);
                this.falling = true;
            }

            // Flip the player based on left/right movement
            this.currentAnim.flip.x = this.flip;

            this.parent();

            // Animate player based on velocity
            // This may be refactored later

            // CASE 1: Y-velocity is negative and we aren't standing...
            //         therefore we are jumping.
            if(this.vel.y < 0 && !this.standing)
                this.currentAnim = this.anims.jump;
            // CASE 2: Y-velocity is positive and we aren't standing...
            //         Y-velocity is only positive when falling
            else if(this.vel.y > 0 && !this.standing)
                this.currentAnim = this.anims.fall;
            // CASE 3: X-velocity is not zero, we must be moving
            else if(this.vel.x > 0 && this.vel.x < 100 || this.vel.x < 0 && this.vel.x > -100) {
                this.currentAnim = this.anims.walk;
            }
            else if(this.vel.x >= 100 || this.vel.x <= -100) {
                this.currentAnim = this.anims.run;
            }
            // CASE 4: We are not moving, play idle animation
            else if (this.vel.y === 0 && this.vel.x == 0) {
                this.currentAnim = this.anims.idle;

            }
            console.log(this.vel.x)
            //console.log(this.currentAnim === this.anims.walk && this.currentAnim.frame === 6);

        },

        // This method is called on player's death
        kill: function() {
            this.parent();
            ig.game.respawnPlayerAtLastCheckpoint(this.pos.x, this.pos.y);
        },

        // On a player's death, this method checks # of lives and displays the proper screen
        // If lives > 0, respawn the player, else show game over screen
        onDeath: function() {
            ig.game.lives --;
            if(ig.game.lives < 0)
                ig.game.gameOver();
        },

    });
});
<|endoftext|>


<commit_before>var util = require("util");
var path = require("path");
var Q = require("q");
var _ = require("lodash");
var exec = require('child_process').exec;

var fs = require("../fs");
var parse = require("../../parse");
var BaseGenerator = require("../page");

/*
 *  This generator inherits from the single page generator
 *  and convert the page output to ebook
 */
var Generator = function() {
    BaseGenerator.apply(this, arguments);

    // Options for eBook generation
    this.options = _.defaults(this.options, {
        extension: "epub"
    });
};
util.inherits(Generator, BaseGenerator);

Generator.prototype.finish = function() {
    var that = this;

    return BaseGenerator.prototype.finish.apply(this)
    .then(function() {
        var d = Q.defer();

        var command = [
            "ebook-convert",
            path.join(that.options.output, "index.html"),
            path.join(that.options.output, "index."+that.options.extension)
        ].join(" ");

        exec(command, function (error, stdout, stderr) {
            if (error) {
                if (error.code == 127) {
                    error.message = "Need to install ebook-convert from Calibre";
                } else {
                    error.message = error.message + " "+stdout;
                }
                return d.reject(error);
            }
            d.resolve();
        });

        return d.promise;
    });
};

module.exports = Generator;
<commit_msg>Add option cover for ebook generation<commit_after>var util = require("util");
var path = require("path");
var Q = require("q");
var _ = require("lodash");
var exec = require('child_process').exec;

var fs = require("fs");
var parse = require("../../parse");
var BaseGenerator = require("../page");

/*
 *  This generator inherits from the single page generator
 *  and convert the page output to ebook
 */
var Generator = function() {
    BaseGenerator.apply(this, arguments);

    // Options for eBook generation
    this.options = _.defaults(this.options, {
        extension: "epub"
    });

    if (!this.options.cover && fs.existsSync(path.join(this.options.input, "cover.png"))) {
        this.options.cover = path.join(this.options.input, "cover.png")
    }
};
util.inherits(Generator, BaseGenerator);

Generator.prototype.finish = function() {
    var that = this;

    return BaseGenerator.prototype.finish.apply(this)
    .then(function() {
        var d = Q.defer();

        var _options = {
            "--cover": that.options.cover
        };

        var command = [
            "ebook-convert",
            path.join(that.options.output, "index.html"),
            path.join(that.options.output, "index."+that.options.extension),
            _.chain(_options)
            .map(function(value, key) {
                if (value == null) return null;
                return key+"="+value;
            })
            .compact()
            .value()
            .join(" ")
        ].join(" ");

        exec(command, function (error, stdout, stderr) {
            if (error) {
                if (error.code == 127) {
                    error.message = "Need to install ebook-convert from Calibre";
                } else {
                    error.message = error.message + " "+stdout;
                }
                return d.reject(error);
            }
            d.resolve();
        });

        return d.promise;
    });
};

module.exports = Generator;
<|endoftext|>


<commit_before>'use strict';

var core = require('mongodb-core');
var crypto = require('crypto');
var stream = require('stream');
var util = require('util');
var Buffer = require('safe-buffer').Buffer;

var ERROR_NAMESPACE_NOT_FOUND = 26;

module.exports = GridFSBucketWriteStream;

/**
 * A writable stream that enables you to write buffers to GridFS.
 *
 * Do not instantiate this class directly. Use `openUploadStream()` instead.
 *
 * @class
 * @param {GridFSBucket} bucket Handle for this stream's corresponding bucket
 * @param {string} filename The value of the 'filename' key in the files doc
 * @param {object} [options] Optional settings.
 * @param {string|number|object} [options.id] Custom file id for the GridFS file.
 * @param {number} [options.chunkSizeBytes] The chunk size to use, in bytes
 * @param {number} [options.w] The write concern
 * @param {number} [options.wtimeout] The write concern timeout
 * @param {number} [options.j] The journal write concern
 * @param {boolean} [options.disableMD5=false] If true, disables adding an md5 field to file data
 * @fires GridFSBucketWriteStream#error
 * @fires GridFSBucketWriteStream#finish
 * @return {GridFSBucketWriteStream} a GridFSBucketWriteStream instance.
 */

function GridFSBucketWriteStream(bucket, filename, options) {
  options = options || {};
  this.bucket = bucket;
  this.chunks = bucket.s._chunksCollection;
  this.filename = filename;
  this.files = bucket.s._filesCollection;
  this.options = options;
  // Signals the write is all done
  this.done = false;

  this.id = options.id ? options.id : core.BSON.ObjectId();
  this.chunkSizeBytes = this.options.chunkSizeBytes;
  this.bufToStore = Buffer.alloc(this.chunkSizeBytes);
  this.length = 0;
  this.md5 = !options.disableMD5 && crypto.createHash('md5');
  this.n = 0;
  this.pos = 0;
  this.state = {
    streamEnd: false,
    outstandingRequests: 0,
    errored: false,
    aborted: false,
    promiseLibrary: this.bucket.s.promiseLibrary
  };

  if (!this.bucket.s.calledOpenUploadStream) {
    this.bucket.s.calledOpenUploadStream = true;

    var _this = this;
    checkIndexes(this, function() {
      _this.bucket.s.checkedIndexes = true;
      _this.bucket.emit('index');
    });
  }
}

util.inherits(GridFSBucketWriteStream, stream.Writable);

/**
 * An error occurred
 *
 * @event GridFSBucketWriteStream#error
 * @type {Error}
 */

/**
 * `end()` was called and the write stream successfully wrote the file
 * metadata and all the chunks to MongoDB.
 *
 * @event GridFSBucketWriteStream#finish
 * @type {object}
 */

/**
 * Write a buffer to the stream.
 *
 * @method
 * @param {Buffer} chunk Buffer to write
 * @param {String} encoding Optional encoding for the buffer
 * @param {Function} callback Function to call when the chunk was added to the buffer, or if the entire chunk was persisted to MongoDB if this chunk caused a flush.
 * @return {Boolean} False if this write required flushing a chunk to MongoDB. True otherwise.
 */

GridFSBucketWriteStream.prototype.write = function(chunk, encoding, callback) {
  var _this = this;
  return waitForIndexes(this, function() {
    return doWrite(_this, chunk, encoding, callback);
  });
};

/**
 * Places this write stream into an aborted state (all future writes fail)
 * and deletes all chunks that have already been written.
 *
 * @method
 * @param {GridFSBucket~errorCallback} callback called when chunks are successfully removed or error occurred
 * @return {Promise} if no callback specified
 */

GridFSBucketWriteStream.prototype.abort = function(callback) {
  if (this.state.streamEnd) {
    var error = new Error('Cannot abort a stream that has already completed');
    if (typeof callback === 'function') {
      return callback(error);
    }
    return this.state.promiseLibrary.reject(error);
  }
  if (this.state.aborted) {
    error = new Error('Cannot call abort() on a stream twice');
    if (typeof callback === 'function') {
      return callback(error);
    }
    return this.state.promiseLibrary.reject(error);
  }
  this.state.aborted = true;
  this.chunks.deleteMany({ files_id: this.id }, function(error) {
    if (typeof callback === 'function') callback(error);
  });
};

/**
 * Tells the stream that no more data will be coming in. The stream will
 * persist the remaining data to MongoDB, write the files document, and
 * then emit a 'finish' event.
 *
 * @method
 * @param {Buffer} chunk Buffer to write
 * @param {String} encoding Optional encoding for the buffer
 * @param {Function} callback Function to call when all files and chunks have been persisted to MongoDB
 */

GridFSBucketWriteStream.prototype.end = function(chunk, encoding, callback) {
  var _this = this;
  if (typeof chunk === 'function') {
    (callback = chunk), (chunk = null), (encoding = null);
  } else if (typeof encoding === 'function') {
    (callback = encoding), (encoding = null);
  }

  if (checkAborted(this, callback)) {
    return;
  }
  this.state.streamEnd = true;

  if (callback) {
    this.once('finish', function(result) {
      callback(null, result);
    });
  }

  if (!chunk) {
    waitForIndexes(this, function() {
      writeRemnant(_this);
    });
    return;
  }

  this.write(chunk, encoding, function() {
    writeRemnant(_this);
  });
};

/**
 * @ignore
 */

function __handleError(_this, error, callback) {
  if (_this.state.errored) {
    return;
  }
  _this.state.errored = true;
  if (callback) {
    return callback(error);
  }
  _this.emit('error', error);
}

/**
 * @ignore
 */

function createChunkDoc(filesId, n, data) {
  return {
    _id: core.BSON.ObjectId(),
    files_id: filesId,
    n: n,
    data: data
  };
}

/**
 * @ignore
 */

function checkChunksIndex(_this, callback) {
  _this.chunks.listIndexes().toArray(function(error, indexes) {
    if (error) {
      // Collection doesn't exist so create index
      if (error.code === ERROR_NAMESPACE_NOT_FOUND) {
        var index = { files_id: 1, n: 1 };
        _this.chunks.createIndex(index, { background: false, unique: true }, function(error) {
          if (error) {
            return callback(error);
          }

          callback();
        });
        return;
      }
      return callback(error);
    }

    var hasChunksIndex = false;
    indexes.forEach(function(index) {
      if (index.key) {
        var keys = Object.keys(index.key);
        if (keys.length === 2 && index.key.files_id === 1 && index.key.n === 1) {
          hasChunksIndex = true;
        }
      }
    });

    if (hasChunksIndex) {
      callback();
    } else {
      index = { files_id: 1, n: 1 };
      var indexOptions = getWriteOptions(_this);

      indexOptions.background = false;
      indexOptions.unique = true;

      _this.chunks.createIndex(index, indexOptions, function(error) {
        if (error) {
          return callback(error);
        }

        callback();
      });
    }
  });
}

/**
 * @ignore
 */

function checkDone(_this, callback) {
  if (_this.done) return true;
  if (_this.state.streamEnd && _this.state.outstandingRequests === 0 && !_this.state.errored) {
    // Set done so we dont' trigger duplicate createFilesDoc
    _this.done = true;
    // Create a new files doc
    var filesDoc = createFilesDoc(
      _this.id,
      _this.length,
      _this.chunkSizeBytes,
      _this.md5 && _this.md5.digest('hex'),
      _this.filename,
      _this.options.contentType,
      _this.options.aliases,
      _this.options.metadata
    );

    if (checkAborted(_this, callback)) {
      return false;
    }

    _this.files.insert(filesDoc, getWriteOptions(_this), function(error) {
      if (error) {
        return __handleError(_this, error, callback);
      }
      _this.emit('finish', filesDoc);
    });

    return true;
  }

  return false;
}

/**
 * @ignore
 */

function checkIndexes(_this, callback) {
  _this.files.findOne({}, { _id: 1 }, function(error, doc) {
    if (error) {
      return callback(error);
    }
    if (doc) {
      return callback();
    }

    _this.files.listIndexes().toArray(function(error, indexes) {
      if (error) {
        // Collection doesn't exist so create index
        if (error.code === ERROR_NAMESPACE_NOT_FOUND) {
          var index = { filename: 1, uploadDate: 1 };
          _this.files.createIndex(index, { background: false }, function(error) {
            if (error) {
              return callback(error);
            }

            checkChunksIndex(_this, callback);
          });
          return;
        }
        return callback(error);
      }

      var hasFileIndex = false;
      indexes.forEach(function(index) {
        var keys = Object.keys(index.key);
        if (keys.length === 2 && index.key.filename === 1 && index.key.uploadDate === 1) {
          hasFileIndex = true;
        }
      });

      if (hasFileIndex) {
        checkChunksIndex(_this, callback);
      } else {
        index = { filename: 1, uploadDate: 1 };

        var indexOptions = getWriteOptions(_this);

        indexOptions.background = false;

        _this.files.createIndex(index, indexOptions, function(error) {
          if (error) {
            return callback(error);
          }

          checkChunksIndex(_this, callback);
        });
      }
    });
  });
}

/**
 * @ignore
 */

function createFilesDoc(_id, length, chunkSize, md5, filename, contentType, aliases, metadata) {
  var ret = {
    _id: _id,
    length: length,
    chunkSize: chunkSize,
    uploadDate: new Date(),
    filename: filename
  };

  if (md5) {
    ret.md5 = md5;
  }

  if (contentType) {
    ret.contentType = contentType;
  }

  if (aliases) {
    ret.aliases = aliases;
  }

  if (metadata) {
    ret.metadata = metadata;
  }

  return ret;
}

/**
 * @ignore
 */

function doWrite(_this, chunk, encoding, callback) {
  if (checkAborted(_this, callback)) {
    return false;
  }

  var inputBuf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding);

  _this.length += inputBuf.length;

  // Input is small enough to fit in our buffer
  if (_this.pos + inputBuf.length < _this.chunkSizeBytes) {
    inputBuf.copy(_this.bufToStore, _this.pos);
    _this.pos += inputBuf.length;

    callback && callback();

    // Note that we reverse the typical semantics of write's return value
    // to be compatible with node's `.pipe()` function.
    // True means client can keep writing.
    return true;
  }

  // Otherwise, buffer is too big for current chunk, so we need to flush
  // to MongoDB.
  var inputBufRemaining = inputBuf.length;
  var spaceRemaining = _this.chunkSizeBytes - _this.pos;
  var numToCopy = Math.min(spaceRemaining, inputBuf.length);
  var outstandingRequests = 0;
  while (inputBufRemaining > 0) {
    var inputBufPos = inputBuf.length - inputBufRemaining;
    inputBuf.copy(_this.bufToStore, _this.pos, inputBufPos, inputBufPos + numToCopy);
    _this.pos += numToCopy;
    spaceRemaining -= numToCopy;
    if (spaceRemaining === 0) {
      if (_this.md5) {
        _this.md5.update(_this.bufToStore);
      }
      var doc = createChunkDoc(_this.id, _this.n, _this.bufToStore);
      ++_this.state.outstandingRequests;
      ++outstandingRequests;

      if (checkAborted(_this, callback)) {
        return false;
      }

      _this.chunks.insert(doc, getWriteOptions(_this), function(error) {
        if (error) {
          return __handleError(_this, error);
        }
        --_this.state.outstandingRequests;
        --outstandingRequests;

        if (!outstandingRequests) {
          _this.emit('drain', doc);
          callback && callback();
          checkDone(_this);
        }
      });

      spaceRemaining = _this.chunkSizeBytes;
      _this.pos = 0;
      ++_this.n;
    }
    inputBufRemaining -= numToCopy;
    numToCopy = Math.min(spaceRemaining, inputBufRemaining);
  }

  // Note that we reverse the typical semantics of write's return value
  // to be compatible with node's `.pipe()` function.
  // False means the client should wait for the 'drain' event.
  return false;
}

/**
 * @ignore
 */

function getWriteOptions(_this) {
  var obj = {};
  if (_this.options.writeConcern) {
    obj.w = _this.options.writeConcern.w;
    obj.wtimeout = _this.options.writeConcern.wtimeout;
    obj.j = _this.options.writeConcern.j;
  }
  return obj;
}

/**
 * @ignore
 */

function waitForIndexes(_this, callback) {
  if (_this.bucket.s.checkedIndexes) {
    return callback(false);
  }

  _this.bucket.once('index', function() {
    callback(true);
  });

  return true;
}

/**
 * @ignore
 */

function writeRemnant(_this, callback) {
  // Buffer is empty, so don't bother to insert
  if (_this.pos === 0) {
    return checkDone(_this, callback);
  }

  ++_this.state.outstandingRequests;

  // Create a new buffer to make sure the buffer isn't bigger than it needs
  // to be.
  var remnant = Buffer.alloc(_this.pos);
  _this.bufToStore.copy(remnant, 0, 0, _this.pos);
  if (_this.md5) {
    _this.md5.update(remnant);
  }
  var doc = createChunkDoc(_this.id, _this.n, remnant);

  // If the stream was aborted, do not write remnant
  if (checkAborted(_this, callback)) {
    return false;
  }

  _this.chunks.insert(doc, getWriteOptions(_this), function(error) {
    if (error) {
      return __handleError(_this, error);
    }
    --_this.state.outstandingRequests;
    checkDone(_this);
  });
}

/**
 * @ignore
 */

function checkAborted(_this, callback) {
  if (_this.state.aborted) {
    if (typeof callback === 'function') {
      callback(new Error('this stream has been aborted'));
    }
    return true;
  }
  return false;
}
<commit_msg>Fixed deprecation warning.<commit_after>'use strict';

var core = require('mongodb-core');
var crypto = require('crypto');
var stream = require('stream');
var util = require('util');
var Buffer = require('safe-buffer').Buffer;

var ERROR_NAMESPACE_NOT_FOUND = 26;

module.exports = GridFSBucketWriteStream;

/**
 * A writable stream that enables you to write buffers to GridFS.
 *
 * Do not instantiate this class directly. Use `openUploadStream()` instead.
 *
 * @class
 * @param {GridFSBucket} bucket Handle for this stream's corresponding bucket
 * @param {string} filename The value of the 'filename' key in the files doc
 * @param {object} [options] Optional settings.
 * @param {string|number|object} [options.id] Custom file id for the GridFS file.
 * @param {number} [options.chunkSizeBytes] The chunk size to use, in bytes
 * @param {number} [options.w] The write concern
 * @param {number} [options.wtimeout] The write concern timeout
 * @param {number} [options.j] The journal write concern
 * @param {boolean} [options.disableMD5=false] If true, disables adding an md5 field to file data
 * @fires GridFSBucketWriteStream#error
 * @fires GridFSBucketWriteStream#finish
 * @return {GridFSBucketWriteStream} a GridFSBucketWriteStream instance.
 */

function GridFSBucketWriteStream(bucket, filename, options) {
  options = options || {};
  this.bucket = bucket;
  this.chunks = bucket.s._chunksCollection;
  this.filename = filename;
  this.files = bucket.s._filesCollection;
  this.options = options;
  // Signals the write is all done
  this.done = false;

  this.id = options.id ? options.id : core.BSON.ObjectId();
  this.chunkSizeBytes = this.options.chunkSizeBytes;
  this.bufToStore = Buffer.alloc(this.chunkSizeBytes);
  this.length = 0;
  this.md5 = !options.disableMD5 && crypto.createHash('md5');
  this.n = 0;
  this.pos = 0;
  this.state = {
    streamEnd: false,
    outstandingRequests: 0,
    errored: false,
    aborted: false,
    promiseLibrary: this.bucket.s.promiseLibrary
  };

  if (!this.bucket.s.calledOpenUploadStream) {
    this.bucket.s.calledOpenUploadStream = true;

    var _this = this;
    checkIndexes(this, function() {
      _this.bucket.s.checkedIndexes = true;
      _this.bucket.emit('index');
    });
  }
}

util.inherits(GridFSBucketWriteStream, stream.Writable);

/**
 * An error occurred
 *
 * @event GridFSBucketWriteStream#error
 * @type {Error}
 */

/**
 * `end()` was called and the write stream successfully wrote the file
 * metadata and all the chunks to MongoDB.
 *
 * @event GridFSBucketWriteStream#finish
 * @type {object}
 */

/**
 * Write a buffer to the stream.
 *
 * @method
 * @param {Buffer} chunk Buffer to write
 * @param {String} encoding Optional encoding for the buffer
 * @param {Function} callback Function to call when the chunk was added to the buffer, or if the entire chunk was persisted to MongoDB if this chunk caused a flush.
 * @return {Boolean} False if this write required flushing a chunk to MongoDB. True otherwise.
 */

GridFSBucketWriteStream.prototype.write = function(chunk, encoding, callback) {
  var _this = this;
  return waitForIndexes(this, function() {
    return doWrite(_this, chunk, encoding, callback);
  });
};

/**
 * Places this write stream into an aborted state (all future writes fail)
 * and deletes all chunks that have already been written.
 *
 * @method
 * @param {GridFSBucket~errorCallback} callback called when chunks are successfully removed or error occurred
 * @return {Promise} if no callback specified
 */

GridFSBucketWriteStream.prototype.abort = function(callback) {
  if (this.state.streamEnd) {
    var error = new Error('Cannot abort a stream that has already completed');
    if (typeof callback === 'function') {
      return callback(error);
    }
    return this.state.promiseLibrary.reject(error);
  }
  if (this.state.aborted) {
    error = new Error('Cannot call abort() on a stream twice');
    if (typeof callback === 'function') {
      return callback(error);
    }
    return this.state.promiseLibrary.reject(error);
  }
  this.state.aborted = true;
  this.chunks.deleteMany({ files_id: this.id }, function(error) {
    if (typeof callback === 'function') callback(error);
  });
};

/**
 * Tells the stream that no more data will be coming in. The stream will
 * persist the remaining data to MongoDB, write the files document, and
 * then emit a 'finish' event.
 *
 * @method
 * @param {Buffer} chunk Buffer to write
 * @param {String} encoding Optional encoding for the buffer
 * @param {Function} callback Function to call when all files and chunks have been persisted to MongoDB
 */

GridFSBucketWriteStream.prototype.end = function(chunk, encoding, callback) {
  var _this = this;
  if (typeof chunk === 'function') {
    (callback = chunk), (chunk = null), (encoding = null);
  } else if (typeof encoding === 'function') {
    (callback = encoding), (encoding = null);
  }

  if (checkAborted(this, callback)) {
    return;
  }
  this.state.streamEnd = true;

  if (callback) {
    this.once('finish', function(result) {
      callback(null, result);
    });
  }

  if (!chunk) {
    waitForIndexes(this, function() {
      writeRemnant(_this);
    });
    return;
  }

  this.write(chunk, encoding, function() {
    writeRemnant(_this);
  });
};

/**
 * @ignore
 */

function __handleError(_this, error, callback) {
  if (_this.state.errored) {
    return;
  }
  _this.state.errored = true;
  if (callback) {
    return callback(error);
  }
  _this.emit('error', error);
}

/**
 * @ignore
 */

function createChunkDoc(filesId, n, data) {
  return {
    _id: core.BSON.ObjectId(),
    files_id: filesId,
    n: n,
    data: data
  };
}

/**
 * @ignore
 */

function checkChunksIndex(_this, callback) {
  _this.chunks.listIndexes().toArray(function(error, indexes) {
    if (error) {
      // Collection doesn't exist so create index
      if (error.code === ERROR_NAMESPACE_NOT_FOUND) {
        var index = { files_id: 1, n: 1 };
        _this.chunks.createIndex(index, { background: false, unique: true }, function(error) {
          if (error) {
            return callback(error);
          }

          callback();
        });
        return;
      }
      return callback(error);
    }

    var hasChunksIndex = false;
    indexes.forEach(function(index) {
      if (index.key) {
        var keys = Object.keys(index.key);
        if (keys.length === 2 && index.key.files_id === 1 && index.key.n === 1) {
          hasChunksIndex = true;
        }
      }
    });

    if (hasChunksIndex) {
      callback();
    } else {
      index = { files_id: 1, n: 1 };
      var indexOptions = getWriteOptions(_this);

      indexOptions.background = false;
      indexOptions.unique = true;

      _this.chunks.createIndex(index, indexOptions, function(error) {
        if (error) {
          return callback(error);
        }

        callback();
      });
    }
  });
}

/**
 * @ignore
 */

function checkDone(_this, callback) {
  if (_this.done) return true;
  if (_this.state.streamEnd && _this.state.outstandingRequests === 0 && !_this.state.errored) {
    // Set done so we dont' trigger duplicate createFilesDoc
    _this.done = true;
    // Create a new files doc
    var filesDoc = createFilesDoc(
      _this.id,
      _this.length,
      _this.chunkSizeBytes,
      _this.md5 && _this.md5.digest('hex'),
      _this.filename,
      _this.options.contentType,
      _this.options.aliases,
      _this.options.metadata
    );

    if (checkAborted(_this, callback)) {
      return false;
    }

    _this.files.insertOne(filesDoc, getWriteOptions(_this), function(error) {
      if (error) {
        return __handleError(_this, error, callback);
      }
      _this.emit('finish', filesDoc);
    });

    return true;
  }

  return false;
}

/**
 * @ignore
 */

function checkIndexes(_this, callback) {
  _this.files.findOne({}, { _id: 1 }, function(error, doc) {
    if (error) {
      return callback(error);
    }
    if (doc) {
      return callback();
    }

    _this.files.listIndexes().toArray(function(error, indexes) {
      if (error) {
        // Collection doesn't exist so create index
        if (error.code === ERROR_NAMESPACE_NOT_FOUND) {
          var index = { filename: 1, uploadDate: 1 };
          _this.files.createIndex(index, { background: false }, function(error) {
            if (error) {
              return callback(error);
            }

            checkChunksIndex(_this, callback);
          });
          return;
        }
        return callback(error);
      }

      var hasFileIndex = false;
      indexes.forEach(function(index) {
        var keys = Object.keys(index.key);
        if (keys.length === 2 && index.key.filename === 1 && index.key.uploadDate === 1) {
          hasFileIndex = true;
        }
      });

      if (hasFileIndex) {
        checkChunksIndex(_this, callback);
      } else {
        index = { filename: 1, uploadDate: 1 };

        var indexOptions = getWriteOptions(_this);

        indexOptions.background = false;

        _this.files.createIndex(index, indexOptions, function(error) {
          if (error) {
            return callback(error);
          }

          checkChunksIndex(_this, callback);
        });
      }
    });
  });
}

/**
 * @ignore
 */

function createFilesDoc(_id, length, chunkSize, md5, filename, contentType, aliases, metadata) {
  var ret = {
    _id: _id,
    length: length,
    chunkSize: chunkSize,
    uploadDate: new Date(),
    filename: filename
  };

  if (md5) {
    ret.md5 = md5;
  }

  if (contentType) {
    ret.contentType = contentType;
  }

  if (aliases) {
    ret.aliases = aliases;
  }

  if (metadata) {
    ret.metadata = metadata;
  }

  return ret;
}

/**
 * @ignore
 */

function doWrite(_this, chunk, encoding, callback) {
  if (checkAborted(_this, callback)) {
    return false;
  }

  var inputBuf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding);

  _this.length += inputBuf.length;

  // Input is small enough to fit in our buffer
  if (_this.pos + inputBuf.length < _this.chunkSizeBytes) {
    inputBuf.copy(_this.bufToStore, _this.pos);
    _this.pos += inputBuf.length;

    callback && callback();

    // Note that we reverse the typical semantics of write's return value
    // to be compatible with node's `.pipe()` function.
    // True means client can keep writing.
    return true;
  }

  // Otherwise, buffer is too big for current chunk, so we need to flush
  // to MongoDB.
  var inputBufRemaining = inputBuf.length;
  var spaceRemaining = _this.chunkSizeBytes - _this.pos;
  var numToCopy = Math.min(spaceRemaining, inputBuf.length);
  var outstandingRequests = 0;
  while (inputBufRemaining > 0) {
    var inputBufPos = inputBuf.length - inputBufRemaining;
    inputBuf.copy(_this.bufToStore, _this.pos, inputBufPos, inputBufPos + numToCopy);
    _this.pos += numToCopy;
    spaceRemaining -= numToCopy;
    if (spaceRemaining === 0) {
      if (_this.md5) {
        _this.md5.update(_this.bufToStore);
      }
      var doc = createChunkDoc(_this.id, _this.n, _this.bufToStore);
      ++_this.state.outstandingRequests;
      ++outstandingRequests;

      if (checkAborted(_this, callback)) {
        return false;
      }

      _this.chunks.insertOne(doc, getWriteOptions(_this), function(error) {
        if (error) {
          return __handleError(_this, error);
        }
        --_this.state.outstandingRequests;
        --outstandingRequests;

        if (!outstandingRequests) {
          _this.emit('drain', doc);
          callback && callback();
          checkDone(_this);
        }
      });

      spaceRemaining = _this.chunkSizeBytes;
      _this.pos = 0;
      ++_this.n;
    }
    inputBufRemaining -= numToCopy;
    numToCopy = Math.min(spaceRemaining, inputBufRemaining);
  }

  // Note that we reverse the typical semantics of write's return value
  // to be compatible with node's `.pipe()` function.
  // False means the client should wait for the 'drain' event.
  return false;
}

/**
 * @ignore
 */

function getWriteOptions(_this) {
  var obj = {};
  if (_this.options.writeConcern) {
    obj.w = _this.options.writeConcern.w;
    obj.wtimeout = _this.options.writeConcern.wtimeout;
    obj.j = _this.options.writeConcern.j;
  }
  return obj;
}

/**
 * @ignore
 */

function waitForIndexes(_this, callback) {
  if (_this.bucket.s.checkedIndexes) {
    return callback(false);
  }

  _this.bucket.once('index', function() {
    callback(true);
  });

  return true;
}

/**
 * @ignore
 */

function writeRemnant(_this, callback) {
  // Buffer is empty, so don't bother to insert
  if (_this.pos === 0) {
    return checkDone(_this, callback);
  }

  ++_this.state.outstandingRequests;

  // Create a new buffer to make sure the buffer isn't bigger than it needs
  // to be.
  var remnant = Buffer.alloc(_this.pos);
  _this.bufToStore.copy(remnant, 0, 0, _this.pos);
  if (_this.md5) {
    _this.md5.update(remnant);
  }
  var doc = createChunkDoc(_this.id, _this.n, remnant);

  // If the stream was aborted, do not write remnant
  if (checkAborted(_this, callback)) {
    return false;
  }

  _this.chunks.insertOne(doc, getWriteOptions(_this), function(error) {
    if (error) {
      return __handleError(_this, error);
    }
    --_this.state.outstandingRequests;
    checkDone(_this);
  });
}

/**
 * @ignore
 */

function checkAborted(_this, callback) {
  if (_this.state.aborted) {
    if (typeof callback === 'function') {
      callback(new Error('this stream has been aborted'));
    }
    return true;
  }
  return false;
}
<|endoftext|>


<commit_before>/* jshint node: true */
module.exports = function(paths) {
    "use strict";
    return {
        allhead: {
            src: ["" + paths.build + "/*.{js,css}"],
            options: {
                position: "top",
                banner: "/*!\n* <%= pkg.title %>\n*\n* Copyright 2013, <%= pkg.author %> info@fineuploader.com\n*\n* Version: <%= pkg.version %>\n*\n* Homepage: http://fineuploader.com\n*\n* Repository: <%= pkg.repository.url %>\n*\n* Licensed only under the Widen Commercial License, see LICENSE\n*/ \n\n"
            }
        },
        allfoot: {
            src: ["" + paths.build + "/*.{js,css}"],
            options: {
                position: "bottom",
                banner: "/*! <%= grunt.template.today('yyyy-mm-dd') %> */\n"
            }
        }
    };
};
<commit_msg>chore(build): link to license file in source header [skip ci]<commit_after>/* jshint node: true */
module.exports = function(paths) {
    "use strict";
    return {
        allhead: {
            src: ["" + paths.build + "/*.{js,css}"],
            options: {
                position: "top",
                banner: "/*!\n* <%= pkg.title %>\n*\n* Copyright 2013, <%= pkg.author %> info@fineuploader.com\n*\n* Version: <%= pkg.version %>\n*\n* Homepage: http://fineuploader.com\n*\n* Repository: <%= pkg.repository.url %>\n*\n* Licensed only under the Widen Commercial License (http://fineuploader.com/licensing).\n*/ \n\n"
            }
        },
        allfoot: {
            src: ["" + paths.build + "/*.{js,css}"],
            options: {
                position: "bottom",
                banner: "/*! <%= grunt.template.today('yyyy-mm-dd') %> */\n"
            }
        }
    };
};
<|endoftext|>


<commit_before>/*
 * angular-confirm
 * http://schlogen.github.io/angular-confirm/
 * Version: 1.1.1 - 2015-08-10
 * License: Apache
 */
angular.module('angular-confirm', ['ui.bootstrap'])
  .controller('ConfirmModalController', ['$scope', '$modalInstance', 'data', function ($scope, $modalInstance, data) {
    $scope.data = angular.copy(data);

    $scope.ok = function () {
      $modalInstance.close();
    };

    $scope.cancel = function () {
      $modalInstance.dismiss('cancel');
    };

  }])
  .value('$confirmModalDefaults', {
    template: '

{{data.title}}

' +
    '
{{data.text}}
' +
    '
' +
    '<button class="btn btn-primary" ng-click="ok()">{{data.ok}}</button>' +
    '<button class="btn btn-default" ng-click="cancel()">{{data.cancel}}</button>' +
    '
',
    controller: 'ConfirmModalController',
    defaultLabels: {
      title: 'Confirm',
      ok: 'OK',
      cancel: 'Cancel'
    }
  })
  .factory('$confirm', ['$modal', '$confirmModalDefaults', function ($modal, $confirmModalDefaults) {
    return function (data, settings) {
      var defaults = angular.copy($confirmModalDefaults);
      settings = angular.extend(defaults, (settings || {}));

      data = angular.extend({}, settings.defaultLabels, data || {});

      if ('templateUrl' in settings && 'template' in settings) {
        delete settings.template;
      }

      settings.resolve = {
        data: function () {
          return data;
        }
      };

      return $modal.open(settings).result;
    };
  }])
  .directive('confirm', ['$confirm', function ($confirm) {
    return {
      priority: 1,
      restrict: 'A',
      scope: {
        confirmIf: "=",
        ngClick: '&',
        confirm: '@',
        confirmSettings: "=",
        confirmTitle: '@',
        confirmOk: '@',
        confirmCancel: '@'
      },
      link: function (scope, element, attrs) {

        element.unbind("click").bind("click", function ($event) {

          $event.preventDefault();

          if (angular.isUndefined(scope.confirmIf) || scope.confirmIf) {

            var data = {text: scope.confirm};
            if (scope.confirmTitle) {
              data.title = scope.confirmTitle;
            }
            if (scope.confirmOk) {
              data.ok = scope.confirmOk;
            }
            if (scope.confirmCancel) {
              data.cancel = scope.confirmCancel;
            }
            $confirm(data, scope.confirmSettings || {}).then(scope.ngClick);
          } else {

            scope.$apply(scope.ngClick);
          }
        });

      }
    }
  }]);
<commit_msg>Only require the modal module to use with this component to prevent conflicts with AngularStrap<commit_after>/*
 * angular-confirm
 * http://schlogen.github.io/angular-confirm/
 * Version: 1.1.1 - 2015-08-10
 * License: Apache
 */
angular.module('angular-confirm', [ 'ui.bootstrap.modal'])
  .controller('ConfirmModalController', ['$scope', '$modalInstance', 'data', function ($scope, $modalInstance, data) {
    $scope.data = angular.copy(data);

    $scope.ok = function () {
      $modalInstance.close();
    };

    $scope.cancel = function () {
      $modalInstance.dismiss('cancel');
    };

  }])
  .value('$confirmModalDefaults', {
    template: '

{{data.title}}

' +
    '
{{data.text}}
' +
    '
' +
    '<button class="btn btn-primary" ng-click="ok()">{{data.ok}}</button>' +
    '<button class="btn btn-default" ng-click="cancel()">{{data.cancel}}</button>' +
    '
',
    controller: 'ConfirmModalController',
    defaultLabels: {
      title: 'Confirm',
      ok: 'OK',
      cancel: 'Cancel'
    }
  })
  .factory('$confirm', ['$modal', '$confirmModalDefaults', function ($modal, $confirmModalDefaults) {
    return function (data, settings) {
      var defaults = angular.copy($confirmModalDefaults);
      settings = angular.extend(defaults, (settings || {}));

      data = angular.extend({}, settings.defaultLabels, data || {});

      if ('templateUrl' in settings && 'template' in settings) {
        delete settings.template;
      }

      settings.resolve = {
        data: function () {
          return data;
        }
      };

      return $modal.open(settings).result;
    };
  }])
  .directive('confirm', ['$confirm', function ($confirm) {
    return {
      priority: 1,
      restrict: 'A',
      scope: {
        confirmIf: "=",
        ngClick: '&',
        confirm: '@',
        confirmSettings: "=",
        confirmTitle: '@',
        confirmOk: '@',
        confirmCancel: '@'
      },
      link: function (scope, element, attrs) {

        element.unbind("click").bind("click", function ($event) {

          $event.preventDefault();

          if (angular.isUndefined(scope.confirmIf) || scope.confirmIf) {

            var data = {text: scope.confirm};
            if (scope.confirmTitle) {
              data.title = scope.confirmTitle;
            }
            if (scope.confirmOk) {
              data.ok = scope.confirmOk;
            }
            if (scope.confirmCancel) {
              data.cancel = scope.confirmCancel;
            }
            $confirm(data, scope.confirmSettings || {}).then(scope.ngClick);
          } else {

            scope.$apply(scope.ngClick);
          }
        });

      }
    }
  }]);
<|endoftext|>


<commit_before>/**
 * @file CheckboxGroup component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';

import Checkbox from '../Checkbox';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import Position from '../_statics/Position';

export default class CheckboxGroup extends Component {

    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            value: props.value
        };

        this.changeHandler = ::this.changeHandler;

    }

    changeHandler(item) {

        let value = _.cloneDeep(this.state.value);

        if (!value || !_.isArray(value)) {
            value = [item];
        } else {

            const index = value.findIndex(v => v.value === item.value);

            if (index > -1) {
                value.splice(index, 1);
            } else {
                value.push(item);
            }

        }

        this.setState({
            value
        }, () => {
            const {disabled, onChange} = this.props;
            !disabled && onChange && onChange(value);
        });

    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.value && nextProps.value !== this.state.value) {
            this.setState({
                value: nextProps.value
            });
        }
    }

    render() {

        const {data} = this.props;

        if (!data) {
            return null;
        }

        const {
                className, style, theme, name, disabled, idProp, uncheckedIconCls, checkedIconCls, indeterminateIconCls,
                onCheck, onUncheck
            } = this.props,
            {value} = this.state;

        return (

                {
                    data.map((item, index) => {

                        const isChecked = value && value.findIndex(v => v.value === item.value) > -1;

                        return (
                            <Checkbox key={idProp in item ? item[idProp] : index}
                                      className={item.className ? item.className : ''}
                                      style={item.style}
                                      theme={item.theme || theme}
                                      uncheckedIconCls={item.uncheckedIconCls || uncheckedIconCls}
                                      checkedIconCls={item.checkedIconCls || checkedIconCls}
                                      indeterminateIconCls={item.indeterminateIconCls || indeterminateIconCls}
                                      name={name}
                                      label={item.label}
                                      value={item.value}
                                      disabled={disabled || item.disabled}
                                      checked={isChecked}
                                      tip={item.tip}
                                      tipPosition={item.tipPosition}
                                      onChange={() => {
                                          this.changeHandler(item);
                                      }}
                                      onCheck={() => {
                                          onCheck && onCheck(item);
                                      }}
                                      onUncheck={() => {
                                          onUncheck && onUncheck(item);
                                      }}/>
                        );

                    })
                }

        );

    }
};

CheckboxGroup.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    /**
     * The CheckboxGroup theme.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    name: PropTypes.string,

    data: PropTypes.arrayOf(PropTypes.shape({

        className: PropTypes.string,
        style: PropTypes.object,
        theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

        label: PropTypes.any,
        value: PropTypes.any,

        disabled: PropTypes.bool,

        tip: PropTypes.any,
        tipPosition: PropTypes.oneOf(Util.enumerateValue(Position))

    })).isRequired,
    value: PropTypes.array,
    disabled: PropTypes.bool,

    idProp: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

    uncheckedIconCls: PropTypes.string,
    checkedIconCls: PropTypes.string,
    indeterminateIconCls: PropTypes.string,

    onChange: PropTypes.func,

    onCheck: PropTypes.func,

    onUncheck: PropTypes.func

};

CheckboxGroup.defaultProps = {

    className: null,
    style: null,
    theme: Theme.DEFAULT,

    name: null,
    data: null,
    value: null,
    disabled: false,
    idProp: 'id',

    uncheckedIconCls: 'fa fa-square-o',
    checkedIconCls: 'fa fa-check-square',
    indeterminateIconCls: 'fa fa-minus-square'

};<commit_msg>update CheckboxGroup<commit_after>/**
 * @file CheckboxGroup component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';

import Checkbox from '../Checkbox';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import Position from '../_statics/Position';

export default class CheckboxGroup extends Component {

    static Theme = Theme;
    static propTypes = {

        className: PropTypes.string,
        style: PropTypes.object,

        /**
         * The CheckboxGroup theme.
         */
        theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

        name: PropTypes.string,

        data: PropTypes.arrayOf(PropTypes.shape({

            className: PropTypes.string,
            style: PropTypes.object,
            theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

            label: PropTypes.any,
            value: PropTypes.any,

            disabled: PropTypes.bool,

            tip: PropTypes.any,
            tipPosition: PropTypes.oneOf(Util.enumerateValue(Position))

        })).isRequired,
        value: PropTypes.array,
        disabled: PropTypes.bool,

        idProp: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        uncheckedIconCls: PropTypes.string,
        checkedIconCls: PropTypes.string,
        indeterminateIconCls: PropTypes.string,

        onChange: PropTypes.func,

        onCheck: PropTypes.func,

        onUncheck: PropTypes.func

    };
    static defaultProps = {

        className: null,
        style: null,
        theme: Theme.DEFAULT,

        name: null,
        data: null,
        value: null,
        disabled: false,
        idProp: 'id',

        uncheckedIconCls: 'fa fa-square-o',
        checkedIconCls: 'fa fa-check-square',
        indeterminateIconCls: 'fa fa-minus-square'

    };

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            value: props.value
        };

        this.changeHandler = ::this.changeHandler;

    }

    changeHandler(item) {

        let value = _.cloneDeep(this.state.value);

        if (!value || !_.isArray(value)) {
            value = [item];
        } else {

            const index = value.findIndex(v => v.value === item.value);

            if (index > -1) {
                value.splice(index, 1);
            } else {
                value.push(item);
            }

        }

        this.setState({
            value
        }, () => {
            const {disabled, onChange} = this.props;
            !disabled && onChange && onChange(value);
        });

    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.value && nextProps.value !== this.state.value) {
            this.setState({
                value: nextProps.value
            });
        }
    }

    render() {

        const {data} = this.props;

        if (!data) {
            return null;
        }

        const {
                className, style, theme, name, disabled, idProp, uncheckedIconCls, checkedIconCls, indeterminateIconCls,
                onCheck, onUncheck
            } = this.props,
            {value} = this.state;

        return (

                {
                    data.map((item, index) => {

                        const isChecked = value && value.findIndex(v => v.value === item.value) > -1;

                        return (
                            <Checkbox key={idProp in item ? item[idProp] : index}
                                      className={item.className ? item.className : ''}
                                      style={item.style}
                                      theme={item.theme || theme}
                                      uncheckedIconCls={item.uncheckedIconCls || uncheckedIconCls}
                                      checkedIconCls={item.checkedIconCls || checkedIconCls}
                                      indeterminateIconCls={item.indeterminateIconCls || indeterminateIconCls}
                                      name={name}
                                      label={item.label}
                                      value={item.value}
                                      disabled={disabled || item.disabled}
                                      checked={isChecked}
                                      tip={item.tip}
                                      tipPosition={item.tipPosition}
                                      onChange={() => {
                                          this.changeHandler(item);
                                      }}
                                      onCheck={() => {
                                          onCheck && onCheck(item);
                                      }}
                                      onUncheck={() => {
                                          onUncheck && onUncheck(item);
                                      }}/>
                        );

                    })
                }

        );

    }
};<|endoftext|>


<commit_before>import _ from 'lodash'
import postcss from 'postcss'

import substituteTailwindAtRules from './lib/substituteTailwindAtRules'
import evaluateTailwindFunctions from './lib/evaluateTailwindFunctions'
import substituteVariantsAtRules from './lib/substituteVariantsAtRules'
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
import substituteScreenAtRules from './lib/substituteScreenAtRules'
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'

import generateUtilities from './legacy/generateUtilities'
import processPlugins from './util/processPlugins'

import defaultPlugins from './defaultPlugins'

export default function(getConfig) {
  return function(css) {
    const config = getConfig()
    const processedPlugins = processPlugins([
      ...defaultPlugins(config),
      ...config.plugins
    ], config)
    const utilities = generateUtilities(config, processedPlugins.utilities)

    return postcss([
      substituteTailwindAtRules(config, processedPlugins, utilities),
      evaluateTailwindFunctions(config),
      substituteVariantsAtRules(config, processedPlugins),
      substituteResponsiveAtRules(config),
      substituteScreenAtRules(config),
      substituteClassApplyAtRules(config, utilities),
    ]).process(css, { from: _.get(css, 'source.input.file') })
  }
}
<commit_msg>Provide our own rawCache to avoid performance issues<commit_after>import _ from 'lodash'
import postcss from 'postcss'

import substituteTailwindAtRules from './lib/substituteTailwindAtRules'
import evaluateTailwindFunctions from './lib/evaluateTailwindFunctions'
import substituteVariantsAtRules from './lib/substituteVariantsAtRules'
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
import substituteScreenAtRules from './lib/substituteScreenAtRules'
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'

import generateUtilities from './legacy/generateUtilities'
import processPlugins from './util/processPlugins'

import defaultPlugins from './defaultPlugins'

export default function(getConfig) {
  return function(css) {
    const config = getConfig()
    const processedPlugins = processPlugins([
      ...defaultPlugins(config),
      ...config.plugins
    ], config)
    const utilities = generateUtilities(config, processedPlugins.utilities)

    return postcss([
      substituteTailwindAtRules(config, processedPlugins, utilities),
      evaluateTailwindFunctions(config),
      substituteVariantsAtRules(config, processedPlugins),
      substituteResponsiveAtRules(config),
      substituteScreenAtRules(config),
      substituteClassApplyAtRules(config, utilities),
      function (root, result) {
        root.rawCache = {
          colon: ': ',
          indent: '  ',
          beforeDecl: '\n',
          beforeRule: '\n',
          beforeOpen: ' ',
          beforeClose: '\n',
          beforeComment: '\n',
          after: '\n',
          emptyBody: '',
          commentLeft: ' ',
          commentRight: ' ',
          semicolon: false
        }
      },
    ]).process(css, { from: _.get(css, 'source.input.file') })
  }
}
<|endoftext|>


<commit_before>'use strict';

/*
 * Start a chain of promises while wrapping synchronous exceptions to promise rejections.
 */
module.exports = function (fn) {
    return new Promise(function (resolve, reject) {
        try {
            resolve(fn());
        } catch (err) {
            reject(err);
        }
    });
};
<commit_msg>update promise/attempt — lint, es6<commit_after>'use strict'

/*
  Start a chain of promises while wrapping synchronous exceptions
  to promise rejections.

*/

module.exports = (fn) => new Promise((resolve, reject) => {
  try {
    resolve(fn())
  } catch (err) {
    reject(err)
  }
})
<|endoftext|>


<commit_before>/**
 * This file indexes followers of popular repositories.
 *
 * Usage:
 *   node followersIndexer.js repositories.json followers.json --tokens="A,B,C"
 */

var tokens = require('./lib/tokens')();
var fs = require('fs');

if (tokens.enabled === 0) {
  printTokenHelp();
  return -1;
}

var githubClient = require('./lib/ghclient')(tokens);
var repositoriesFileName = process.argv[2];
var inputArgumentsValid = fs.existsSync(repositoriesFileName);

if (!inputArgumentsValid) {
  printInputArgumentsHelp();
  return -2;
}

var allRepositories = getIndexedRepositories(repositoriesFileName);
var processedRepositoriesName = getProcessedRepositoriesFileName(process.argv[3], repositoriesFileName);
var db = require('./lib/ldb')(processedRepositoriesName);

db.getAllKeys()
  .then(function (processedRepositoriesKeys) {
    var processedRepositories = {};
    processedRepositoriesKeys.forEach(function (key) { processedRepositories[key] = 1; });

    var remainingRepositories = getRemainingRepositories(allRepositories, processedRepositories);
    printStats(allRepositories, processedRepositories, remainingRepositories);

    var indexFollowers = require('./lib/indexFollowers');
    indexFollowers(remainingRepositories, db, githubClient);
  });

function printTokenHelp() {
  [
    'Github access token is not present in environment variables',
    'Go to https://github.com/settings/applications and click "Create new token"',
    'Pass tokens as a comma-separated argument --tokens="A,B,C"'
  ].forEach(function (line) { console.log(line); });
}

function printInputArgumentsHelp() {
  [
    'GitHub popuplar projects followers indexer.',
    'Usage:',
    '  node followersIndexer repositories.json followers.json',
    '',
    'Where: ',
    ' - repositories.json: file generated by repoIndexer.js',
    ' - followers.json: file where to save indexed followers'
  ].forEach(function (line) { console.log(line); });
}

function printStats(allRepositories, processedRepositories, remainingRepositories) {
  console.log('Statistics:');
  console.log('  Total:', allRepositories.length);
  console.log('  Processed:', Object.keys(processedRepositories).length);
  console.log('  Remaining:', remainingRepositories.length);
}

function readJson(fileName) {
  return JSON.parse(fs.readFileSync(fileName, 'utf8'));
}

function getIndexedRepositories(repositoriesFileName) {
  console.log('Reading repositories file', repositoriesFileName);
  var repositories = readJson(repositoriesFileName);
  console.log('Read', repositories.length, 'repositories');
  return repositories;
}

function getRemainingRepositories(allRepositories, indexedRepositories) {
  return allRepositories.filter(function (x) { return !indexedRepositories[x.name]; });
}

function getProcessedRepositoriesFileName(followersFileName, repositoriesFileName) {
  if (fs.existsSync(followersFileName)) {
    console.log('Indexed followers:', followersFileName);
    return followersFileName;
  }

  console.log('Indexed followers database is not found.');
  var path = require('path');
  var absoluteRepositoriesFileName = path.resolve(repositoriesFileName);
  var repoPath = path.dirname(absoluteRepositoriesFileName);
  followersFileName = path.join(repoPath, path.basename(absoluteRepositoriesFileName, '.json') + 'Followers');
  console.log('Trying to use', followersFileName, 'as indexed followers db.');
  return followersFileName;
}
<commit_msg>Updated documantation<commit_after>/**
 * GitHub popuplar projects followers indexer.
 * Usage:
 *   node followersIndexer repositories.json followers --tokens="A,B,C"
 *
 * Where:
 *   - repositories.json: file generated by repoIndexer.js
 *   - followers: leveldb name where to save indexed followers
 */

var tokens = require('./lib/tokens')();
var fs = require('fs');

if (tokens.enabled === 0) {
  printTokenHelp();
  return -1;
}

var githubClient = require('./lib/ghclient')(tokens);
var repositoriesFileName = process.argv[2];
var inputArgumentsValid = fs.existsSync(repositoriesFileName);

if (!inputArgumentsValid) {
  printInputArgumentsHelp();
  return -2;
}

var allRepositories = getIndexedRepositories(repositoriesFileName);
var processedRepositoriesName = getProcessedRepositoriesFileName(process.argv[3], repositoriesFileName);
var db = require('./lib/ldb')(processedRepositoriesName);

db.getAllKeys()
  .then(function (processedRepositoriesKeys) {
    var processedRepositories = {};
    processedRepositoriesKeys.forEach(function (key) { processedRepositories[key] = 1; });

    var remainingRepositories = getRemainingRepositories(allRepositories, processedRepositories);
    printStats(allRepositories, processedRepositories, remainingRepositories);

    var indexFollowers = require('./lib/indexFollowers');
    indexFollowers(remainingRepositories, db, githubClient);
  });

function printTokenHelp() {
  [
    'Github access token is not present in environment variables',
    'Go to https://github.com/settings/applications and click "Create new token"',
    'Pass tokens as a comma-separated argument --tokens="A,B,C"'
  ].forEach(function (line) { console.log(line); });
}

function printInputArgumentsHelp() {
  [
    'GitHub popuplar projects followers indexer.',
    'Usage:',
    '  node followersIndexer repositories.json followers --tokens="A,B,C"',
    '',
    'Where: ',
    ' - repositories.json: file generated by repoIndexer.js',
    ' - followers: leveldb name where to save indexed followers'
  ].forEach(function (line) { console.log(line); });
}

function printStats(allRepositories, processedRepositories, remainingRepositories) {
  console.log('Statistics:');
  console.log('  Total:', allRepositories.length);
  console.log('  Processed:', Object.keys(processedRepositories).length);
  console.log('  Remaining:', remainingRepositories.length);
}

function readJson(fileName) {
  return JSON.parse(fs.readFileSync(fileName, 'utf8'));
}

function getIndexedRepositories(repositoriesFileName) {
  console.log('Reading repositories file', repositoriesFileName);
  var repositories = readJson(repositoriesFileName);
  console.log('Read', repositories.length, 'repositories');
  return repositories;
}

function getRemainingRepositories(allRepositories, indexedRepositories) {
  return allRepositories.filter(function (x) { return !indexedRepositories[x.name]; });
}

function getProcessedRepositoriesFileName(followersFileName, repositoriesFileName) {
  if (fs.existsSync(followersFileName)) {
    console.log('Indexed followers:', followersFileName);
    return followersFileName;
  }

  console.log('Indexed followers database is not found.');
  var path = require('path');
  var absoluteRepositoriesFileName = path.resolve(repositoriesFileName);
  var repoPath = path.dirname(absoluteRepositoriesFileName);
  followersFileName = path.join(repoPath, path.basename(absoluteRepositoriesFileName, '.json') + 'Followers');
  console.log('Trying to use', followersFileName, 'as indexed followers db.');
  return followersFileName;
}
<|endoftext|>


<commit_before><commit_msg>Implemented leaderboard.list().<commit_after><|endoftext|>