<commit_before>/* Setup - Sources - Model */
var SourceModel = Backbone.Model.extend({
  defaults: {
    _section: '',
    action: '{{_("Add")}}',
    name: '',
    username: '',
    password: '',
    host: '',
    port: 993,
    protocol: '',
    interval: 300,
    'discovery.paths': [],
    'discovery.policy': 'unknown',
    'discovery.local_copy': true,
    'discovery.process_new': true,
    'discovery.create_tag': false,
    'discovery.apply_tags': ['']
  },
  validation: {
    name: {
      minLength: 2,
      required: true,
      msg: "{{_('Source Name')}}"
    },
    username: {
      required: false,
      msg: "{{_('User name')}}"
    },
    password: {
      required: false,
      msg: "{{_('Password')}}"
    },
    host: {
      required: false,
      msg: "{{_('Host')}}"
    },
    port: {
      required: false,
      msg: "{{_('Port')}}"
    },
    protocol: {
      oneOf: ["mbox", "maildir", "macmaildir", "gmvault", "imap", "imap_ssl", "pop3"],
      required: true,
      msg: "{{_('Mailbox protocol or format')}}"
    },
    interval: {
      required: false,
      msg: "{{_('How frequently to check for mail')}}"
    },
    'discovery.paths': {
      required: false,
      msg: "{{_('Paths to watch for new mailboxes')}}"
    },
    'discovery.policy': {
      oneOf: ['unknown', 'ignore', 'watch','read', 'move', 'sync'],
      required: false,
      msg: "{{_('Default mailbox policy')}}"
    },
    'discovery.local_copy': {
      required: false,
      msg: "{{_('Copy mail to a local mailbox?')}}"
    },
    'discovery.create_tag': {
      required: false,
      msg: "{{_('Create a tag for each mailbox?')}}"
    },
    'discovery.process_new': {
      required: false,
      msg: "{{_('Is a potential source of new mail')}}"
    },
    'discovery.apply_tags': {
      required: false,
      msg: "{{_('Tags applied to messages')}}"
    }
  }
});

var SourcesCollection = Backbone.Collection.extend({
  url: '/api/0/settings/as.json?var=sources',
  model: SourceModel
});

/* Setup - Sources - View */
var SourcesView = Backbone.View.extend({
  initialize: function() {
		this.render();
  },
  render: function() {
    return this;
  },
  events: {
    "change #input-setup-source-type"  : "actionSelected",
    "change #input-setup-source_sync"  : "actionSyncSelected",
    "click .source-mailbox-policy"     : "actionMailboxToggle",
    "click #btn-setup-sources-next"    : "actionGoToImporting",
    "click #btn-setup-source-save"     : "processSource",
    "click .setup-source-disable"      : "processDisable"
  },
  show: function() {

    this.$el.html(_.template($("#template-setup-sources").html()));

    // Load Data & Add to Collection
    Mailpile.API.settings_get({ var: 'sources' }, function(result) {

      // Redirect to Add
      if (_.isEmpty(result.result.sources)) {
        Backbone.history.navigate('#sources/add', true);
      }

      _.each(result.result.sources, function(val, key) {
        var source = new SourceModel(_.extend({id: key, action: '{{_("Edit")}}'}, val));
        SourcesCollection.add(source);
        $('#setup-sources-list-items').append(_.template($('#template-setup-sources-item').html(), source.attributes));
      });
    });

    return this;
  },
  showEvent: function(event) {

    // Default Message
    var message = event.message;

    // Is IMAP or POP
    if (event.data.connection) {

      // Connection / Behavior (message)
      if (event.data.connection && event.data.connection.live && !event.data.connection.error[0]) {

        // Various Found or Is downloading
        if (event.data.copying && event.data.copying.running && event.data.copying.total) {
          message = '{{_("Downloading")}} ' + event.data.copying.copied_messages + ' {{_("of")}} ' + event.data.copying.total + ' {{_("messages")}}';
        } else if (event.data.copying && event.data.copying.running) {
          message = '{{_("Found some messages to download")}}';
        } else if (event.data.rescan) {
          message = '{{_("Rescanning mailboxes")}}';
        }

      }
      else if (!event.data.connection.live && !event.data.connection.error[0]) {
        message = '{{_("Not connected to server")}}';
      }
      else if (!event.data.connection.live && event.data.connection.error[0] == 'auth') {
        message =  '{{_("Can not connect to mailserver")}}';
        $('#setup-source-notice-' + event.data.id)
          .html('{{_("The username & password are incorrect")}} {{_("edit them now")}}')
          .fadeIn();
      }
      else if (!event.data.connection.live && event.data.connection.error[0]) {
        message = event.data.connection.error[1];
      }
    }

    // Has Unconfigured Mailboxes (action)
    if (event.data.have_unknown) {
      $('#setup-source-notice-' + event.data.id)
        .html('{{_("You have unconfigured mailboxes")}} {{_("configure them now")}}')
        .fadeIn();

      $('#btn-setup-sources-next').attr('disabled', true);
    } else {
      $('#btn-setup-sources-next').attr('disabled', false);
    }

    // UI Message
    $('#setup-source-message-' + event.data.id).html('' + message + '');

  },
  actionGoToImporting: function(e) {
    e.preventDefault();
    Backbone.history.navigate('#importing', true);
  },
  processDisable: function(e) {
    e.preventDefault();
    var source_id = $(e.target).data('id');
    Mailpile.API.settings_set_post({ _section: source_id, enabled: false }, function(result) {
      $('#setup-source-' + source_id).fadeOut();
    });
  }
});<commit_msg>Abstracted Event notifications a bit better<commit_after>/* Setup - Sources - Model */
var SourceModel = Backbone.Model.extend({
  defaults: {
    _section: '',
    action: '{{_("Add")}}',
    name: '',
    username: '',
    password: '',
    host: '',
    port: 993,
    protocol: '',
    interval: 300,
    'discovery.paths': [],
    'discovery.policy': 'unknown',
    'discovery.local_copy': true,
    'discovery.process_new': true,
    'discovery.create_tag': false,
    'discovery.apply_tags': ['']
  },
  validation: {
    name: {
      minLength: 2,
      required: true,
      msg: "{{_('Source Name')}}"
    },
    username: {
      required: false,
      msg: "{{_('User name')}}"
    },
    password: {
      required: false,
      msg: "{{_('Password')}}"
    },
    host: {
      required: false,
      msg: "{{_('Host')}}"
    },
    port: {
      required: false,
      msg: "{{_('Port')}}"
    },
    protocol: {
      oneOf: ["mbox", "maildir", "macmaildir", "gmvault", "imap", "imap_ssl", "pop3"],
      required: true,
      msg: "{{_('You must pick a protocol or format')}}"
    },
    interval: {
      required: false,
      msg: "{{_('How frequently to check for mail')}}"
    },
    'discovery.paths': {
      required: false,
      msg: "{{_('Paths to watch for new mailboxes')}}"
    },
    'discovery.policy': {
      oneOf: ['unknown', 'ignore', 'watch','read', 'move', 'sync'],
      required: false,
      msg: "{{_('Default mailbox policy')}}"
    },
    'discovery.local_copy': {
      required: false,
      msg: "{{_('Copy mail to a local mailbox?')}}"
    },
    'discovery.create_tag': {
      required: false,
      msg: "{{_('Create a tag for each mailbox?')}}"
    },
    'discovery.process_new': {
      required: false,
      msg: "{{_('Is a potential source of new mail')}}"
    },
    'discovery.apply_tags': {
      required: false,
      msg: "{{_('Tags applied to messages')}}"
    }
  }
});

var SourcesCollection = Backbone.Collection.extend({
  url: '/api/0/settings/as.json?var=sources',
  model: SourceModel
});

/* Setup - Sources - View */
var SourcesView = Backbone.View.extend({
  initialize: function() {
		this.render();
  },
  render: function() {
    return this;
  },
  events: {
    "change #input-setup-source-type"  : "actionSelected",
    "change #input-setup-source_sync"  : "actionSyncSelected",
    "click .source-mailbox-policy"     : "actionMailboxToggle",
    "click #btn-setup-sources-next"    : "actionGoToImporting",
    "click #btn-setup-source-save"     : "processSource",
    "click .setup-source-disable"      : "processDisable"
  },
  show: function() {

    this.$el.html(_.template($("#template-setup-sources").html()));

    // Load Data & Add to Collection
    Mailpile.API.settings_get({ var: 'sources' }, function(result) {

      // Redirect to Add
      if (_.isEmpty(result.result.sources)) {
        Backbone.history.navigate('#sources/add', true);
      }

      _.each(result.result.sources, function(val, key) {
        var source = new SourceModel(_.extend({id: key, action: '{{_("Edit")}}'}, val));
        SourcesCollection.add(source);
        $('#setup-sources-list-items').append(_.template($('#template-setup-sources-item').html(), source.attributes));
      });
    });

    return this;
  },
  eventUnconfigured: function(event) {
    // Has Unconfigured Mailboxes (action)
    if (event.data.have_unknown) {
      $('#setup-source-notice-' + event.data.id)
        .html('{{_("You have unconfigured mailboxes")}} {{_("configure them now")}}')
        .fadeIn();

      $('#btn-setup-sources-next').attr('disabled', true);
    } else {
      $('#btn-setup-sources-next').attr('disabled', false);
    }
  },
  eventCopying: function(event) {
    // Various Found or Is downloading
    if (event.data.copying && event.data.copying.running && event.data.copying.total) {
      message = '{{_("Downloading")}} ' + event.data.copying.copied_messages + ' {{_("of")}} ' + event.data.copying.total + ' {{_("messages")}}';
    } else if (event.data.copying && event.data.copying.running) {
      message = '{{_("Found some messages to download")}}';
    } else if (event.data.rescan) {
      message = '{{_("Rescanning mailboxes")}}';
    }
    return message;
  },
  eventConnection: function(event) {

    // Default Message
    var message = event.message;

    // Is IMAP or POP
    if (event.data.connection) {

      // Connection / Behavior (message)
      if (event.data.connection && event.data.connection.live && !event.data.connection.error[0]) {
        message = this.eventCopying(event);
      }
      else if (!event.data.connection.live && !event.data.connection.error[0]) {
        message = '{{_("Not connected to server")}}';
      }
      else if (!event.data.connection.live && event.data.connection.error[0] == 'auth') {
        message =  '{{_("Can not connect to mailserver")}}';
        $('#setup-source-notice-' + event.data.id)
          .html('{{_("The username & password are incorrect")}} {{_("edit them now")}}')
          .fadeIn();
      }
      else if (!event.data.connection.live && event.data.connection.error[0]) {
        message = event.data.connection.error[1];
      }
    }
    else {
      message = this.eventCopying(event);
    }

    // UI Message
    $('#setup-source-message-' + event.data.id).html('' + message + '');
  },
  actionGoToImporting: function(e) {
    e.preventDefault();
    Backbone.history.navigate('#importing', true);
  },
  processDisable: function(e) {
    e.preventDefault();
    var source_id = $(e.target).data('id');
    Mailpile.API.settings_set_post({ _section: source_id, enabled: false }, function(result) {
      $('#setup-source-' + source_id).fadeOut();
    });
  }
});<|endoftext|>


<commit_before><commit_msg>NTP: Hide the notifier when restoring all removed thumbnails.<commit_after><|endoftext|>


<commit_before>/* Set up the environment before loading the rest of the files into Zotero */
var $rdf = {
	Util: {
		ArrayIndexOf: function (arr, item, i) {
			//supported in all browsers except IE<9
			return arr.indexOf(item, i);
		},
		RDFArrayRemove: function (a, x) { //removes all statements equal to x from a
			for (var i = 0; i < a.length; i++) {
				//TODO: This used to be the following, which didnt always work..why
				//if(a[i] == x)
				if (a[i].subject.sameTerm(x.subject) && a[i].predicate.sameTerm(x.predicate) && a[i].object.sameTerm(x.object) && a[i].why.sameTerm(x.why)) {
					a.splice(i, 1);
					return;
				}
			}
			throw "RDFArrayRemove: Array did not contain " + x;
		}
	},
	log: {
		debug: Zotero.debug,
		warn: Zotero.debug
	}
};

if(Zotero.RDF) {
	Zotero.RDF.AJAW = $rdf;
} else {
	Zotero.RDF = {AJAW:$rdf};
}

var tabulator = {log: $rdf.log};
var alert = $rdf.log.warn;<commit_msg>Fix indentation and parse error<commit_after>/* Set up the environment before loading the rest of the files into Zotero */
var $rdf = {
	Util: {
		ArrayIndexOf: function (arr, item, i) {
			//supported in all browsers except IE<9
			return arr.indexOf(item, i);
		},
		RDFArrayRemove: function (a, x) { //removes all statements equal to x from a
			for (var i = 0; i < a.length; i++) {
				//TODO: This used to be the following, which didnt always work..why
				//if(a[i] == x)
				if (a[i].subject.sameTerm(x.subject) && a[i].predicate.sameTerm(x.predicate) && a[i].object.sameTerm(x.object) && a[i].why.sameTerm(x.why)) {
					a.splice(i, 1);
					return;
				}
			}
			throw "RDFArrayRemove: Array did not contain " + x;
		}
	},
	log: {
		debug: Zotero.debug,
		warn: Zotero.debug
	}
};

if(Zotero.RDF) {
	Zotero.RDF.AJAW = $rdf;
} else {
	Zotero.RDF = {AJAW:$rdf};
}

var tabulator = {log: $rdf.log};
var alert = $rdf.log.warn;
<|endoftext|>


<commit_before>if (!process.env.token) {
    console.log('Error: Specify token in environment');
    process.exit(1);
}

require('any-promise/register/q');

var Botkit = require('./lib/Botkit.js'),
    os = require('os'),
    controller = Botkit.slackbot({
        //debug: true
    }),
    bot = controller.spawn({
        token: process.env.token
    }).startRTM(),
    Q = require('q'),
    request = require('request-promise-any');

controller.setupWebserver(process.env.PORT, function(err, webserver) {
  controller.createWebhookEndpoints(controller.webserver, 'PsRh1Hn3lbVjQpYtf3UaLwKH');
});

var games = {},
    suitMappings = {'HEARTS': 'red', 'SPADES': 'green', 'CLUBS': 'yellow', 'DIAMONDS': 'blue'},
    valueMappings = {'JACK': 'Draw 2', 'QUEEN': 'Skip', 'KING': 'Reverse'};

//TODO: Allow for commands via @mentions as well

controller.hears('new', ['slash_command'/*, 'direct_mention', 'mention'*/], function(bot, message){
    console.log(message);
    initializeGame(bot, message);
});

controller.hears('join', ['slash_command'/*, 'direct_mention', 'mention'*/], function(bot, message){
    console.log(message);
    joinGame(bot, message);
});

controller.hears('quit', ['slash_command'/*, 'direct_mention', 'mention'*/], function(bot, message){
    console.log(message);
    quitGame(bot, message);
});

controller.hears('order', ['slash_command'/*, 'direct_mention', 'mention'*/], function(bot, message){
    console.log(message);
    reportTurnOrder(bot, message, true);
});

controller.hears('setup', ['slash_command'/*, 'direct_mention', 'mention'*/], function(bot, message){
    console.log(message);
    for (var i = 2; i <= 2; i++){
        var mockUser = 'Player' + i;

        joinGame(bot, message, mockUser);
    }
});

controller.hears('start', ['slash_command'], function(bot, message){
    console.log(message);
    beginGame(bot, message);
});

function beginGame(bot, message){
    var user = message.user_name,
        game = getGame(bot, message);

    if (!game){
        return;
    }

    if (game.player1 !== user){
        bot.replyPrivate(message, 'Only player 1 (' + game.player1 + ') can start the game.');
        return;
    }

    if (Object.keys(game.players).length < 2){
        bot.replyPrivate(message, 'You need at least two players to begin playing.');
        return;
    }

    if (game.started){
        bot.replyPrivate(message, 'The game is already started.');
        reportTurnOrder(bot, message, true, true);
        return;
    }

    game.started = true;
    var drawRequests = [];

    bot.replyPublic(message, 'Game has started! Shuffling and dealing the hands.');

    //Create the deck
    request({
                uri: 'http://deckofcardsapi.com/api/deck/new/shuffle/?deck_count=2',
                json: true
            })
        .then(function(result){
                game.deckId = result.deck_id;
            })
        .then(function(){
                console.log('Deck request finished');
            })
        .then(function(){
                for (playerName in game.players){
                    console.log('beginning draw for ' + playerName);
                    var player = game.players[playerName];
                    var drawRequest = request({
                                uri: 'http://deckofcardsapi.com/api/deck/' + game.deckId + '/draw/?count=7',
                                json: true
                            })
                        .then(function(result){
                            console.log(result);

                            console.log(result.cards.length + ' cards returned, adding to ' + playerName + ' hand');

                            for (var j = 0; j < result.cards.length; j++){
                                player.cards[j] = getUnoCard(result.cards[j]);
                            }
                        })
                        .then(function(){
                            console.log('Draw request finished');
                            console.log(player);
                        });

                    drawRequests.push(drawRequest);
                }
            })
        .then(function(){
                Q.allSettled(drawRequests).then(function(){
                    console.log('All draw requests should be finished by now.');
                    console.log(game);
                    announceTurn(bot, message);
                })
            });
}

function getUnoCard(standardCard){
    var value = valueMappings[standardCard.value] || (standardCard.value - 1),
        color = suitMappings[standardCard.suit];

    if (value === 'ACE'){
        color = 'Wild';
        switch (standardCard.suit){
            case 'CLUBS':
            case 'SPADES':
                value = 'Wild';
                break;
            case 'HEARTS':
            case 'DIAMONDS':
                value = 'Draw 4';
                break;
        }
    }

    var res = {
        color: color,
        value: value
    };

    console.log('standardCard: ' + standardCard);
    console.log('unoCard: ' + res);

    return res;
}

function getStandardCard(unoCard){

}

function announceTurn(bot, message){
    var game = getGame(bot, message);

    bot.replyPublicDelayed(message, 'It is ' + game.turnOrder[0] + '\'s turn.\nType \\uno cards, \\uno draw, \\uno skip or \\uno play.')
}

function quitGame(bot, message){
    var user = message.user_name,
        game = getGame(bot, message),
        channel = message.channel;

    if (!game.players[user]){
        bot.replyPrivate(message, 'You weren\'t playing to begin with.');
        return;
    }

    delete game.players[user];

    var player = game.turnOrder.indexOf(user);
    game.turnOrder.splice(player, 1);

    bot.replyPublic(message, user + ' has left the game.');

    if (Object.keys(game.players).length === 0){
        bot.replyPublicDelayed(message, 'No more players. Ending the game.');
        games[channel] = newGame();
        return;
    }

    if (game.player1 === user){
        game.player1 = Object.keys(game.players)[0];
        bot.replyPublicDelayed(message, game.player1 + ' is the new player 1.');
    }

    if (Object.keys(game.players).length === 1){
        game.started = false;
        bot.replyPublicDelayed(message, 'Only one player remaining. Waiting for more players.');
    }

    reportTurnOrder(bot, message);
}

function joinGame(bot, message, userName){
    var user = userName || message.user_name,
        channel = message.channel;

    var game = getGame(bot, message);

    if (!game){
        return;
    }

    if (game.players[user]){
        bot.replyPrivate(message, user + ', you\'ve already joined the game!');
        return;
    }

    game.players[user] = {
        hand: []
    };
    game.turnOrder.push(user);

    bot.replyPublic(message, user + ' has joined the game.');

    reportTurnOrder(bot, message);
}

function getGame(bot, message, suppressReport){
    var channel = message.channel;

    if (!games[channel] || !games[channel].initialized){
        if (!suppressReport)
        {
            bot.replyPrivate(message, 'There is no game yet.');
        }
        return undefined;
    }

    return games[channel];
}

function reportTurnOrder(bot, message, isPrivate, isDelayed){
    var game = getGame(bot, message);

    if (!game){
        return;
    }

    var currentOrder = '';

    for (var i = 1; i < game.turnOrder.length + 1; i++){
        if (i > 1){
            currentOrder = currentOrder + ', ';
        }

        currentOrder = currentOrder + '\n' + i + '. ' + game.turnOrder[i - 1];
    }

    if (isPrivate){
        if (isDelayed){
            bot.replyPrivateDelayed(message, 'Current playing order:\n' + currentOrder);
        } else{
            bot.replyPrivate(message, 'Current playing order:\n' + currentOrder);
        }
    }
    else{
        bot.replyPublicDelayed(message, 'Current playing order:\n' + currentOrder);
    }
}

function initializeGame(bot, message){
    var user = message.user_name,
        channel = message.channel;

    var game = getGame(bot, message, true);

    if (!game){
        game = newGame();

        games[channel] = game;
    }

    if (game.initialized){
        bot.replyPrivate(message, 'There is already an uno game in progress. Type !join to join the game.');
        return;
    }

    game = newGame();
    games[channel] = game;

    game.initialized = true;
    game.player1 = user;
    game.players[user] = {
        hand: []
    };
    game.turnOrder.push(user);

    bot.replyPublic(message, user + ' has started UNO. Type !join to join the game.');

    reportTurnOrder(bot, message);
};

function newGame(){
    return {
        initialized: false,
        started: false,
        players: [],
        deckId: '',
        turnOrder: []
    };
}

controller.hears(['uptime', 'identify yourself', 'who are you', 'what is your name'],
    'direct_message,direct_mention,mention', function(bot, message) {

        var hostname = os.hostname();
        var uptime = formatUptime(process.uptime());

        bot.reply(message,
            ':robot_face: I am a bot named <@' + bot.identity.name +
             '>. I have been running for ' + uptime + ' on ' + hostname + '.');

    });

function formatUptime(uptime) {
    var unit = 'second';
    if (uptime > 60) {
        uptime = uptime / 60;
        unit = 'minute';
    }
    if (uptime > 60) {
        uptime = uptime / 60;
        unit = 'hour';
    }
    if (uptime != 1) {
        unit = unit + 's';
    }

    uptime = uptime + ' ' + unit;
    return uptime;
}
<commit_msg>clear up some logging messages<commit_after>if (!process.env.token) {
    console.log('Error: Specify token in environment');
    process.exit(1);
}

require('any-promise/register/q');

var Botkit = require('./lib/Botkit.js'),
    os = require('os'),
    controller = Botkit.slackbot({
        //debug: true
    }),
    bot = controller.spawn({
        token: process.env.token
    }).startRTM(),
    Q = require('q'),
    request = require('request-promise-any');

controller.setupWebserver(process.env.PORT, function(err, webserver) {
  controller.createWebhookEndpoints(controller.webserver, 'PsRh1Hn3lbVjQpYtf3UaLwKH');
});

var games = {},
    suitMappings = {'HEARTS': 'red', 'SPADES': 'green', 'CLUBS': 'yellow', 'DIAMONDS': 'blue'},
    valueMappings = {'JACK': 'Draw 2', 'QUEEN': 'Skip', 'KING': 'Reverse'};

//TODO: Allow for commands via @mentions as well

controller.hears('new', ['slash_command'/*, 'direct_mention', 'mention'*/], function(bot, message){
    //console.log(message);
    initializeGame(bot, message);
});

controller.hears('join', ['slash_command'/*, 'direct_mention', 'mention'*/], function(bot, message){
    console.log(message);
    joinGame(bot, message);
});

controller.hears('quit', ['slash_command'/*, 'direct_mention', 'mention'*/], function(bot, message){
    console.log(message);
    quitGame(bot, message);
});

controller.hears('order', ['slash_command'/*, 'direct_mention', 'mention'*/], function(bot, message){
    console.log(message);
    reportTurnOrder(bot, message, true);
});

controller.hears('setup', ['slash_command'/*, 'direct_mention', 'mention'*/], function(bot, message){
    //console.log(message);
    for (var i = 2; i <= 2; i++){
        var mockUser = 'Player' + i;

        joinGame(bot, message, mockUser);
    }
});

controller.hears('start', ['slash_command'], function(bot, message){
    //console.log(message);
    beginGame(bot, message);
});

function beginGame(bot, message){
    var user = message.user_name,
        game = getGame(bot, message);

    if (!game){
        return;
    }

    if (game.player1 !== user){
        bot.replyPrivate(message, 'Only player 1 (' + game.player1 + ') can start the game.');
        return;
    }

    if (Object.keys(game.players).length < 2){
        bot.replyPrivate(message, 'You need at least two players to begin playing.');
        return;
    }

    if (game.started){
        bot.replyPrivate(message, 'The game is already started.');
        reportTurnOrder(bot, message, true, true);
        return;
    }

    game.started = true;
    var drawRequests = [];

    bot.replyPublic(message, 'Game has started! Shuffling the deck and dealing the hands.');

    //Create the deck
    request({
                uri: 'http://deckofcardsapi.com/api/deck/new/shuffle/?deck_count=2',
                json: true
            })
        .then(function(result){
                game.deckId = result.deck_id;
            })
        /*.then(function(){
                console.log('Deck request finished');
            })*/
        .then(function(){
                for (playerName in game.players){
                    console.log('beginning draw for ' + playerName);
                    var player = game.players[playerName];
                    var drawRequest = request({
                                uri: 'http://deckofcardsapi.com/api/deck/' + game.deckId + '/draw/?count=7',
                                json: true
                            })
                        .then(function(result){
                            console.log(result);

                            console.log(result.cards.length + ' cards returned, adding to ' + playerName + ' hand');

                            for (var j = 0; j < result.cards.length; j++){
                                player.cards.push(getUnoCard(result.cards[j]));
                            }
                        })
                        .then(function(){
                            console.log('Draw request finished');
                            console.log(player);
                        });

                    drawRequests.push(drawRequest);
                }
            })
        .then(function(){
                Q.allSettled(drawRequests).then(function(){
                    console.log('All draw requests should be finished by now.');
                    console.log(game);
                    announceTurn(bot, message);
                })
            });
}

function getUnoCard(standardCard){
    var value = valueMappings[standardCard.value] || (standardCard.value - 1),
        color = suitMappings[standardCard.suit];

    if (value === 'ACE'){
        color = 'Wild';
        switch (standardCard.suit){
            case 'CLUBS':
            case 'SPADES':
                value = 'Wild';
                break;
            case 'HEARTS':
            case 'DIAMONDS':
                value = 'Draw 4';
                break;
        }
    }

    var res = {
        color: color,
        value: value
    };

    console.log('standardCard:');
    console.log(standardCard);
    console.log('unoCard:');
    console.log(res);

    return res;
}

function getStandardCard(unoCard){

}

function announceTurn(bot, message){
    var game = getGame(bot, message);

    bot.replyPublicDelayed(message, 'It is ' + game.turnOrder[0] + '\'s turn.\nType \\uno cards, \\uno draw, \\uno skip or \\uno play.')
}

function quitGame(bot, message){
    var user = message.user_name,
        game = getGame(bot, message),
        channel = message.channel;

    if (!game.players[user]){
        bot.replyPrivate(message, 'You weren\'t playing to begin with.');
        return;
    }

    delete game.players[user];

    var player = game.turnOrder.indexOf(user);
    game.turnOrder.splice(player, 1);

    bot.replyPublic(message, user + ' has left the game.');

    if (Object.keys(game.players).length === 0){
        bot.replyPublicDelayed(message, 'No more players. Ending the game.');
        games[channel] = newGame();
        return;
    }

    if (game.player1 === user){
        game.player1 = Object.keys(game.players)[0];
        bot.replyPublicDelayed(message, game.player1 + ' is the new player 1.');
    }

    if (Object.keys(game.players).length === 1){
        game.started = false;
        bot.replyPublicDelayed(message, 'Only one player remaining. Waiting for more players.');
    }

    reportTurnOrder(bot, message);
}

function joinGame(bot, message, userName){
    var user = userName || message.user_name,
        channel = message.channel;

    var game = getGame(bot, message);

    if (!game){
        return;
    }

    if (game.players[user]){
        bot.replyPrivate(message, user + ', you\'ve already joined the game!');
        return;
    }

    game.players[user] = {
        hand: []
    };
    game.turnOrder.push(user);

    bot.replyPublic(message, user + ' has joined the game.');

    reportTurnOrder(bot, message);
}

function getGame(bot, message, suppressReport){
    var channel = message.channel;

    if (!games[channel] || !games[channel].initialized){
        if (!suppressReport)
        {
            bot.replyPrivate(message, 'There is no game yet.');
        }
        return undefined;
    }

    return games[channel];
}

function reportTurnOrder(bot, message, isPrivate, isDelayed){
    var game = getGame(bot, message);

    if (!game){
        return;
    }

    var currentOrder = '';

    for (var i = 1; i < game.turnOrder.length + 1; i++){
        if (i > 1){
            currentOrder = currentOrder + ', ';
        }

        currentOrder = currentOrder + '\n' + i + '. ' + game.turnOrder[i - 1];
    }

    if (isPrivate){
        if (isDelayed){
            bot.replyPrivateDelayed(message, 'Current playing order:\n' + currentOrder);
        } else{
            bot.replyPrivate(message, 'Current playing order:\n' + currentOrder);
        }
    }
    else{
        bot.replyPublicDelayed(message, 'Current playing order:\n' + currentOrder);
    }
}

function initializeGame(bot, message){
    var user = message.user_name,
        channel = message.channel;

    var game = getGame(bot, message, true);

    if (!game){
        game = newGame();

        games[channel] = game;
    }

    if (game.initialized){
        bot.replyPrivate(message, 'There is already an uno game in progress. Type !join to join the game.');
        return;
    }

    game = newGame();
    games[channel] = game;

    game.initialized = true;
    game.player1 = user;
    game.players[user] = {
        hand: []
    };
    game.turnOrder.push(user);

    bot.replyPublic(message, user + ' has started UNO. Type !join to join the game.');

    reportTurnOrder(bot, message);
};

function newGame(){
    return {
        initialized: false,
        started: false,
        players: [],
        deckId: '',
        turnOrder: []
    };
}

controller.hears(['uptime', 'identify yourself', 'who are you', 'what is your name'],
    'direct_message,direct_mention,mention', function(bot, message) {

        var hostname = os.hostname();
        var uptime = formatUptime(process.uptime());

        bot.reply(message,
            ':robot_face: I am a bot named <@' + bot.identity.name +
             '>. I have been running for ' + uptime + ' on ' + hostname + '.');

    });

function formatUptime(uptime) {
    var unit = 'second';
    if (uptime > 60) {
        uptime = uptime / 60;
        unit = 'minute';
    }
    if (uptime > 60) {
        uptime = uptime / 60;
        unit = 'hour';
    }
    if (uptime != 1) {
        unit = unit + 's';
    }

    uptime = uptime + ' ' + unit;
    return uptime;
}
<|endoftext|>


<commit_before>import { evolve as evolveRamda } from "ramda";

import { add } from "../rambda.js";
import { compareCombinations, compareToRamda } from "./_internals/testUtils";
import { evolve } from "./evolve";

test.only("happy", () => {
  const rules = {
    foo: add(1),
    nested: {
      bar: x => Object.keys(x).length,
    }
  };
  const input = {
    a: 1,
    foo: 2,
    nested: {
      bar: {z: 3},
    }
  };
  const result = evolve(rules, input);
  expect(result).toEqual({
    a: 1,
    foo: 3,
    nested: {
      bar: 1,
    }
  });
});

test("is recursive", () => {
  const rules = {
    nested: {
      second: add(-1),
      third: add(1),
    },
  };
  const object = {
    first: 1,
    nested: {
      second: 2,
      third: 3,
    },
  };
  const expected = {
    first: 1,
    nested: {
      second: 1,
      third: 4,
    },
  };
  const result = evolve(rules, object);
  expect(result).toEqual(expected);
});

test("ignores primitive value rulesormations", () => {
  const rules = {
    n: 2,
    m: "foo",
  };
  const object = {
    n: 0,
    m: 1,
  };
  const expected = {
    n: 0,
    m: 1,
  };
  const result = evolve(rules, object);
  expect(result).toEqual(expected);
});

test("with array", () => {
  const rules = [add(1), add(-1)];
  const list = [100, 1400];
  const expected = [101, 1399];
  const result = evolve(rules, list);
  expect(result).toEqual(expected);
});

const rulesObject = { a: add(1) };
const rulesList = [add(1)];
const possibleIterables = [null, undefined, "", 42, [], [1], { a: 1 }];
const possibleRules = [...possibleIterables, rulesList, rulesObject];

describe("brute force", () => {
  compareCombinations({
    firstInput: possibleRules,
    callback: (errorsCounters) => {
      expect(errorsCounters).toMatchInlineSnapshot(`
        Object {
          "ERRORS_MESSAGE_MISMATCH": 0,
          "ERRORS_TYPE_MISMATCH": 4,
          "RESULTS_MISMATCH": 0,
          "SHOULD_NOT_THROW": 51,
          "SHOULD_THROW": 0,
        }
      `);
    },
    secondInput: possibleIterables,
    fn: evolve,
    fnRamda: evolveRamda,
  });
});
<commit_msg>test: r.evolve when nested rule is wrong<commit_after>import { evolve as evolveRamda } from "ramda";

import { add } from "../rambda.js";
import { compareCombinations, compareToRamda } from "./_internals/testUtils";
import { evolve } from "./evolve";

test("happy", () => {
  const rules = {
    foo: add(1),
    nested: {
      bar: x => Object.keys(x).length,
    }
  };
  const input = {
    a: 1,
    foo: 2,
    nested: {
      bar: {z: 3},
    }
  };
  const result = evolve(rules, input);
  expect(result).toEqual({
    a: 1,
    foo: 3,
    nested: {
      bar: 1,
    }
  });
});

test("nested rule is wrong", () => {
  const rules = {
    foo: add(1),
    nested: {
      bar: 10,
    }
  };
  const input = {
    a: 1,
    foo: 2,
    nested: {
      bar: {z: 3},
    }
  };
  const result = evolve(rules)(input);
  expect(result).toEqual({
    a: 1,
    foo: 3,
    nested: {
      bar: {z: 3},
    }
  });
});

test("is recursive", () => {
  const rules = {
    nested: {
      second: add(-1),
      third: add(1),
    },
  };
  const object = {
    first: 1,
    nested: {
      second: 2,
      third: 3,
    },
  };
  const expected = {
    first: 1,
    nested: {
      second: 1,
      third: 4,
    },
  };
  const result = evolve(rules, object);
  expect(result).toEqual(expected);
});

test("ignores primitive values", () => {
  const rules = {
    n: 2,
    m: "foo",
  };
  const object = {
    n: 0,
    m: 1,
  };
  const expected = {
    n: 0,
    m: 1,
  };
  const result = evolve(rules, object);
  expect(result).toEqual(expected);
});

test("with array", () => {
  const rules = [add(1), add(-1)];
  const list = [100, 1400];
  const expected = [101, 1399];
  const result = evolve(rules, list);
  expect(result).toEqual(expected);
});

const rulesObject = { a: add(1) };
const rulesList = [add(1)];
const possibleIterables = [null, undefined, "", 42, [], [1], { a: 1 }];
const possibleRules = [...possibleIterables, rulesList, rulesObject];

describe("brute force", () => {
  compareCombinations({
    firstInput: possibleRules,
    callback: (errorsCounters) => {
      expect(errorsCounters).toMatchInlineSnapshot(`
        Object {
          "ERRORS_MESSAGE_MISMATCH": 0,
          "ERRORS_TYPE_MISMATCH": 4,
          "RESULTS_MISMATCH": 0,
          "SHOULD_NOT_THROW": 51,
          "SHOULD_THROW": 0,
        }
      `);
    },
    secondInput: possibleIterables,
    fn: evolve,
    fnRamda: evolveRamda,
  });
});
<|endoftext|>


<commit_before>/**
 * @scope enchant.CanvasLayer.prototype
 */
enchant.CanvasLayer = enchant.Class.create(enchant.Group, {
    /**
     * @name enchant.CanvasLayer
     * @class
     [lang:ja]
     * Canvas を用いた描画を行うクラス.
     * 子を Canvas を用いた描画に切り替えるクラス.
     [/lang]
     [lang:en]
     * A class which is using HTML Canvas for the rendering.
     * The rendering of children will be replaced by the Canvas rendering.
     [/lang]
     [lang:de]
     * Eine Klasse die HTML Canvas für das Rendern nutzt.
     * Das Rendern der Kinder wird durch das Canvas Rendering ersetzt.
     [/lang]
     * @constructs
     * @extends enchant.Group
     */
    initialize: function() {
        var core = enchant.Core.instance;

        enchant.Group.call(this);

        this._cvsCache = {
            matrix: [1, 0, 0, 1, 0, 0],
            detectColor: '#000000'
        };
        this._cvsCache.layer = this;

        this._element = document.createElement('canvas');
        this._element.style.position = 'absolute';
        // issue 179
        this._element.style.left = this._element.style.top = '0px';

        this._detect = document.createElement('canvas');
        this._detect.style.position = 'absolute';
        this._lastDetected = 0;

        this.context = this._element.getContext('2d');
        this._dctx = this._detect.getContext('2d');

        this._colorManager = new enchant.DetectColorManager(16, 256);

        this.width = core.width;
        this.height = core.height;

        var touch = [
            enchant.Event.TOUCH_START,
            enchant.Event.TOUCH_MOVE,
            enchant.Event.TOUCH_END
        ];

        touch.forEach(function(type) {
            this.addEventListener(type, function(e) {
                if (this._scene) {
                    this._scene.dispatchEvent(e);
                }
            });
        }, this);

        var __onchildadded = function(e) {
            var child = e.node;
            var self = e.target;
            var layer;
            if (self instanceof enchant.CanvasLayer) {
                layer = self._scene._layers.Canvas;
            } else {
                layer = self.scene._layers.Canvas;
            }
            enchant.CanvasLayer._attachCache(child, layer, __onchildadded, __onchildremoved);
            var render = new enchant.Event(enchant.Event.RENDER);
            if (self._dirty) {
                self._updateCoordinate();
            }
            child._dirty = true;
            enchant.Matrix.instance.stack.push(self._matrix);
            enchant.CanvasRenderer.instance.render(layer.context, child, render);
            enchant.Matrix.instance.stack.pop(self._matrix);
        };

        var __onchildremoved = function(e) {
            var child = e.node;
            var self = e.target;
            var layer;
            if (self instanceof enchant.CanvasLayer) {
                layer = self._scene._layers.Canvas;
            } else {
                layer = self.scene._layers.Canvas;
            }
            enchant.CanvasLayer._detachCache(child, layer, __onchildadded, __onchildremoved);
        };

        this.addEventListener('childremoved', __onchildremoved);
        this.addEventListener('childadded', __onchildadded);

    },
    /**
     [lang:ja]
     * CanvasLayerの横幅.
     [/lang]
     [lang:en]
     * The width of the CanvasLayer.
     [/lang]
     [lang:de]
     * Die Breite der CanvasLayer.
     [/lang]
     * @type Number
     */
    width: {
        get: function() {
            return this._width;
        },
        set: function(width) {
            this._width = width;
            this._element.width = this._detect.width = width;
        }
    },
    /**
     [lang:ja]
     * CanvasLayerの高さ.
     [/lang]
     [lang:en]
     * The height of the CanvasLayer.
     [/lang]
     [lang:de]
     * Die Höhe der CanvasLayer.
     [/lang]
     * @type Number
     */
    height: {
        get: function() {
            return this._height;
        },
        set: function(height) {
            this._height = height;
            this._element.height = this._detect.height = height;
        }
    },
    addChild: function(node) {
        this.childNodes.push(node);
        node.parentNode = this;
        var childAdded = new enchant.Event('childadded');
        childAdded.node = node;
        childAdded.next = null;
        this.dispatchEvent(childAdded);
        node.dispatchEvent(new enchant.Event('added'));
        if (this.scene) {
            node.scene = this.scene;
            var addedToScene = new enchant.Event('addedtoscene');
            node.dispatchEvent(addedToScene);
        }
    },
    insertBefore: function(node, reference) {
        var i = this.childNodes.indexOf(reference);
        if (i !== -1) {
            this.childNodes.splice(i, 0, node);
            node.parentNode = this;
            var childAdded = new enchant.Event('childadded');
            childAdded.node = node;
            childAdded.next = reference;
            this.dispatchEvent(childAdded);
            node.dispatchEvent(new enchant.Event('added'));
            if (this.scene) {
                node.scene = this.scene;
                var addedToScene = new enchant.Event('addedtoscene');
                node.dispatchEvent(addedToScene);
            }
        } else {
            this.addChild(node);
        }
    },
    /**
     [lang:ja]
     * レンダリングを開始する.
     [/lang]
     [lang:en]
     [/lang]
     [lang:de]
     [/lang]
     * @private
     */
    _startRendering: function() {
        this.addEventListener('exitframe', this._onexitframe);
        this._onexitframe(new enchant.Event(enchant.Event.RENDER));
    },
    /**
     [lang:ja]
     * レンダリングを停止する.
     [/lang]
     [lang:en]
     [/lang]
     [lang:de]
     [/lang]
     * @private
     */
    _stopRendering: function() {
        this.removeEventListener('render', this._onexitframe);
        this._onexitframe(new enchant.Event(enchant.Event.RENDER));
    },
    _onexitframe: function() {
        var core = enchant.Core.instance;
        var ctx = this.context;
        ctx.clearRect(0, 0, core.width, core.height);
        var render = new enchant.Event(enchant.Event.RENDER);
        enchant.CanvasRenderer.instance.render(ctx, this, render);
    },
    _determineEventTarget: function(e) {
        return this._getEntityByPosition(e.x, e.y);
    },
    _getEntityByPosition: function(x, y) {
        var core = enchant.Core.instance;
        var ctx = this._dctx;
        if (this._lastDetected < core.frame) {
            ctx.clearRect(0, 0, this.width, this.height);
            enchant.CanvasRenderer.instance.detectRender(ctx, this);
            this._lastDetected = core.frame;
        }
        var color = ctx.getImageData(x, y, 1, 1).data;
        return this._colorManager.getSpriteByColor(color);
    }
});

enchant.CanvasLayer._attachCache = function(node, layer, onchildadded, onchildremoved) {
    var child;
    if (!node._cvsCache) {
        node._cvsCache = {};
        node._cvsCache.matrix = [ 1, 0, 0, 1, 0, 0 ];
        node._cvsCache.detectColor = 'rgba(' + layer._colorManager.attachDetectColor(node) + ')';
        node.addEventListener('childadded', onchildadded);
        node.addEventListener('childremoved', onchildremoved);
    }
    if (node.childNodes) {
        for (var i = 0, l = node.childNodes.length; i < l; i++) {
            child = node.childNodes[i];
            enchant.CanvasLayer._attachCache(child, layer, onchildadded, onchildremoved);
        }
    }
};

enchant.CanvasLayer._detachCache = function(node, layer, onchildadded, onchildremoved) {
    var child;
    if (node._cvsCache) {
        layer._colorManager.detachDetectColor(node);
        node.removeEventListener('childadded', onchildadded);
        node.removeEventListener('childremoved', onchildremoved);
        delete node._cvsCache;
    }
    if (node.childNodes) {
        for (var i = 0, l = node.childNodes.length; i < l; i++) {
            child = node.childNodes[i];
            enchant.CanvasLayer._detachCache(child, layer, onchildadded, onchildremoved);
        }
    }
};
<commit_msg>remove unused code<commit_after>/**
 * @scope enchant.CanvasLayer.prototype
 */
enchant.CanvasLayer = enchant.Class.create(enchant.Group, {
    /**
     * @name enchant.CanvasLayer
     * @class
     [lang:ja]
     * Canvas を用いた描画を行うクラス.
     * 子を Canvas を用いた描画に切り替えるクラス.
     [/lang]
     [lang:en]
     * A class which is using HTML Canvas for the rendering.
     * The rendering of children will be replaced by the Canvas rendering.
     [/lang]
     [lang:de]
     * Eine Klasse die HTML Canvas für das Rendern nutzt.
     * Das Rendern der Kinder wird durch das Canvas Rendering ersetzt.
     [/lang]
     * @constructs
     * @extends enchant.Group
     */
    initialize: function() {
        var core = enchant.Core.instance;

        enchant.Group.call(this);

        this._cvsCache = {
            matrix: [1, 0, 0, 1, 0, 0],
            detectColor: '#000000'
        };
        this._cvsCache.layer = this;

        this._element = document.createElement('canvas');
        this._element.style.position = 'absolute';
        // issue 179
        this._element.style.left = this._element.style.top = '0px';

        this._detect = document.createElement('canvas');
        this._detect.style.position = 'absolute';
        this._lastDetected = 0;

        this.context = this._element.getContext('2d');
        this._dctx = this._detect.getContext('2d');

        this._colorManager = new enchant.DetectColorManager(16, 256);

        this.width = core.width;
        this.height = core.height;

        var touch = [
            enchant.Event.TOUCH_START,
            enchant.Event.TOUCH_MOVE,
            enchant.Event.TOUCH_END
        ];

        touch.forEach(function(type) {
            this.addEventListener(type, function(e) {
                if (this._scene) {
                    this._scene.dispatchEvent(e);
                }
            });
        }, this);

        var __onchildadded = function(e) {
            var child = e.node;
            var self = e.target;
            var layer;
            if (self instanceof enchant.CanvasLayer) {
                layer = self._scene._layers.Canvas;
            } else {
                layer = self.scene._layers.Canvas;
            }
            enchant.CanvasLayer._attachCache(child, layer, __onchildadded, __onchildremoved);
            var render = new enchant.Event(enchant.Event.RENDER);
            if (self._dirty) {
                self._updateCoordinate();
            }
            child._dirty = true;
            enchant.Matrix.instance.stack.push(self._matrix);
            enchant.CanvasRenderer.instance.render(layer.context, child, render);
            enchant.Matrix.instance.stack.pop(self._matrix);
        };

        var __onchildremoved = function(e) {
            var child = e.node;
            var self = e.target;
            var layer;
            if (self instanceof enchant.CanvasLayer) {
                layer = self._scene._layers.Canvas;
            } else {
                layer = self.scene._layers.Canvas;
            }
            enchant.CanvasLayer._detachCache(child, layer, __onchildadded, __onchildremoved);
        };

        this.addEventListener('childremoved', __onchildremoved);
        this.addEventListener('childadded', __onchildadded);

    },
    /**
     [lang:ja]
     * CanvasLayerの横幅.
     [/lang]
     [lang:en]
     * The width of the CanvasLayer.
     [/lang]
     [lang:de]
     * Die Breite der CanvasLayer.
     [/lang]
     * @type Number
     */
    width: {
        get: function() {
            return this._width;
        },
        set: function(width) {
            this._width = width;
            this._element.width = this._detect.width = width;
        }
    },
    /**
     [lang:ja]
     * CanvasLayerの高さ.
     [/lang]
     [lang:en]
     * The height of the CanvasLayer.
     [/lang]
     [lang:de]
     * Die Höhe der CanvasLayer.
     [/lang]
     * @type Number
     */
    height: {
        get: function() {
            return this._height;
        },
        set: function(height) {
            this._height = height;
            this._element.height = this._detect.height = height;
        }
    },
    addChild: function(node) {
        this.childNodes.push(node);
        node.parentNode = this;
        var childAdded = new enchant.Event('childadded');
        childAdded.node = node;
        childAdded.next = null;
        this.dispatchEvent(childAdded);
        node.dispatchEvent(new enchant.Event('added'));
    },
    insertBefore: function(node, reference) {
        var i = this.childNodes.indexOf(reference);
        if (i !== -1) {
            this.childNodes.splice(i, 0, node);
            node.parentNode = this;
            var childAdded = new enchant.Event('childadded');
            childAdded.node = node;
            childAdded.next = reference;
            this.dispatchEvent(childAdded);
            node.dispatchEvent(new enchant.Event('added'));
        } else {
            this.addChild(node);
        }
    },
    /**
     [lang:ja]
     * レンダリングを開始する.
     [/lang]
     [lang:en]
     [/lang]
     [lang:de]
     [/lang]
     * @private
     */
    _startRendering: function() {
        this.addEventListener('exitframe', this._onexitframe);
        this._onexitframe(new enchant.Event(enchant.Event.RENDER));
    },
    /**
     [lang:ja]
     * レンダリングを停止する.
     [/lang]
     [lang:en]
     [/lang]
     [lang:de]
     [/lang]
     * @private
     */
    _stopRendering: function() {
        this.removeEventListener('render', this._onexitframe);
        this._onexitframe(new enchant.Event(enchant.Event.RENDER));
    },
    _onexitframe: function() {
        var core = enchant.Core.instance;
        var ctx = this.context;
        ctx.clearRect(0, 0, core.width, core.height);
        var render = new enchant.Event(enchant.Event.RENDER);
        enchant.CanvasRenderer.instance.render(ctx, this, render);
    },
    _determineEventTarget: function(e) {
        return this._getEntityByPosition(e.x, e.y);
    },
    _getEntityByPosition: function(x, y) {
        var core = enchant.Core.instance;
        var ctx = this._dctx;
        if (this._lastDetected < core.frame) {
            ctx.clearRect(0, 0, this.width, this.height);
            enchant.CanvasRenderer.instance.detectRender(ctx, this);
            this._lastDetected = core.frame;
        }
        var color = ctx.getImageData(x, y, 1, 1).data;
        return this._colorManager.getSpriteByColor(color);
    }
});

enchant.CanvasLayer._attachCache = function(node, layer, onchildadded, onchildremoved) {
    var child;
    if (!node._cvsCache) {
        node._cvsCache = {};
        node._cvsCache.matrix = [ 1, 0, 0, 1, 0, 0 ];
        node._cvsCache.detectColor = 'rgba(' + layer._colorManager.attachDetectColor(node) + ')';
        node.addEventListener('childadded', onchildadded);
        node.addEventListener('childremoved', onchildremoved);
    }
    if (node.childNodes) {
        for (var i = 0, l = node.childNodes.length; i < l; i++) {
            child = node.childNodes[i];
            enchant.CanvasLayer._attachCache(child, layer, onchildadded, onchildremoved);
        }
    }
};

enchant.CanvasLayer._detachCache = function(node, layer, onchildadded, onchildremoved) {
    var child;
    if (node._cvsCache) {
        layer._colorManager.detachDetectColor(node);
        node.removeEventListener('childadded', onchildadded);
        node.removeEventListener('childremoved', onchildremoved);
        delete node._cvsCache;
    }
    if (node.childNodes) {
        for (var i = 0, l = node.childNodes.length; i < l; i++) {
            child = node.childNodes[i];
            enchant.CanvasLayer._detachCache(child, layer, onchildadded, onchildremoved);
        }
    }
};
<|endoftext|>


<commit_before>/**
 * typed-function
 *
 * Type checking for JavaScript functions
 *
 * https://github.com/josdejong/typed-function
 */
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], factory);
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals (root is window)
    root.typed = factory();
  }
}(this, function () {
  'use strict';

  // order types
  // anytype (*) will be ordered last, and then object, as other types may be
  // an object too.
  function compareTypes(a, b) {
    if (a === '*') return 1;
    if (b === '*') return -1;

    if (a === 'Object') return 1;
    if (b === 'Object') return -1;

    return 0;
  }

  // order numbers
  function compareNumbers(a, b) {
    return a > b;
  }

  /**
   * Collection with function definitions (local shortcuts to functions)
   * @constructor
   */
  function Defs() {}

  /**
   * Add a function definition.
   * @param {function} fn
   * @param {string} [type='fn']
   * @returns {string} Returns the function name, for example 'fn0' or 'signature2'
   */
  Defs.prototype.add = function (fn, type) {
    type = type || 'fn';
    if (!this[type]) this[type] = [];

    var index = this[type].indexOf(fn);
    if (index == -1) {
      index = this[type].length;
      this[type].push(fn);
    }
    return type + index;
  };

  /**
   * Create code lines for all definitions
   * @param [name='defs']
   * @returns {Array} Returns the code lines containing all function definitions
   */
  Defs.prototype.code = function (name) {
    var me = this;
    var code = [];
    name = name || 'defs';

    Object.keys(this).forEach(function (type) {
      var def = me[type];
      def.forEach(function (def, index) {
        code.push('var ' + type + index + ' = ' + name + '[\'' + type + '\'][' + index + '];');
      });
    });

    return code;
  };

  /**
   * A function signature
   * @param {string | Array.<string>} params  Array with the type(s) of each parameter,
   *                                          or a comma separated string with types
   * @param {function} fn                     The actual function
   * @constructor
   */
  function Signature(params, fn) {
    if (typeof params === 'string') {
      this.params = (params !== '') ? params.split(',').map(function (param) {
        return param.trim();
      }) : [];
    }
    else {
      this.params = params;
    }
    this.fn = fn;
  }

  // TODO: implement function Signature.split
  // TODO: implement function Signature.merge
  // TODO: implement function Signature.toString

  /**
   * split all raw signatures into an array with splitted params
   * @param {Object.<string, function>} rawSignatures
   * @return {Array.<{params: Array.<string>, fn: function}>} Returns splitted signatures
   */
  function splitSignatures(rawSignatures) {
    return Object.keys(rawSignatures).map(function (params) {
      var fn = rawSignatures[params];
      return new Signature(params, fn);
    });

    // TODO: split params containing an '|' into multiple entries
  }

  /**
   * create a map with normalized signatures as key and the function as value
   * @param {Array.<{params: Array.<string>, fn: function}>} signatures   An array with splitted signatures
   * @return {{}} Returns a map with normalized signatures
   */
  function normalizeSignatures(signatures) {
    var normalized = {};

    signatures.map(function (entry) {
      var signature = entry.params.join(',');
      if (signature in normalized) {
        throw new Error('Error: signature "' + signature + '" defined twice');
      }
      normalized[signature] = entry.fn;
    });

    return normalized
  }

  /**
   * create an array with for every parameter an array with possible types
   * @param {Array.<{params: Array.<string>, fn: function}>} signatures   An array with splitted signatures
   * @return {Array.<Array.<string>>} Returns an array with allowed types per parameter
   */
  function splitTypes(signatures) {
    var types = [];

    signatures.forEach(function (entry) {
      entry.params.forEach(function (param, i) {
        if (!types[i]) {
          types[i] = [];
        }
        if (types[i].indexOf(param) == -1) {
          types[i].push(param);
        }
      });
    });

    return types;
  }

  /**
   * create a recursive tree for traversing the number and type of parameters
   * @param {Array.<{params: Array.<string>, fn: function}>} signatures   An array with splitted signatures
   * @returns {{}}
   */
  function createParamsTree(signatures) {
    var tree = {};

    signatures.forEach(function (entry) {
      var params = entry.params.concat([]);

      // get the tree entry for the current number of arguments
      var obj = tree[params.length];
      if (!obj) {
        obj = tree[params.length] = {
          signature: [],
          fn: null,
          types: {}
        };
      }

      // loop over all parameters, create a nested structure
      while(params.length > 0) {
        var param = params.shift();
        if (!obj.types[param]) {
          obj.types[param] = {
            signature: obj.signature.concat(param),
            fn: null,
            types: {}
          };
        }
        obj = obj.types[param];
      }

      // add the function as leaf
      obj.fn = entry.fn;
    });

    return tree;
  }

  /**
   * Compose a function from sub-functions each handling a single type signature.
   * Signatures:
   *   typed(signature: string, fn: function)
   *   typed(name: string, signature: string, fn: function)
   *   typed(signatures: Object.<string, function>)
   *   typed(name: string, signatures: Object.<string, function>)
   *
   * @param {string | null} name
   * @param {Object.<string, function>} signatures
   * @return {function} Returns the typed function
   * @private
   */
  function _typed(name, signatures) {
    var defs = new Defs();
    var structure = splitSignatures(signatures);

    function switchTypes(signature, args, prefix) {
      var code = [];

      if (signature.fn !== null) {
        var def = defs.add(signature.fn, 'signature');
        code.push(prefix + 'return ' + def + '(' + args.join(', ') +'); // signature: ' + signature.signature);
      }
      else {
        // add entries for the provided types
        Object.keys(signature.types)
            .sort(compareTypes)
            .forEach(function (type, index) {
              var arg = 'arg' + args.length;

              var before;
              var after;
              var nextPrefix = prefix + '  ';
              if (type == '*') {
                before = (index > 0 ? 'else {' : '');
                after  = (index > 0 ? '}' : '');
                if (index == 0) {nextPrefix = prefix;}
              }
              else {
                var def = defs.add(getTest(type), 'test') + '(' + arg + ')';
                before = 'if (' + def + ') { // type: ' + type;
                after  = '}';
              }

              if (before) code.push(prefix + before);
              code = code.concat(switchTypes(signature.types[type], args.concat(arg), nextPrefix));
              if (after) code.push(prefix + after);
            });

        // add entries for type conversions
        var added = {};
        typed.conversions
            .filter(function (conversion) {
              return signature.types[conversion.to] &&
                  !signature.types[conversion.from];
            })
            .forEach(function (conversion) {
              if (!added[conversion.from]) {
                added[conversion.from] = true;

                var arg = 'arg' + args.length;
                var test = defs.add(getTest(conversion.from), 'test') + '(' + arg + ')';
                var convert = defs.add(conversion.convert, 'convert') + '(' + arg + ')';

                code.push(prefix + 'if (' + test + ') { // type: ' + conversion.from + ', convert to ' + conversion.to);
                code = code.concat(switchTypes(signature.types[conversion.to], args.concat(convert), prefix + '  '));
                code.push(prefix + '}');
              }
            });
      }

      return code;
    }

    var types = splitTypes(structure);
    var params = [];
    for (var i = 0; i < types.length; i++) { // we can't use .map here, some entries may be undefined
      params.push('arg' + i);
    }

    var code = [];
    var tree = createParamsTree(structure);
    var paramCounts = Object.keys(tree);
    code.push('return function ' + (name || '') + '(' + params.join(', ') + ') {');
    paramCounts
        .sort(compareNumbers)
        .forEach(function (count, index) {
          var signature = tree[count];
          var args = [];
          var statement = (index == 0) ? 'if' : 'else if';
          code.push('  ' + statement + ' (arguments.length == ' + count +  ') {');
          code = code.concat(switchTypes(signature, args, '    '));

          code.push('  }');
          if (index == paramCounts.length - 1) {
            code.push('  else {');
            code.push('    throw new TypeError(\'Wrong number of arguments\');'); // TODO: output the allowed numbers
            code.push('  }');
          }
        });
    code.push('  throw new TypeError(\'Wrong function signature\');');  // TODO: output the actual signature
    code.push('}');

    var factory = [];
    factory.push('(function (defs) {');
    factory = factory.concat(defs.code('defs'));
    factory = factory.concat(code);
    factory.push('})');

    var fn = eval(factory.join('\n'))(defs);

    // attach the signatures with sub-functions to the constructed function
    fn.signatures = normalizeSignatures(structure); // normalized signatures

    return fn;
  }

  // data type tests
  var types = {
    'null':     function (x) {return x === null},
    'boolean':  function (x) {return typeof x === 'boolean'},
    'number':   function (x) {return typeof x === 'number'},
    'string':   function (x) {return typeof x === 'string'},
    'function': function (x) {return typeof x === 'function'},
    'Array':    function (x) {return Array.isArray(x)},
    'Date':     function (x) {return x instanceof Date},
    'RegExp':   function (x) {return x instanceof RegExp},
    'Object':   function (x) {return typeof x === 'object'}
  };

  // type conversions
  // order is important
  var conversions = [];

  function getTest(type) {
    var test = typed.types[type];
    if (!test) {
      var matches = Object.keys(typed.types)
          .filter(function (t) {
            return t.toLowerCase() == type.toLowerCase();
          })
          .map(function (t) {
            return '"' + t + '"';
          });
      throw new Error('Unknown type "' + type + '"' +
      (matches.length ? ('. Did you mean ' + matches.join(', or ') + '?') : ''));
    }
    return test;
  }

  // temporary object for holding types and conversions, for constructing
  // the `typed` function itself
  // TODO: find a more elegant solution for this
  var typed = {
    types: types,
    conversions: conversions
  };

  /**
   * Construct the typed function itself with various signatures
   *
   * Signatures:
   *
   *   typed(signature: string, fn: function)
   *   typed(name: string, signature: string, fn: function)
   *   typed(signatures: Object.<string, function>)
   *   typed(name: string, signatures: Object.<string, function>)
   */
  typed = _typed('typed', {
    'Object': function (signatures) {
      return _typed(null, signatures);
    },
    'string, Object': _typed,
    'string, function': function (signature, fn) {
      var signatures = {};
      signatures[signature] = fn;
      return _typed(null, signatures);
    },
    'string, string, function': function(name, signature, fn) {
      var signatures = {};
      signatures[signature] = fn;
      return _typed(name, signatures);
    }
  });

  // attach types and conversions to the final `typed` function
  typed.types = types;
  typed.conversions = conversions;

  return typed;
}));

<commit_msg>Minor refactoring<commit_after>/**
 * typed-function
 *
 * Type checking for JavaScript functions
 *
 * https://github.com/josdejong/typed-function
 */
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], factory);
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals (root is window)
    root.typed = factory();
  }
}(this, function () {
  'use strict';

  // order types
  // anytype (*) will be ordered last, and then object, as other types may be
  // an object too.
  function compareTypes(a, b) {
    if (a === '*') return 1;
    if (b === '*') return -1;

    if (a === 'Object') return 1;
    if (b === 'Object') return -1;

    return 0;
  }

  /**
   * Get a type test function for a specific data type
   * @param {string} type                   A data type like 'number' or 'string'
   * @returns {function(obj: *) : boolean}  Returns a type testing function.
   *                                        Throws an error for an unknown type.
   */
  function getTypeTest(type) {
    var test = typed.types[type];
    if (!test) {
      var matches = Object.keys(typed.types)
          .filter(function (t) {
            return t.toLowerCase() == type.toLowerCase();
          })
          .map(function (t) {
            return '"' + t + '"';
          });

      throw new Error('Unknown type "' + type + '"' +
          (matches.length ? ('. Did you mean ' + matches.join(', or ') + '?') : ''));
    }
    return test;
  }

  // order numbers
  function compareNumbers(a, b) {
    return a > b;
  }

  /**
   * Collection with function definitions (local shortcuts to functions)
   * @constructor
   */
  function Defs() {}

  /**
   * Add a function definition.
   * @param {function} fn
   * @param {string} [type='fn']
   * @returns {string} Returns the function name, for example 'fn0' or 'signature2'
   */
  Defs.prototype.add = function (fn, type) {
    type = type || 'fn';
    if (!this[type]) this[type] = [];

    var index = this[type].indexOf(fn);
    if (index == -1) {
      index = this[type].length;
      this[type].push(fn);
    }
    return type + index;
  };

  /**
   * Create code lines for all definitions
   * @param [name='defs']
   * @returns {Array} Returns the code lines containing all function definitions
   */
  Defs.prototype.code = function (name) {
    var me = this;
    var code = [];
    name = name || 'defs';

    Object.keys(this).forEach(function (type) {
      var def = me[type];
      def.forEach(function (def, index) {
        code.push('var ' + type + index + ' = ' + name + '[\'' + type + '\'][' + index + '];');
      });
    });

    return code;
  };

  /**
   * A function signature
   * @param {string | Array.<string>} params  Array with the type(s) of each parameter,
   *                                          or a comma separated string with types
   * @param {function} fn                     The actual function
   * @constructor
   */
  function Signature(params, fn) {
    if (typeof params === 'string') {
      this.params = (params !== '') ? params.split(',').map(function (param) {
        return param.trim();
      }) : [];
    }
    else {
      this.params = params;
    }
    this.fn = fn;
  }

  // TODO: implement function Signature.split
  // TODO: implement function Signature.merge
  // TODO: implement function Signature.toString

  /**
   * split all raw signatures into an array with splitted params
   * @param {Object.<string, function>} rawSignatures
   * @return {Array.<{params: Array.<string>, fn: function}>} Returns splitted signatures
   */
  function splitSignatures(rawSignatures) {
    return Object.keys(rawSignatures).map(function (params) {
      var fn = rawSignatures[params];
      return new Signature(params, fn);
    });

    // TODO: split params containing an '|' into multiple entries
  }

  /**
   * create a map with normalized signatures as key and the function as value
   * @param {Array.<{params: Array.<string>, fn: function}>} signatures   An array with splitted signatures
   * @return {{}} Returns a map with normalized signatures
   */
  function normalizeSignatures(signatures) {
    var normalized = {};

    signatures.map(function (entry) {
      var signature = entry.params.join(',');
      if (signature in normalized) {
        throw new Error('Error: signature "' + signature + '" defined twice');
      }
      normalized[signature] = entry.fn;
    });

    return normalized
  }

  /**
   * create an array with for every parameter an array with possible types
   * @param {Array.<{params: Array.<string>, fn: function}>} signatures   An array with splitted signatures
   * @return {Array.<Array.<string>>} Returns an array with allowed types per parameter
   */
  function splitTypes(signatures) {
    var types = [];

    signatures.forEach(function (entry) {
      entry.params.forEach(function (param, i) {
        if (!types[i]) {
          types[i] = [];
        }
        if (types[i].indexOf(param) == -1) {
          types[i].push(param);
        }
      });
    });

    return types;
  }

  /**
   * create a recursive tree for traversing the number and type of parameters
   * @param {Array.<{params: Array.<string>, fn: function}>} signatures   An array with splitted signatures
   * @returns {{}}
   */
  function createParamsTree(signatures) {
    var tree = {};

    signatures.forEach(function (entry) {
      var params = entry.params.concat([]);

      // get the tree entry for the current number of arguments
      var obj = tree[params.length];
      if (!obj) {
        obj = tree[params.length] = {
          signature: [],
          fn: null,
          types: {}
        };
      }

      // loop over all parameters, create a nested structure
      while(params.length > 0) {
        var param = params.shift();
        if (!obj.types[param]) {
          obj.types[param] = {
            signature: obj.signature.concat(param),
            fn: null,
            types: {}
          };
        }
        obj = obj.types[param];
      }

      // add the function as leaf
      obj.fn = entry.fn;
    });

    return tree;
  }

  /**
   * Compose a function from sub-functions each handling a single type signature.
   * Signatures:
   *   typed(signature: string, fn: function)
   *   typed(name: string, signature: string, fn: function)
   *   typed(signatures: Object.<string, function>)
   *   typed(name: string, signatures: Object.<string, function>)
   *
   * @param {string | null} name
   * @param {Object.<string, function>} signatures
   * @return {function} Returns the typed function
   * @private
   */
  function _typed(name, signatures) {
    var defs = new Defs();
    var structure = splitSignatures(signatures);

    function switchTypes(signature, args, prefix) {
      var code = [];

      if (signature.fn !== null) {
        var def = defs.add(signature.fn, 'signature');
        code.push(prefix + 'return ' + def + '(' + args.join(', ') +'); // signature: ' + signature.signature);
      }
      else {
        // add entries for the provided types
        Object.keys(signature.types)
            .sort(compareTypes)
            .forEach(function (type, index) {
              var arg = 'arg' + args.length;

              var before;
              var after;
              var nextPrefix = prefix + '  ';
              if (type == '*') {
                before = (index > 0 ? 'else {' : '');
                after  = (index > 0 ? '}' : '');
                if (index == 0) {nextPrefix = prefix;}
              }
              else {
                var def = defs.add(getTypeTest(type), 'test') + '(' + arg + ')';
                before = 'if (' + def + ') { // type: ' + type;
                after  = '}';
              }

              if (before) code.push(prefix + before);
              code = code.concat(switchTypes(signature.types[type], args.concat(arg), nextPrefix));
              if (after) code.push(prefix + after);
            });

        // add entries for type conversions
        var added = {};
        typed.conversions
            .filter(function (conversion) {
              return signature.types[conversion.to] &&
                  !signature.types[conversion.from];
            })
            .forEach(function (conversion) {
              if (!added[conversion.from]) {
                added[conversion.from] = true;

                var arg = 'arg' + args.length;
                var test = defs.add(getTypeTest(conversion.from), 'test') + '(' + arg + ')';
                var convert = defs.add(conversion.convert, 'convert') + '(' + arg + ')';

                code.push(prefix + 'if (' + test + ') { // type: ' + conversion.from + ', convert to ' + conversion.to);
                code = code.concat(switchTypes(signature.types[conversion.to], args.concat(convert), prefix + '  '));
                code.push(prefix + '}');
              }
            });
      }

      return code;
    }

    var types = splitTypes(structure);
    var params = [];
    for (var i = 0; i < types.length; i++) { // we can't use .map here, some entries may be undefined
      params.push('arg' + i);
    }

    var code = [];
    var tree = createParamsTree(structure);
    var paramCounts = Object.keys(tree);
    code.push('return function ' + (name || '') + '(' + params.join(', ') + ') {');
    paramCounts
        .sort(compareNumbers)
        .forEach(function (count, index) {
          var signature = tree[count];
          var args = [];
          var statement = (index == 0) ? 'if' : 'else if';
          code.push('  ' + statement + ' (arguments.length == ' + count +  ') {');
          code = code.concat(switchTypes(signature, args, '    '));

          code.push('  }');
          if (index == paramCounts.length - 1) {
            code.push('  else {');
            code.push('    throw new TypeError(\'Wrong number of arguments\');'); // TODO: output the allowed numbers
            code.push('  }');
          }
        });
    code.push('  throw new TypeError(\'Wrong function signature\');');  // TODO: output the actual signature
    code.push('}');

    var factory = [];
    factory.push('(function (defs) {');
    factory = factory.concat(defs.code('defs'));
    factory = factory.concat(code);
    factory.push('})');

    var fn = eval(factory.join('\n'))(defs);

    // attach the signatures with sub-functions to the constructed function
    fn.signatures = normalizeSignatures(structure); // normalized signatures

    return fn;
  }

  // data type tests
  var types = {
    'null':     function (x) {return x === null},
    'boolean':  function (x) {return typeof x === 'boolean'},
    'number':   function (x) {return typeof x === 'number'},
    'string':   function (x) {return typeof x === 'string'},
    'function': function (x) {return typeof x === 'function'},
    'Array':    function (x) {return Array.isArray(x)},
    'Date':     function (x) {return x instanceof Date},
    'RegExp':   function (x) {return x instanceof RegExp},
    'Object':   function (x) {return typeof x === 'object'}
  };

  // type conversions. Order is important
  var conversions = [];

  // temporary object for holding types and conversions, for constructing
  // the `typed` function itself
  // TODO: find a more elegant solution for this
  var typed = {
    types: types,
    conversions: conversions
  };

  /**
   * Construct the typed function itself with various signatures
   *
   * Signatures:
   *
   *   typed(signature: string, fn: function)
   *   typed(name: string, signature: string, fn: function)
   *   typed(signatures: Object.<string, function>)
   *   typed(name: string, signatures: Object.<string, function>)
   */
  typed = _typed('typed', {
    'Object': function (signatures) {
      return _typed(null, signatures);
    },
    'string, Object': _typed,
    'string, function': function (signature, fn) {
      var signatures = {};
      signatures[signature] = fn;
      return _typed(null, signatures);
    },
    'string, string, function': function(name, signature, fn) {
      var signatures = {};
      signatures[signature] = fn;
      return _typed(name, signatures);
    }
  });

  // attach types and conversions to the final `typed` function
  typed.types = types;
  typed.conversions = conversions;

  return typed;
}));

<|endoftext|>


<commit_before>'use strict';

//
// Implements mongodb data source.
//

module.exports = function (config) {

	var fs = require('fs');
	var assert = require('chai').assert;
	var E = require('linq');
	var pmongo = require('promised-mongo');

	var host = config.host || 'localhost';
	var collection;
	var connectionString = host + '/' + config.db;
	var query = config.query || {};
	var fields = config.fields || {};

	if (Object.isString(config)) {
		host = config.host || 'localhost';
		var connectionStringParts = config.split('/');
		assert(connectionStringParts.length === 3, "Expected 'config' parameter to 'mongo data source' to be a connection string composed of 3 parts or a config object. Connection string format: <host>/<db>/<collection-name>");

		connectionString = connectionStringParts[0] + '/' + connectionStringParts[1];
		collection = connectionStringParts[2];

		query = {};
		fields = {};
	}
	else {
		assert.isObject(config, "Expected 'config' parameter to 'mongo data source' to be an object.");
		assert.isString(config.db, "Expected 'config.db' parameter to 'mongo data source' to be a string.");
		assert.isString(config.collection, "Expected 'config.collection' parameter to 'mongo data source' to be a string.");

		host = config.host || 'localhost';
		connectionString = host + '/' + config.db;
		collection = config.collection;
		query = config.query || {};
		fields = config.fields || {};
	}

	return {

		//
		// Write to mongodb.
		//
		read: function () {

			var db = pmongo(connectionString, [collection]);
			return db[collection]
				.find(query, fields)
				.toArray()
				.then(function (docs) {
					db.close();
					return docs;
				});
		},

		//
		// Read from monogdb.
		//
		write: function (documents) {
			assert.isArray(documents, "Expected 'documents' parameter to 'mongo.write' to be an array.");

			var db = pmongo(connectionString, [collection]);
			return E.from(documents)
				.aggregate(Promise.resolve(), function (prevSavePromise, document) {
					return prevSavePromise.then(function () {
						return db[collection].save(document);
					});
				})
				.then(function () {
					db.close();
				});
		},
	};
};

<commit_msg>Temporary fixes to mongo plugin after recent refactoring.<commit_after>'use strict';

//
// Implements mongodb data source.
//

module.exports = function (config) {

	var dataForge = require("../../index.js");

	var fs = require('fs');
	var assert = require('chai').assert;
	var E = require('linq');
	var pmongo = require('promised-mongo');

	var host = config.host || 'localhost';
	var collection;
	var connectionString = host + '/' + config.db;
	var query = config.query || {};
	var fields = config.fields || {};

	if (Object.isString(config)) {
		host = config.host || 'localhost';
		var connectionStringParts = config.split('/');
		assert(connectionStringParts.length === 3, "Expected 'config' parameter to 'mongo data source' to be a connection string composed of 3 parts or a config object. Connection string format: <host>/<db>/<collection-name>");

		connectionString = connectionStringParts[0] + '/' + connectionStringParts[1];
		collection = connectionStringParts[2];

		query = {};
		fields = {};
	}
	else {
		assert.isObject(config, "Expected 'config' parameter to 'mongo data source' to be an object.");
		assert.isString(config.db, "Expected 'config.db' parameter to 'mongo data source' to be a string.");
		assert.isString(config.collection, "Expected 'config.collection' parameter to 'mongo data source' to be a string.");

		host = config.host || 'localhost';
		connectionString = host + '/' + config.db;
		collection = config.collection;
		query = config.query || {};
		fields = config.fields || {};
	}

	return {

		//
		// Read from mongodb.
		//
		read: function () {

			var db = pmongo(connectionString, [collection]);
			return db[collection]
				.find(query, fields)
				.toArray()
				.then(function (docs) {
					return docs;
				})
				.catch(function (err) {
					db.close();
					throw err;

				})
				.then(function (docs) {
					db.close();
					return new dataForge.DataFrame({ rows: docs });
				});
		},

		//
		// Write to monogdb.
		//
		write: function (dataFrame) {
			assert.isObject(dataFrame, "Expected 'dataFrame' parameter to 'mongo.write' to be a data frame object.");

			var documents = dataFrame.toObjects();

			var db = pmongo(connectionString, [collection]);
			return E.from(documents)
				.aggregate(Promise.resolve(), function (prevSavePromise, document) {
					return prevSavePromise.then(function () {
						return db[collection].save(document);
					});
				})
				.then(function () {
					db.close();
				});
		},
	};
};

<|endoftext|>


<commit_before>//= require vendor/jquery/jquery-1.12.1.min.js
//= require plugins/jquery.fitvids.js
//= require plugins/jquery.greedy-navigation.js
//= require plugins/jquery.magnific-popup.js
//= require plugins/jquery.smooth-scroll.min.js
//= require plugins/stickyfill.min.js
//= require vendor/anchor.js
//= require vendor/particles.min.js
<commit_msg>removed reference to particles<commit_after>//= require vendor/jquery/jquery-1.12.1.min.js
//= require plugins/jquery.fitvids.js
//= require plugins/jquery.greedy-navigation.js
//= require plugins/jquery.magnific-popup.js
//= require plugins/jquery.smooth-scroll.min.js
//= require plugins/stickyfill.min.js
//= require vendor/anchor.js
<|endoftext|>


<commit_before>!(function(){
  var exports;
  if( typeof window !== 'undefined'){
    exports = window;
  } else if( typeof module !== 'undefined' ){
    exports = module.exports;
  } else {
    console.warn("I don't know where to export to....Enums.js");
    exports = {};
  }

exports.Enum = (function () {
  "use strict";
  var Enum = function ( enums ) {
    var i,
        keys = [],
        values = [];

//  if(!(enums instanceof Array)){
//    throw new SyntaxError('Enum input must be an Array');
//  }

    if ( enums instanceof Array ) {
      for ( i = 0 ; i < enums.length ; i++ ) {
        try {
          Object.defineProperty(
            this,
            enums[i],
            {
              configurable: false,
              enumerable:   true,
              value:        i,
              writable:     false
            }
          );
          values.push(i);
          keys.push(enums[i]);
        } catch (e) {
          throw new TypeError('Enum Constructor Failure, you must pass a set of unique keys.');
        }
      }
    } else if ( enums instanceof Object ) {
      for ( i in enums ) {
        if ( enums.hasOwnProperty(i) ) {
          if ( values.lastIndexOf(enums[i]) !== -1 ) {
            throw new TypeError('Enum Constructor Failure, you must pass a unique value for each key');
          }
          try {
            Object.defineProperty(
              this,
              i,
              {
                configurable: false,
                enumerable:   true,
                value:        enums[i],
                writable:     false
              }
            );
            values.push(enums[i]);
            keys.push(i);
          } catch (e) {
            throw new TypeError('Enum Constructor Failure.');
          }
        }
      }
    }

//    Object.defineProperty(this, 'length', {
//      configurable: false,
//      enumerable:   false,
//      value:        enums.length,
//      writable:     false
//    });
//    Object.defineProperty(this, 'keys', {
//      configurable: false,
//      enumerable:   false,
//      value:        keys,
//      writable:     false
//    });
//    Object.defineProperty(this, 'values', {
//      configurable: false,
//      enumerable:   false,
//      value:        values,
//      writable:     false
//    });

    return Object.freeze(this);
  };

  // Prototype Functions
  Object.defineProperties(Enum.prototype, {
    'length':{
      configurable: false,
      enumerable:   false,
      get:          function () {
        var count = 0;
        for ( var prop in this )
          ++count;
        return count;
        //return this.keys.length;
      }
    },
    'keys':{
      configurable: false,
      enumerable:   false,
      get:          function () {
        var keys = [];
        for ( var prop in this )
          if ( this.hasOwnProperty(prop) )
            keys.push(prop);
        return keys;
      }
    },
    'values':{
      configurable: false,
      enumerable:   false,
      get:          function () {
        var values = [];
        for ( var prop in this )
          if ( this.hasOwnProperty(prop) )
            values.push(this[prop]);
        return values;
      }
    },
    'toString':{
      configurable: false,
      enumerable:   false,
      writable:     false,
      value:        function(){return '[object Enum]';}
    }
  });
  /*
  Object.defineProperty(Enum.prototype, 'length', {
    configurable: false,
    enumerable:   false,
    get:          function () {
      var count = 0;
      for ( var prop in this )
        ++count;
      return count;
//      return this.keys.length;
    }
  });
  Object.defineProperty(Enum.prototype, 'keys', {
    configurable: false,
    enumerable:   false,
    get:          function () {
      var keys = [];
      for ( var prop in this )
        if ( this.hasOwnProperty(prop) )
          keys.push(prop);
      return keys;
    }
  });
  Object.defineProperty(Enum.prototype, 'values', {
    configurable: false,
    enumerable:   false,
    get:          function () {
      var values = [];
      for ( var prop in this )
        if ( this.hasOwnProperty(prop) )
          values.push(this[prop]);
      return values;
    }
  });
  Object.defineProperty(Enum.prototype, 'toString', {
    configurable: false,
    enumerable:   false,
    value:        function () {
      return '[object Enum]';
    },
    writable:     false
  });
  */

  // Export
  return Enum;

})();

})();
<commit_msg>Added Brackets to for and if in Prototype functions<commit_after>!(function(){
  var exports;
  if( typeof window !== 'undefined'){
    exports = window;
  } else if( typeof module !== 'undefined' ){
    exports = module.exports;
  } else {
    console.warn("I don't know where to export to....Enums.js");
    exports = {};
  }

exports.Enum = (function () {
  "use strict";
  var Enum = function ( enums ) {
    var i,
        keys = [],
        values = [];

//  if(!(enums instanceof Array)){
//    throw new SyntaxError('Enum input must be an Array');
//  }

    if ( enums instanceof Array ) {
      for ( i = 0 ; i < enums.length ; i++ ) {
        try {
          Object.defineProperty(
            this,
            enums[i],
            {
              configurable: false,
              enumerable:   true,
              value:        i,
              writable:     false
            }
          );
          values.push(i);
          keys.push(enums[i]);
        } catch (e) {
          throw new TypeError('Enum Constructor Failure, you must pass a set of unique keys.');
        }
      }
    } else if ( enums instanceof Object ) {
      for ( i in enums ) {
        if ( enums.hasOwnProperty(i) ) {
          if ( values.lastIndexOf(enums[i]) !== -1 ) {
            throw new TypeError('Enum Constructor Failure, you must pass a unique value for each key');
          }
          try {
            Object.defineProperty(
              this,
              i,
              {
                configurable: false,
                enumerable:   true,
                value:        enums[i],
                writable:     false
              }
            );
            values.push(enums[i]);
            keys.push(i);
          } catch (e) {
            throw new TypeError('Enum Constructor Failure.');
          }
        }
      }
    }

//    Object.defineProperty(this, 'length', {
//      configurable: false,
//      enumerable:   false,
//      value:        enums.length,
//      writable:     false
//    });
//    Object.defineProperty(this, 'keys', {
//      configurable: false,
//      enumerable:   false,
//      value:        keys,
//      writable:     false
//    });
//    Object.defineProperty(this, 'values', {
//      configurable: false,
//      enumerable:   false,
//      value:        values,
//      writable:     false
//    });

    return Object.freeze(this);
  };

  // Prototype Functions
  Object.defineProperties(Enum.prototype, {
    'length':{
      configurable: false,
      enumerable:   false,
      get:          function () {
        var count = 0;
        for ( var prop in this ){
          ++count;
        }
        return count;
        //return this.keys.length;
      }
    },
    'keys':{
      configurable: false,
      enumerable:   false,
      get:          function () {
        var keys = [];
        for ( var prop in this )
          if ( this.hasOwnProperty(prop) ){
            keys.push(prop);
          }
        return keys;
      }
    },
    'values':{
      configurable: false,
      enumerable:   false,
      get:          function () {
        var values = [];
        for ( var prop in this ){
          if ( this.hasOwnProperty(prop) ){
            values.push(this[prop]);
          }
        }
        return values;
      }
    },
    'toString':{
      configurable: false,
      enumerable:   false,
      writable:     false,
      value:        function(){return '[object Enum]';}
    }
  });
  /*
  Object.defineProperty(Enum.prototype, 'length', {
    configurable: false,
    enumerable:   false,
    get:          function () {
      var count = 0;
      for ( var prop in this )
        ++count;
      return count;
//      return this.keys.length;
    }
  });
  Object.defineProperty(Enum.prototype, 'keys', {
    configurable: false,
    enumerable:   false,
    get:          function () {
      var keys = [];
      for ( var prop in this )
        if ( this.hasOwnProperty(prop) )
          keys.push(prop);
      return keys;
    }
  });
  Object.defineProperty(Enum.prototype, 'values', {
    configurable: false,
    enumerable:   false,
    get:          function () {
      var values = [];
      for ( var prop in this )
        if ( this.hasOwnProperty(prop) )
          values.push(this[prop]);
      return values;
    }
  });
  Object.defineProperty(Enum.prototype, 'toString', {
    configurable: false,
    enumerable:   false,
    value:        function () {
      return '[object Enum]';
    },
    writable:     false
  });
  */

  // Export
  return Enum;

})();

})();
<|endoftext|>


<commit_before>import test from 'ava';
import testFactory from './_test-factory';
import plugin from '../dist';

/**
 * These tests check css selectors that the plugin CANNOT combined together.
 * Meaning that the selectors provided are unique.
 * These tests check only standard css syntax.
 */

const css = testFactory('css', [plugin]);

test(
  'class',
  css,
  '.module {}',
  '.module {}'
);

test(
  'id',
  css,
  '#one {}',
  '#one {}'
);

test(
  'tag',
  css,
  'a {}',
  'a {}'
);

test(
  'universal',
  css,
  '* {}',
  '* {}'
);

test(
  'classes',
  css,
  '.one {} .two {}',
  '.one {} .two {}'
);

test(
  'ids',
  css,
  '#one {} #two {}',
  '#one {} #two {}'
);

test(
  'tags',
  css,
  'a {} b {}',
  'a {} b {}'
);

test(
  'universals',
  css,
  '* a {} * b {}',
  '* a {} * b {}'
);

test(
  'combinations of classes',
  css,
  '.one.two {} .one .two {}',
  '.one.two {} .one .two {}'
);

test(
  'combinations of ids',
  css,
  '#one#two {} #one #two {}',
  '#one#two {} #one #two {}'
);

test(
  'attribute selectors',
  css,
  '.a[href] {} .a[title] {}',
  '.a[href] {} .a[title] {}'
);

test(
  'selectors with same attribute property and unique values',
  css,
  '.a[href="a"] {} .a[href="b"] {}',
  '.a[href="a"] {} .a[href="b"] {}'
);

test(
  'selectors with same attribute',
  css,
  '.a [href] {} .a[href] {}',
  '.a [href] {} .a[href] {}'
);

test(
  'pseudo classes',
  css,
  'a:link {} a:visited {}',
  'a:link {} a:visited {}'
);

test(
  'pseudo class and non pseudo class',
  css,
  'a:link {} a {}',
  'a:link {} a {}'
);

test(
  'pseudo elements',
  css,
  'p::first-line {} p::last-line {}',
  'p::first-line {} p::last-line {}'
);

test(
  'pseudo element and non pseudo element',
  css,
  'p::first-line {} p {}',
  'p::first-line {} p {}'
);

test(
  'pseudo class and pseudo element',
  css,
  'p::first-line {} p:hover {}',
  'p::first-line {} p:hover {}'
);

test(
  'selectors same classes',
  css,
  '.one .two {} .one.two {}',
  '.one .two {} .one.two {}'
);

test(
  'selectors with partial class selector match',
  css,
  '.one.two {} .one.two.three {}',
  '.one.two {} .one.two.three {}'
);
<commit_msg>Issue #68: Add test for expected keyframe behavior<commit_after>import test from 'ava';
import testFactory from './_test-factory';
import plugin from '../dist';

/**
 * These tests check css selectors that the plugin CANNOT combined together.
 * Meaning that the selectors provided are unique.
 * These tests check only standard css syntax.
 */

const css = testFactory('css', [plugin]);

test(
  'class',
  css,
  '.module {}',
  '.module {}'
);

test(
  'id',
  css,
  '#one {}',
  '#one {}'
);

test(
  'tag',
  css,
  'a {}',
  'a {}'
);

test(
  'universal',
  css,
  '* {}',
  '* {}'
);

test(
  'classes',
  css,
  '.one {} .two {}',
  '.one {} .two {}'
);

test(
  'ids',
  css,
  '#one {} #two {}',
  '#one {} #two {}'
);

test(
  'tags',
  css,
  'a {} b {}',
  'a {} b {}'
);

test(
  'universals',
  css,
  '* a {} * b {}',
  '* a {} * b {}'
);

test(
  'combinations of classes',
  css,
  '.one.two {} .one .two {}',
  '.one.two {} .one .two {}'
);

test(
  'combinations of ids',
  css,
  '#one#two {} #one #two {}',
  '#one#two {} #one #two {}'
);

test(
  'attribute selectors',
  css,
  '.a[href] {} .a[title] {}',
  '.a[href] {} .a[title] {}'
);

test(
  'selectors with same attribute property and unique values',
  css,
  '.a[href="a"] {} .a[href="b"] {}',
  '.a[href="a"] {} .a[href="b"] {}'
);

test(
  'selectors with same attribute',
  css,
  '.a [href] {} .a[href] {}',
  '.a [href] {} .a[href] {}'
);

test(
  'pseudo classes',
  css,
  'a:link {} a:visited {}',
  'a:link {} a:visited {}'
);

test(
  'pseudo class and non pseudo class',
  css,
  'a:link {} a {}',
  'a:link {} a {}'
);

test(
  'pseudo elements',
  css,
  'p::first-line {} p::last-line {}',
  'p::first-line {} p::last-line {}'
);

test(
  'pseudo element and non pseudo element',
  css,
  'p::first-line {} p {}',
  'p::first-line {} p {}'
);

test(
  'pseudo class and pseudo element',
  css,
  'p::first-line {} p:hover {}',
  'p::first-line {} p:hover {}'
);

test(
  'selectors same classes',
  css,
  '.one .two {} .one.two {}',
  '.one .two {} .one.two {}'
);

test(
  'selectors with partial class selector match',
  css,
  '.one.two {} .one.two.three {}',
  '.one.two {} .one.two.three {}'
);

test(
  'keyframe selectors',
  css,
  '@keyframes a {0% {} 100% {}} @keyframes b {0% {} 100% {}}',
  '@keyframes a {0% {} 100% {}} @keyframes b {0% {} 100% {}}'
);
<|endoftext|>