<commit_before>export class ScriptHelper {
    static add(url, content, type = 'text/javascript') {
        return new Promise((resolve, reject) => {
            let script = document.createElement('script');
            script.type = type;
            if (url) {
                script.src = url;
            } else if (content) {
                script.innerText = content;
            }
            script.addEventListener('load', () => {
                resolve(script);
            });
            script.addEventListener('error', () => {
                reject(script);
            });
            script.addEventListener('abort', () => {
                reject(script);
            });
            document.body.appendChild(script);
        });
    }

    static addByContent(content, type) {
        return this.add(null, content, type);
    }

    static addByUrl(url, type) {
        return this.add(url, null, type);
    }
}
<commit_msg>fix: ScriptHelper content loading<commit_after>export class ScriptHelper {
    static add(url, content, type = 'text/javascript') {
        return new Promise((resolve, reject) => {
            let script = document.createElement('script');
            script.type = type;
            if (url) {
                script.src = url;
            } else if (content) {
                script.innerText = content;
            }
            if (url) {
                script.addEventListener('load', () => {
                    resolve(script);
                });
                script.addEventListener('error', () => {
                    reject(script);
                });
                script.addEventListener('abort', () => {
                    reject(script);
                });
                document.body.appendChild(script);
            } else {
                document.body.appendChild(script);
                resolve();
            }
        });
    }

    static addByContent(content, type) {
        return this.add(null, content, type);
    }

    static addByUrl(url, type) {
        return this.add(url, null, type);
    }
}
<|endoftext|>


<commit_before>(function (window){
	var ga = { };

    function updateSimulateButton (){
        if (pp2.board.table().flop().length != 3 ){
            $("#simulate").attr("disabled","disabled");
            return;
        }

        var count = 0;
        //check if atleast 2 player's hand has been set
        _.each(pp2.board.players(),function(p){
            if ( p.hand().length != 0 ){
                count++;
                if ( count >= 2){
                    return;
                }
            }
        })

        if ( count == 2 ){
            $("#simulate").removeAttr('disabled');
        }else{
            $("#simulate").attr("disabled","disabled");
        }
    }
    /**
     * Set a player's hand on the table to be the cards passed.
     * @param playerId Player number
     * @param {Card[]} cards Cards for the player
     */
    ga.setPlayerCards = function (playerId, cards) {
        var $player = $('#' + playerId);

        if (_.isUndefined(cards)) {
            cards = [];
        }

        if (_.isArray(cards) && cards.length == 0) {
            // empty hand
            $('.selected', $player).hide();
            $('.no-cards', $player).show();
            return;
        }

        $('.selected', $player).show();
        $('.no-cards', $player).hide();

        var $imgs = $('.selected img', $player);
        var $selectables = $('.selected .card-placeholder', $player);
        cards.forEach(function (card, i) {
            console.log(card);
            $($imgs[i]).attr('src', 'images/Cards/' + card.suit.long + '/' + card.value.short + card.suit.short + '.svg');
        });

        // show and hide
        cards.forEach(function (card, i) {
            $($imgs[i]).show();
            $($selectables[i]).hide();
        });

         _.range(cards.length, 2).forEach(function (i) {
             $($imgs[i]).hide();
             $($selectables[i]).show();
        });

        $('.selected .plus-content .glyphicon-plus', $player).each(function () {
            var $this = $(this);

            $this.css({
                'top': (($this.parent().parent().height() - $this.height())/2) + 'px'
            });
        });
        updateSimulateButton();
    };

    ga.updateBoardEnabledState = function (boardTypeId, isSet) {
        var state = {
            flop: "turn",
            turn: "river"
        };

        if ( isSet ){
            $("#"+boardTypeId+" .enabled").removeClass("enabled").addClass("button");
            if ( boardTypeId in state){
                $("#"+state[boardTypeId]+" .button").removeClass("button").addClass("enabled");
            }
        } else {
            $("#"+boardTypeId+" .button").removeClass("button").addClass("enabled");
            if ( boardTypeId in state){
                $("#"+state[boardTypeId]+" .enabled").removeClass("enabled").addClass("button");
            }
        }

    };

    ga.setBoard = function (boardTypeId, cards) {
        var $boardType = $("#" + boardTypeId);
        if (_.isUndefined(cards)) {
            cards = [];
        } else if ( !_.isArray(cards)) {
            cards = [cards];
        }

        $('img', $boardType).remove();
        if (_.isArray(cards) && cards.length == 0) {
            // empty hand
            $('.plus-content', $boardType).show();
            ga.updateBoardEnabledState(boardTypeId, false);
        } else {
            $('.plus-content', $boardType).hide();

            cards.forEach(function (card, i) {
                $boardType.find(".table-card:nth-child("+(i+1)+")")
                    .append("");
            });
            ga.updateBoardEnabledState(boardTypeId, true);
        }

        updateSimulateButton();
    };

    /**
     * Set the labels for a player's result.
     * @param playerNo
     * @param handLikelyHood
     * @param isBest
     * @private
     */
    var __setHandResult = function (playerNo, handLikelyHood, isBest) {
        var $rspan = $('#p' + playerNo + ' .result');

        if ($rspan.length === 0) {
            return;
        }

        if (_.isNumber(handLikelyHood)) {
            $rspan.text(handLikelyHood + '%');
        } else {
            $rspan.text('');
        }

        if (isBest) {
            $rspan.removeClass('label-primary');
            $rspan.addClass('label-success');
        } else {
            $rspan.addClass('label-primary');
            $rspan.removeClass('label-success');
        }
    };

    /**
     * Sets the board to show the result likely hoods.
     * @param {Number[]} handLikelyHoods Array of percentages (out of 100).
     */
    ga.setHandResults = function (handLikelyHoods) {
        var bestIndex = _.chain(_.range(handLikelyHoods.length)).zip(handLikelyHoods)
            .max(function (x) { return x[1]; })
            .value()[0];

        handLikelyHoods.map(function (likelyHood, i) {
            return [i + 1, likelyHood, i === bestIndex];
        }).forEach(function (args) { __setHandResult.apply(null, args); });

        _.range(handLikelyHoods.length, 6).map(function (i) {
            return [i + 1, undefined, false];
        }).forEach(function (args) { __setHandResult.apply(null, args); });
    };

    window.GameActions = ga;
})(window);<commit_msg>guard:simulate: fixed issue with 3 hands disabling simulate and flop being required<commit_after>(function (window){
	var ga = { };

    function updateSimulateButton (){
        var count = 0;
        //check if atleast 2 player's hand has been set
        _.each(pp2.board.players(),function(p){
            if ( p.hand().length != 0 ){
                count++;
                if ( count >= 2){
                    return;
                }
            }
        })

        if ( count >= 2 ){
            $("#simulate").removeAttr('disabled');
        }else{
            $("#simulate").attr("disabled","disabled");
        }
    }
    /**
     * Set a player's hand on the table to be the cards passed.
     * @param playerId Player number
     * @param {Card[]} cards Cards for the player
     */
    ga.setPlayerCards = function (playerId, cards) {
        var $player = $('#' + playerId);

        if (_.isUndefined(cards)) {
            cards = [];
        }

        if (_.isArray(cards) && cards.length == 0) {
            // empty hand
            $('.selected', $player).hide();
            $('.no-cards', $player).show();
            return;
        }

        $('.selected', $player).show();
        $('.no-cards', $player).hide();

        var $imgs = $('.selected img', $player);
        var $selectables = $('.selected .card-placeholder', $player);
        cards.forEach(function (card, i) {
            console.log(card);
            $($imgs[i]).attr('src', 'images/Cards/' + card.suit.long + '/' + card.value.short + card.suit.short + '.svg');
        });

        // show and hide
        cards.forEach(function (card, i) {
            $($imgs[i]).show();
            $($selectables[i]).hide();
        });

         _.range(cards.length, 2).forEach(function (i) {
             $($imgs[i]).hide();
             $($selectables[i]).show();
        });

        $('.selected .plus-content .glyphicon-plus', $player).each(function () {
            var $this = $(this);

            $this.css({
                'top': (($this.parent().parent().height() - $this.height())/2) + 'px'
            });
        });
        updateSimulateButton();
    };

    ga.updateBoardEnabledState = function (boardTypeId, isSet) {
        var state = {
            flop: "turn",
            turn: "river"
        };

        if ( isSet ){
            $("#"+boardTypeId+" .enabled").removeClass("enabled").addClass("button");
            if ( boardTypeId in state){
                $("#"+state[boardTypeId]+" .button").removeClass("button").addClass("enabled");
            }
        } else {
            $("#"+boardTypeId+" .button").removeClass("button").addClass("enabled");
            if ( boardTypeId in state){
                $("#"+state[boardTypeId]+" .enabled").removeClass("enabled").addClass("button");
            }
        }

    };

    ga.setBoard = function (boardTypeId, cards) {
        var $boardType = $("#" + boardTypeId);
        if (_.isUndefined(cards)) {
            cards = [];
        } else if ( !_.isArray(cards)) {
            cards = [cards];
        }

        $('img', $boardType).remove();
        if (_.isArray(cards) && cards.length == 0) {
            // empty hand
            $('.plus-content', $boardType).show();
            ga.updateBoardEnabledState(boardTypeId, false);
        } else {
            $('.plus-content', $boardType).hide();

            cards.forEach(function (card, i) {
                $boardType.find(".table-card:nth-child("+(i+1)+")")
                    .append("");
            });
            ga.updateBoardEnabledState(boardTypeId, true);
        }

    };

    /**
     * Set the labels for a player's result.
     * @param playerNo
     * @param handLikelyHood
     * @param isBest
     * @private
     */
    var __setHandResult = function (playerNo, handLikelyHood, isBest) {
        var $rspan = $('#p' + playerNo + ' .result');

        if ($rspan.length === 0) {
            return;
        }

        if (_.isNumber(handLikelyHood)) {
            $rspan.text(handLikelyHood + '%');
        } else {
            $rspan.text('');
        }

        if (isBest) {
            $rspan.removeClass('label-primary');
            $rspan.addClass('label-success');
        } else {
            $rspan.addClass('label-primary');
            $rspan.removeClass('label-success');
        }
    };

    /**
     * Sets the board to show the result likely hoods.
     * @param {Number[]} handLikelyHoods Array of percentages (out of 100).
     */
    ga.setHandResults = function (handLikelyHoods) {
        var bestIndex = _.chain(_.range(handLikelyHoods.length)).zip(handLikelyHoods)
            .max(function (x) { return x[1]; })
            .value()[0];

        handLikelyHoods.map(function (likelyHood, i) {
            return [i + 1, likelyHood, i === bestIndex];
        }).forEach(function (args) { __setHandResult.apply(null, args); });

        _.range(handLikelyHoods.length, 6).map(function (i) {
            return [i + 1, undefined, false];
        }).forEach(function (args) { __setHandResult.apply(null, args); });
    };

    window.GameActions = ga;
})(window);<|endoftext|>


<commit_before>/**
 * # messages
 *
 * Copyright (c)2011, by Branko Vukelic <branko@herdhound.com>
 *
 * Translation of various gateway error messages to human-readable format.
 *
 * All error messages generated by Samurai gateway are translated using the
 * `messages.translateAll` and `messages.translate` methods. The former
 * translates all messages returned by `authpost.makeRequest` method, and the
 * latter translates individual messages.
 *
 * In either case, what we end up with is a mapping between fields and
 * messages. Depending on what you are trying to do, the fields can be card
 * data fields, transaction details fields, or virtual fields such as
 * 'gateway', or 'bank'.
 *
 * @author Branko Vukelic <branko@herdhound.com>
 * @license MIT (see LICENSE)
 */

var msg = exports;

/**
 * #messages.str
 * *Individual localized strings*
 * @private
 */
msg.str = {};
msg.str.en_US = {
  SYSTEM_ERROR: 'There was a system error',
  INVALID_NUMBER: 'Card number is invalid',
  INVALID_CSC: 'Card security code is invalid'
};

/**
 * #getStr(key)
 * *Returns a function that yields the localized string for given key*
 *
 * @param {String} key
 * @returns {Function} Returns a translation function that accepts lang argument
 * @private
 */
function getStr(key) {
  return function(lang) {
    return msg.str[lang][key];
  };
}

/**
 * #messages.mappings
 * *Maps Samurai error messages to human-readable strings*
 *
 * This mapping maps class, context, and key to an object that contains the
 * Daimyp field name, and translation function which returns the human-readable
 * string given a language code.
 *
 * @private
 */
msg.mappings = {
  error: {
    'system.general': {
      'default': ['system', getStr('SYSTEM_ERROR')]
    },
    'input.card_number': {
      too_short: ['number', getStr('INVALID_NUMBER')],
      too_long: ['number', getStr('INVALID_NUMBER')],
      failed_checksum: ['number', getStr('INVALID_NUMBER')]
    },
    'input.cvv': {
      too_long: ['csc', getStr('INVALID_CSC')],
      too_short: ['csc', getStr('INVALID_CSC')]
    }
  }
};

/**
 * #messages.translate(message, lang)
 * *Returns a human readable string in given language*
 *
 * The return value is an object that maps a Daimyo field name to
 * human-readable translation. The field name can be a virtual field like
 * 'system' or 'gateway', which indicates the error pretains to components of
 * payment processing workflow, rather than a field.
 *
 * @param {Object} message Message object to be translated
 * @param {String} [lang] Optional language code (defaults to `en_US`)
 * @returns {Object} Object containing the field name, and human readable string
 */
msg.translate = function(message, lang) {
  var mapping = msg.mappings[message.cls][message.context][message.key];
  lang = lang || 'en_US';
  return {
    field: mapping[0],
    message: mapping[1](lang)
  };
};

/**
 * #messages.translateAll(messages, lang)
 * *Translate multiple messages, and return a single field-message mapping*
 *
 * @param {Array} messages Array of message objects
 * @param {String} [lang] Optional language code (defaults to `en_US`);
 * @returns {Object} Object containing the field names, and human readable strings
 */
msg.translateAll = function(messages, lang) {
  var errors = messages.filter(function(item) {
    return item.cls === 'error';
  });
  var info = messages.filter(function(item) {
    return item.cls === 'info';
  });
  function build(msgs) {
    var translations = {};
    msgs.forEach(function(message) {
      translation = msg.translate(message, lang);
      if (translations.hasOwnProperty(translation.field) &&
          translations[translation.field].indexOf(translation.message) < 0) {
        translations[translation.field].push(translation.message);
      } else {
        translations[translation.field] = [translation.message];
      }
    });
    return translations;
  }
  return {
    errors: build(errors),
    info: build(info)
  };
};
<commit_msg>Fixed #2<commit_after>/**
 * # messages
 *
 * Copyright (c)2011, by Branko Vukelic <branko@herdhound.com>
 *
 * Translation of various gateway error messages to human-readable format.
 *
 * All error messages generated by Samurai gateway are translated using the
 * `messages.translateAll` and `messages.translate` methods. The former
 * translates all messages returned by `authpost.makeRequest` method, and the
 * latter translates individual messages.
 *
 * In either case, what we end up with is a mapping between fields and
 * messages. Depending on what you are trying to do, the fields can be card
 * data fields, transaction details fields, or virtual fields such as
 * 'gateway', or 'bank'.
 *
 * @author Branko Vukelic <branko@herdhound.com>
 * @license MIT (see LICENSE)
 */

var msg = exports;

/**
 * #messages.str
 * *Individual localized strings*
 * @private
 */
msg.str = {};
msg.str.en_US = {
  SYSTEM_ERROR: 'There was a system error',
  INVALID_NUMBER: 'Card number is invalid',
  INVALID_CSC: 'Card security code is invalid'
};

/**
 * #getStr(key)
 * *Returns a function that yields the localized string for given key*
 *
 * @param {String} key
 * @returns {Function} Returns a translation function that accepts lang argument
 * @private
 */
function getStr(key) {
  return function(lang) {
    return msg.str[lang][key];
  };
}

/**
 * #messages.mappings
 * *Maps Samurai error messages to human-readable strings*
 *
 * This mapping maps class, context, and key to an object that contains the
 * Daimyp field name, and translation function which returns the human-readable
 * string given a language code.
 *
 * @private
 */
msg.mappings = {
  error: {
    'system.general': {
      'default': ['system', getStr('SYSTEM_ERROR')]
    },
    'input.card_number': {
      too_short: ['number', getStr('INVALID_NUMBER')],
      too_long: ['number', getStr('INVALID_NUMBER')],
      failed_checksum: ['number', getStr('INVALID_NUMBER')]
    },
    'input.cvv': {
      too_long: ['csc', getStr('INVALID_CSC')],
      too_short: ['csc', getStr('INVALID_CSC')]
    }
  }
};

/**
 * #messages.translate(message, lang)
 * *Returns a human readable string in given language*
 *
 * The return value is an object that maps a Daimyo field name to
 * human-readable translation. The field name can be a virtual field like
 * 'system' or 'gateway', which indicates the error pretains to components of
 * payment processing workflow, rather than a field.
 *
 * @param {Object} message Message object to be translated
 * @param {String} [lang] Optional language code (defaults to `en_US`)
 * @returns {Object} Object containing the field name, and human readable string
 */
msg.translate = function(message, lang) {
  try {
    var mapping = msg.mappings[message.cls][message.context][message.key];
    lang = lang || 'en_US';
    return {
      field: mapping[0],
      message: mapping[1](lang)
    };
  } catch(e) {
    // We have an unknown message
    return {
      field: 'unknown',
      message: message.cls + ':' + message.context + ':' + message.key
    };
  }
};

/**
 * #messages.translateAll(messages, lang)
 * *Translate multiple messages, and return a single field-message mapping*
 *
 * @param {Array} messages Array of message objects
 * @param {String} [lang] Optional language code (defaults to `en_US`);
 * @returns {Object} Object containing the field names, and human readable strings
 */
msg.translateAll = function(messages, lang) {
  var errors = messages.filter(function(item) {
    return item.cls === 'error';
  });
  var info = messages.filter(function(item) {
    return item.cls === 'info';
  });
  function build(msgs) {
    var translations = {};
    msgs.forEach(function(message) {
      translation = msg.translate(message, lang);
      if (translations.hasOwnProperty(translation.field) &&
          translations[translation.field].indexOf(translation.message) < 0) {
        translations[translation.field].push(translation.message);
      } else {
        translations[translation.field] = [translation.message];
      }
    });
    return translations;
  }
  return {
    errors: build(errors),
    info: build(info)
  };
};
<|endoftext|>


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

function pad(n, width, z) {
    z = z || '0';
    width = width || 2;
    n = n + '';
    return n.length >= width ? n : new Array(width - n.length + 1).join(z) +
        n;
}

var dateString = function(date) {
    return "" +
        date.getFullYear() + '-' +
        pad(date.getMonth() + 1) + '-' +
        pad(date.getDate()) + '_' +
        pad(date.getHours()) + '-' +
        pad(date.getMinutes()) + '-' +
        pad(date.getSeconds()) + '-' +
        pad(date.getMilliseconds(), 3);
}

// Creates the scaffolding for a migration
// jsMigration [boolean] true if js, false if sql
function getScaffolding(jsMigration) {
    if (jsMigration) {
        return "module.exports.migrate = function(db, callback) {\n};";
    } else {
        return "";
    }
}

function openInEditor(editor, filePath) {
    var editor = child_process.spawn(editor, [filePath], {
        stdio: 'inherit'
    });
    editor.on('exit', process.exit);
}

// All the ones in the database
function getExecutedMigrations(db) {
    return new Promise(function(resolve, reject) {
        db.query('SELECT "version" FROM "schema_migrations"', function(err, resp) {
            if (err) {
                // if there is an error assume we are at the default state, and run root migration
                // attempt to run file located at appRoot/migrations/schema/root.sql -- good for previous data force load (e.g. Rails)
                let schema = fs.readFileSync(migrationsDir + "schema/root.sql").toString();
                db.query(schema); // populate with root schema if not populated.
                reject(Error(err));
            } else {
                // if no error, dump all versions into an array called executed for quick searching.
                resolve(_.pluck(resp.rows, 'version'));
            }
        });
    });
}

// All the ones in the filesystem
function getExistingMigrations(migrationsDir) {
    return new Promise(function(resolve, reject) {
        // populate all existing migrations by reading the migrations directory
        fs.readdir(migrationsDir, function(err, list) {
            if (err) {
                reject(Error(err));
            } else {
                let migrations = [];
                let m = undefined;
                let j = undefined;

                for (let li = 0; li < list.length; li++) {
                    if (m = list[li].match(/(.*)\.sql/)) {
                        // if the file has a .sql extension, load it as a file read for sql schema updating
                        try {
                            migrations.push({
                                id: m[1],
                                sql: fs.readFileSync(migrationsDir + m[0]).toString()
                            });
                        } catch (err) {
                            console.error(util.format("Error reading sql migration %s. \n%s", m[0], err));
                        }
                    } else if (j = list[li].match(/(.*)\.js/)) {
                        // if the file has a .js extension, load via require system and set js attribute as .migrate function
                        try {
                            migrations.push({
                                id: j[1],
                                js: require(migrationsDir + "/" + list[li]).migrate
                            });
                        } catch (err) {
                            console.error(util.format("Error reading js migration %s. \n%s", list[li], err));
                        }
                    }
                }

                resolve(migrations);
            }
        });
    });
}

function runMigration(db, openTransaction, closeTransaction, migration) {
    return new Promise(function(resolve, reject) {

        console.log("Executing migration: " + migration.id);

        // check if migration is SQL
        if (migration.sql) {

            // suffix with schema migrations insertion so we dont run again if successful.
            var sql = openTransaction + migration.sql + "; INSERT INTO schema_migrations VALUES ('" +
                migration.id + "'); " + closeTransaction;

            // execute the full query
            db.query(sql, function(e, r) {
                if (e) {
                    db.query("ROLLBACK;", function() {
                        // if error, dump why we couldn't migrate and process no more.
                        reject(util.format("Could not migrate %s. Error: %s", migration.id, e));
                    });
                } else {
                    resolve();
                }
            });

        } else {
            // migration is JS code
            // pass our db object and execute with callback to insert into schema migration AND recurse with rest of "torun" array
            migration.js(db, function() {
                db.query("INSERT INTO schema_migrations VALUES ($1)", [migration.id], function(err, resp) {
                    if (err) {
                        reject(err);
                    } else {
                        resolve();
                    }
                });
            });
        }
    });
}

module.exports.migrate = async function(appRoot, appConfig, options) {
    var editor = process.env.EDITOR;
    var db;
    var openTransaction;
    var closeTransaction;
    // set up the migrations directory
    var migrationsDir = appRoot + "migrations/";

    if (options && options.editor) {
        editor = options.editor;
    }

    // determine working condition.
    if (appConfig.postgresql) {
        // load postgresql library
        try {
            var pg = require("pg");
        } catch (e) {
            console.log("You must install pg globally!");
        }

        // create and connect db
        db = new pg.Client(appConfig.postgresql);
        db.connect();
        openTransaction = "BEGIN; ";
        closeTransaction = "COMMIT; ";

    } else if (appConfig.mysql) {
        try {
            var mysql = require("mysql");
        } catch (e) {
            console.log("You must install mysql globally!");
        }

        // create and connect db
        db = mysql.createClient(appConfig.mysql);
        openTransaction = "START TRANSACTION; ";
        closeTransaction = "COMMIT; ";

    } else {
        console.log("You must specify a connection string for either PostgreSQL or MySQL");
        process.exit(-1);
    }

    // if requested with no parameters
    if (process.argv.length <= 2) {
        var executed = await getExecutedMigrations(db);
        var migrations = await getExistingMigrations(migrationsDir);

        var migrationsToRun = _.sortBy(_.filter(migrations,
            function(migration) {
                return !~executed.indexOf(migration.id);
            }), 'id');

        Promise.all(_.map(migrationsToRun, function(mig) {
            return runMigration(db, openTransaction, closeTransaction, mig);
        })).then(function() {
            console.log("Completed successfully");
            db.end();
            process.exit(0);
        }).catch(function(e) {
            console.error(e);
            db.end();
            process.exit(-1);  // get on with your life
        });

    } else {
        if (process.argv[2] == "generate" || process.argv[2] == "-g") {
            // if provided a generate argument: ./script/migrate generate or ./script/migrate -g
            var jsMigration = (process.argv[3] === "js");
            var fileName = dateString(new Date());
            var filePath = util.format("%s%s.%s", migrationsDir, fileName,
                jsMigration ? "js" : "sql");
            var scaffolding = getScaffolding(jsMigration);

            fs.writeFileSync(filePath, scaffolding);
            console.log(util.format("Created new migration file: %s", fileName));
            openInEditor(editor, filePath);
        } else if (process.argv[2] == "--dry-run") {
            var executed = await getExecutedMigrations(db);
            var migrations = await getExistingMigrations(migrationsDir);

            var migrationsToRun = _.sortBy(_.filter(migrations,
                function(migration) {
                    return !~executed.indexOf(migration.id);
                }), 'id');

            if (migrationsToRun.length > 0) {
                console.log("Migrations that would be run: ");
            } else {
                console.log("No migrations haven't been applied.");
            }
            _.map(migrationsToRun, function(mig) {
                console.log(mig.id);
            });
            process.exit(0);
        } else {
            // run a specific migration
            var migrationsToRun = _.map(process.argv.slice(2), function(migration) {
                var parts = migration.split('.');
                var ret = {};
                var fn;

                if (parts[1] == 'sql') {
                    fn = fs.readFileSync(migrationsDir + '/' + migration).toString();
                } else {
                    fn = require(migrationsDir + "/" + migration).migrate;
                }
                ret.id = parts[0];
                ret[parts[1]] = fn;
                return ret;
            });

            Promise.all(_.map(migrationsToRun, function(mig) {
                return runMigration(db, openTransaction, closeTransaction, mig);
            })).then(function() {
                console.log("Completed succesfully.");
                db.end();
                process.exit(0);  // get on with your life
            }).catch(function(e) {
                console.error(e);
                db.end();
                process.exit(-1);  // get on with your life
            });
        }
    }
};
<commit_msg>Updated pluck to map<commit_after>var _ = require('lodash');
var child_process = require("child_process");
var exec = child_process.exec;
var fs = require("fs");
var util = require('util');

function pad(n, width, z) {
    z = z || '0';
    width = width || 2;
    n = n + '';
    return n.length >= width ? n : new Array(width - n.length + 1).join(z) +
        n;
}

var dateString = function(date) {
    return "" +
        date.getFullYear() + '-' +
        pad(date.getMonth() + 1) + '-' +
        pad(date.getDate()) + '_' +
        pad(date.getHours()) + '-' +
        pad(date.getMinutes()) + '-' +
        pad(date.getSeconds()) + '-' +
        pad(date.getMilliseconds(), 3);
}

// Creates the scaffolding for a migration
// jsMigration [boolean] true if js, false if sql
function getScaffolding(jsMigration) {
    if (jsMigration) {
        return "module.exports.migrate = function(db, callback) {\n};";
    } else {
        return "";
    }
}

function openInEditor(editor, filePath) {
    var editor = child_process.spawn(editor, [filePath], {
        stdio: 'inherit'
    });
    editor.on('exit', process.exit);
}

// All the ones in the database
function getExecutedMigrations(db) {
    return new Promise(function(resolve, reject) {
        db.query('SELECT "version" FROM "schema_migrations"', function(err, resp) {
            if (err) {
                // if there is an error assume we are at the default state, and run root migration
                // attempt to run file located at appRoot/migrations/schema/root.sql -- good for previous data force load (e.g. Rails)
                let schema = fs.readFileSync(migrationsDir + "schema/root.sql").toString();
                db.query(schema); // populate with root schema if not populated.
                reject(Error(err));
            } else {
                // if no error, dump all versions into an array called executed for quick searching.
                resolve(_.map(resp.rows, 'version'));
            }
        });
    });
}

// All the ones in the filesystem
function getExistingMigrations(migrationsDir) {
    return new Promise(function(resolve, reject) {
        // populate all existing migrations by reading the migrations directory
        fs.readdir(migrationsDir, function(err, list) {
            if (err) {
                reject(Error(err));
            } else {
                let migrations = [];
                let m = undefined;
                let j = undefined;

                for (let li = 0; li < list.length; li++) {
                    if (m = list[li].match(/(.*)\.sql/)) {
                        // if the file has a .sql extension, load it as a file read for sql schema updating
                        try {
                            migrations.push({
                                id: m[1],
                                sql: fs.readFileSync(migrationsDir + m[0]).toString()
                            });
                        } catch (err) {
                            console.error(util.format("Error reading sql migration %s. \n%s", m[0], err));
                        }
                    } else if (j = list[li].match(/(.*)\.js/)) {
                        // if the file has a .js extension, load via require system and set js attribute as .migrate function
                        try {
                            migrations.push({
                                id: j[1],
                                js: require(migrationsDir + "/" + list[li]).migrate
                            });
                        } catch (err) {
                            console.error(util.format("Error reading js migration %s. \n%s", list[li], err));
                        }
                    }
                }

                resolve(migrations);
            }
        });
    });
}

function runMigration(db, openTransaction, closeTransaction, migration) {
    return new Promise(function(resolve, reject) {

        console.log("Executing migration: " + migration.id);

        // check if migration is SQL
        if (migration.sql) {

            // suffix with schema migrations insertion so we dont run again if successful.
            var sql = openTransaction + migration.sql + "; INSERT INTO schema_migrations VALUES ('" +
                migration.id + "'); " + closeTransaction;

            // execute the full query
            db.query(sql, function(e, r) {
                if (e) {
                    db.query("ROLLBACK;", function() {
                        // if error, dump why we couldn't migrate and process no more.
                        reject(util.format("Could not migrate %s. Error: %s", migration.id, e));
                    });
                } else {
                    resolve();
                }
            });

        } else {
            // migration is JS code
            // pass our db object and execute with callback to insert into schema migration AND recurse with rest of "torun" array
            migration.js(db, function() {
                db.query("INSERT INTO schema_migrations VALUES ($1)", [migration.id], function(err, resp) {
                    if (err) {
                        reject(err);
                    } else {
                        resolve();
                    }
                });
            });
        }
    });
}

module.exports.migrate = async function(appRoot, appConfig, options) {
    var editor = process.env.EDITOR;
    var db;
    var openTransaction;
    var closeTransaction;
    // set up the migrations directory
    var migrationsDir = appRoot + "migrations/";

    if (options && options.editor) {
        editor = options.editor;
    }

    // determine working condition.
    if (appConfig.postgresql) {
        // load postgresql library
        try {
            var pg = require("pg");
        } catch (e) {
            console.log("You must install pg globally!");
        }

        // create and connect db
        db = new pg.Client(appConfig.postgresql);
        db.connect();
        openTransaction = "BEGIN; ";
        closeTransaction = "COMMIT; ";

    } else if (appConfig.mysql) {
        try {
            var mysql = require("mysql");
        } catch (e) {
            console.log("You must install mysql globally!");
        }

        // create and connect db
        db = mysql.createClient(appConfig.mysql);
        openTransaction = "START TRANSACTION; ";
        closeTransaction = "COMMIT; ";

    } else {
        console.log("You must specify a connection string for either PostgreSQL or MySQL");
        process.exit(-1);
    }

    // if requested with no parameters
    if (process.argv.length <= 2) {
        var executed = await getExecutedMigrations(db);
        var migrations = await getExistingMigrations(migrationsDir);

        var migrationsToRun = _.sortBy(_.filter(migrations,
            function(migration) {
                return !~executed.indexOf(migration.id);
            }), 'id');

        Promise.all(_.map(migrationsToRun, function(mig) {
            return runMigration(db, openTransaction, closeTransaction, mig);
        })).then(function() {
            console.log("Completed successfully");
            db.end();
            process.exit(0);
        }).catch(function(e) {
            console.error(e);
            db.end();
            process.exit(-1);  // get on with your life
        });

    } else {
        if (process.argv[2] == "generate" || process.argv[2] == "-g") {
            // if provided a generate argument: ./script/migrate generate or ./script/migrate -g
            var jsMigration = (process.argv[3] === "js");
            var fileName = dateString(new Date());
            var filePath = util.format("%s%s.%s", migrationsDir, fileName,
                jsMigration ? "js" : "sql");
            var scaffolding = getScaffolding(jsMigration);

            fs.writeFileSync(filePath, scaffolding);
            console.log(util.format("Created new migration file: %s", fileName));
            openInEditor(editor, filePath);
        } else if (process.argv[2] == "--dry-run") {
            var executed = await getExecutedMigrations(db);
            var migrations = await getExistingMigrations(migrationsDir);

            var migrationsToRun = _.sortBy(_.filter(migrations,
                function(migration) {
                    return !~executed.indexOf(migration.id);
                }), 'id');

            if (migrationsToRun.length > 0) {
                console.log("Migrations that would be run: ");
            } else {
                console.log("No migrations haven't been applied.");
            }
            _.map(migrationsToRun, function(mig) {
                console.log(mig.id);
            });
            process.exit(0);
        } else {
            // run a specific migration
            var migrationsToRun = _.map(process.argv.slice(2), function(migration) {
                var parts = migration.split('.');
                var ret = {};
                var fn;

                if (parts[1] == 'sql') {
                    fn = fs.readFileSync(migrationsDir + '/' + migration).toString();
                } else {
                    fn = require(migrationsDir + "/" + migration).migrate;
                }
                ret.id = parts[0];
                ret[parts[1]] = fn;
                return ret;
            });

            Promise.all(_.map(migrationsToRun, function(mig) {
                return runMigration(db, openTransaction, closeTransaction, mig);
            })).then(function() {
                console.log("Completed succesfully.");
                db.end();
                process.exit(0);  // get on with your life
            }).catch(function(e) {
                console.error(e);
                db.end();
                process.exit(-1);  // get on with your life
            });
        }
    }
};
<|endoftext|>


<commit_before>
var jobStatusInterval = null;
var requestPendingAllJobs = false;

var jobsManager = {
  jobs: [],
  htmlElements: {
    builder: function (jobs) {
      $(jobs).each(function () {

        currentJob = this;
        var completed = currentJob.status === 'completed' ? true : false;
        var jobDOM =
          '
'
          + '' + (new Date(currentJob.time)).toLocaleString('fr-FR') + ' : '
          + '' + 'Job N° ' + currentJob.uuid + ' '
          + '<button value=' + currentJob.uuid + ' data-role="delete">'
          + ((currentJob.status === 'queued' || currentJob.status === 'working') ? i18n.killOptim : i18n.deleteOptim)
          + '</button>'
          + ' (Status: ' + currentJob.status + ')'
          + (completed ? ' ' + 'Telecharger le resultat de l\'optimisation' + '' : '')
          + '
';

        $('#jobs-list').append(jobDOM);

        if (completed) {
          $('a[data-job-id="' + currentJob.uuid + '"').on('click', function (e) {
            e.preventDefault();
            jobsManager.checkJobStatus({
              job: currentJob,
            }, function (err, job) {
              if (err) {
                if (debug) console.error(err);
                return alert("An error occured");
              }

              if (typeof job === 'string') {
                $('#result').html(job)
                var a = document.createElement('a');
                a.href = 'data:attachment/csv,' + encodeURIComponent(job);
                a.target = '_blank';
                a.download = 'result.csv';
                document.body.appendChild(a);
                a.click();
              }
              else {
                var solution = job.solutions[0];
                $('#result').html(JSON.stringify(solution, null, 4));
                var a = document.createElement('a');
                a.href = 'data:attachment/json,' + encodeURIComponent(JSON.stringify(solution, null, 4));
                a.target = '_blank';
                a.download = 'result.json';
                document.body.appendChild(a);
                a.click();
              }
            });
          })
        }
      });
      $('#jobs-list button').on('click', function () {
        jobsManager.roleDispatcher(this);
      });
    }
  },
  roleDispatcher: function (object) {
    switch ($(object).data('role')) {
      case 'focus':
        //actually in building, create to apply different behavior to the button object restartJob, actually not set. #TODO
        break;
      case 'delete':
        this.ajaxDeleteJob($(object).val());
        break;
    }
  },
  ajaxGetJobs: function (timeinterval) {
    var ajaxload = function () {
      if (!requestPendingAllJobs) {
        requestPendingAllJobs = true;
        $.ajax({
          url: '/0.1/vrp/jobs',
          type: 'get',
          dataType: 'json',
          data: { api_key: getParams()['api_key'] },
          complete: function () { requestPendingAllJobs = false; }
        }).done(function (data) {
          jobsManager.shouldUpdate(data);
        }).fail(function (jqXHR, textStatus, errorThrown) {
          clearInterval(window.AjaxGetRequestInterval);
          if (jqXHR.status == 401) {
            $('#optim-list-status').prepend('
' + i18n.unauthorizedError + '
');
            $('form input, form button').prop('disabled', true);
          }
        });
      }
    };
    if (timeinterval) {
      ajaxload();
      window.AjaxGetRequestInterval = setInterval(ajaxload, 5000);
    } else {
      ajaxload();
    }
  },
  ajaxDeleteJob: function (uuid) {
    $.ajax({
      url: '/0.1/vrp/jobs/' + uuid + '.json',
      type: 'delete',
      dataType: 'json',
      data: {
        api_key: getParams()['api_key']
      },
    }).done(function (data) {
      if (debug) { console.log("the uuid have been deleted from the jobs queue & the DB"); }
      $('button[data-role="delete"][value="' + uuid + '"]').fadeOut(500, function () { $(this).closest('.job').remove(); });
    });
  },
  shouldUpdate: function (data) {
    // erase list if no job running
    if (data.length === 0 && jobsManager.jobs.length !== 0) {
      $('#jobs-list').empty();
    }
    //check if chagements occurs in the data api. #TODO, update if more params are needed.
    $(data).each(function (index, object) {
      if (jobsManager.jobs.length > 0) {
        if (object.status != jobsManager.jobs[index].status || jobsManager.jobs.length != data.length) {
          jobsManager.jobs = data;
          $('#jobs-list').empty();
          jobsManager.htmlElements.builder(jobsManager.jobs);
        }
      }
      else {
        jobsManager.jobs = data;
        $('#jobs-list').empty();
        jobsManager.htmlElements.builder(jobsManager.jobs);
      }
    });
  },
  checkJobStatus: function (options, cb) {
    var nbError = 0;
    var pendingRequest = false;

    if (options.interval) {
      jobStatusInterval = setInterval(function () {
        if (!pendingRequest) {
          pendingRequest = true;
          requestPendingJob();
        }
      }, options.interval);
      return;
    }

    requestPendingJob();

    function requestPendingJob() {
      $.ajax({
        type: 'GET',
        contentType: 'application/json',
        url: '/0.1/vrp/jobs/'
          + (options.job.id || options.job.uuid)
          + (options.format ? options.format : '')
          + '?api_key=' + getParams()["api_key"],
        success: function (job, status, xhr) {
          if (options.format === ".csv") {
            nbError = 0;
            onCSVFormat(jobStatusInterval, job, xhr, cb);
          }
          else if (options.format === ".json") {
            nbError = 0;
            onJSONFormat(jobStatusInterval, job, xhr, cb);
          }
          else {
            cb(null, job, xhr);
          }
        },
        error: function (xhr, status) {
          ++nbError
          if (nbError > 2) {
            alert(i18n.failureOptim(nbError, status));
            if (jobStatusInterval) {
              clearInterval(jobStatusInterval);
            }
            cb({ xhr, status });
          }
        },
        complete: function () { pendingRequest = false; }
      });
    }

  },
  stopJobChecking: function () {
    clearInterval(jobStatusInterval);
  }
};

function onCSVFormat(jobStatusInterval, job, xhr, cb) {
  if (xhr.status === 200 || xhr.status === 202 && jobStatusInterval) {
    clearInterval(jobStatusInterval);
  }
  cb(null, job, xhr);
}

function onJSONFormat(jobStatusInterval, job, xhr, cb) {
  if (((job.job && (job.job.status !== 'queued' && job.job.status !== 'working'))
    || typeof job === 'string') && jobStatusInterval) {
    clearInterval(jobStatusInterval);
  }
  cb(null, job, xhr);
}
<commit_msg>UX : Add download button on failed status too<commit_after>
var jobStatusInterval = null;
var requestPendingAllJobs = false;

var jobsManager = {
  jobs: [],
  htmlElements: {
    builder: function (jobs) {
      $(jobs).each(function () {

        currentJob = this;
        var completed = (currentJob.status === 'completed' || currentJob.status === 'failed') ? true : false;
        var jobDOM =
          '
'
          + '' + (new Date(currentJob.time)).toLocaleString('fr-FR') + ' : '
          + '' + 'Job N° ' + currentJob.uuid + ' '
          + '<button value=' + currentJob.uuid + ' data-role="delete">'
          + ((currentJob.status === 'queued' || currentJob.status === 'working') ? i18n.killOptim : i18n.deleteOptim)
          + '</button>'
          + ' (Status: ' + currentJob.status + ')'
          + (completed ? ' ' + 'Telecharger le resultat de l\'optimisation' + '' : '')
          + '
';

        $('#jobs-list').append(jobDOM);

        if (completed) {
          $('a[data-job-id="' + currentJob.uuid + '"').on('click', function (e) {
            e.preventDefault();
            jobsManager.checkJobStatus({
              job: currentJob,
            }, function (err, job) {
              if (err) {
                if (debug) console.error(err);
                return alert("An error occured");
              }

              if (typeof job === 'string') {
                $('#result').html(job)
                var a = document.createElement('a');
                a.href = 'data:attachment/csv,' + encodeURIComponent(job);
                a.target = '_blank';
                a.download = 'result.csv';
                document.body.appendChild(a);
                a.click();
              }
              else {
                var solution = job.solutions[0];
                $('#result').html(JSON.stringify(solution, null, 4));
                var a = document.createElement('a');
                a.href = 'data:attachment/json,' + encodeURIComponent(JSON.stringify(solution, null, 4));
                a.target = '_blank';
                a.download = 'result.json';
                document.body.appendChild(a);
                a.click();
              }
            });
          })
        }
      });
      $('#jobs-list button').on('click', function () {
        jobsManager.roleDispatcher(this);
      });
    }
  },
  roleDispatcher: function (object) {
    switch ($(object).data('role')) {
      case 'focus':
        //actually in building, create to apply different behavior to the button object restartJob, actually not set. #TODO
        break;
      case 'delete':
        this.ajaxDeleteJob($(object).val());
        break;
    }
  },
  ajaxGetJobs: function (timeinterval) {
    var ajaxload = function () {
      if (!requestPendingAllJobs) {
        requestPendingAllJobs = true;
        $.ajax({
          url: '/0.1/vrp/jobs',
          type: 'get',
          dataType: 'json',
          data: { api_key: getParams()['api_key'] },
          complete: function () { requestPendingAllJobs = false; }
        }).done(function (data) {
          jobsManager.shouldUpdate(data);
        }).fail(function (jqXHR, textStatus, errorThrown) {
          clearInterval(window.AjaxGetRequestInterval);
          if (jqXHR.status == 401) {
            $('#optim-list-status').prepend('
' + i18n.unauthorizedError + '
');
            $('form input, form button').prop('disabled', true);
          }
        });
      }
    };
    if (timeinterval) {
      ajaxload();
      window.AjaxGetRequestInterval = setInterval(ajaxload, 5000);
    } else {
      ajaxload();
    }
  },
  ajaxDeleteJob: function (uuid) {
    $.ajax({
      url: '/0.1/vrp/jobs/' + uuid + '.json',
      type: 'delete',
      dataType: 'json',
      data: {
        api_key: getParams()['api_key']
      },
    }).done(function (data) {
      if (debug) { console.log("the uuid have been deleted from the jobs queue & the DB"); }
      $('button[data-role="delete"][value="' + uuid + '"]').fadeOut(500, function () { $(this).closest('.job').remove(); });
    });
  },
  shouldUpdate: function (data) {
    // erase list if no job running
    if (data.length === 0 && jobsManager.jobs.length !== 0) {
      $('#jobs-list').empty();
    }
    //check if chagements occurs in the data api. #TODO, update if more params are needed.
    $(data).each(function (index, object) {
      if (jobsManager.jobs.length > 0) {
        if (object.status != jobsManager.jobs[index].status || jobsManager.jobs.length != data.length) {
          jobsManager.jobs = data;
          $('#jobs-list').empty();
          jobsManager.htmlElements.builder(jobsManager.jobs);
        }
      }
      else {
        jobsManager.jobs = data;
        $('#jobs-list').empty();
        jobsManager.htmlElements.builder(jobsManager.jobs);
      }
    });
  },
  checkJobStatus: function (options, cb) {
    var nbError = 0;
    var pendingRequest = false;

    if (options.interval) {
      jobStatusInterval = setInterval(function () {
        if (!pendingRequest) {
          pendingRequest = true;
          requestPendingJob();
        }
      }, options.interval);
      return;
    }

    requestPendingJob();

    function requestPendingJob() {
      $.ajax({
        type: 'GET',
        contentType: 'application/json',
        url: '/0.1/vrp/jobs/'
          + (options.job.id || options.job.uuid)
          + (options.format ? options.format : '')
          + '?api_key=' + getParams()["api_key"],
        success: function (job, status, xhr) {
          if (options.format === ".csv") {
            nbError = 0;
            onCSVFormat(jobStatusInterval, job, xhr, cb);
          }
          else if (options.format === ".json") {
            nbError = 0;
            onJSONFormat(jobStatusInterval, job, xhr, cb);
          }
          else {
            cb(null, job, xhr);
          }
        },
        error: function (xhr, status) {
          ++nbError
          if (nbError > 2) {
            alert(i18n.failureOptim(nbError, status));
            if (jobStatusInterval) {
              clearInterval(jobStatusInterval);
            }
            cb({ xhr, status });
          }
        },
        complete: function () { pendingRequest = false; }
      });
    }

  },
  stopJobChecking: function () {
    clearInterval(jobStatusInterval);
  }
};

function onCSVFormat(jobStatusInterval, job, xhr, cb) {
  if (xhr.status === 200 || xhr.status === 202 && jobStatusInterval) {
    clearInterval(jobStatusInterval);
  }
  cb(null, job, xhr);
}

function onJSONFormat(jobStatusInterval, job, xhr, cb) {
  if (((job.job && (job.job.status !== 'queued' && job.job.status !== 'working'))
    || typeof job === 'string') && jobStatusInterval) {
    clearInterval(jobStatusInterval);
  }
  cb(null, job, xhr);
}
<|endoftext|>


<commit_before>var dbmUtil = require('./util');
var Migration = require('./migration');
var log = require('./log');
var Promise = require('bluebird');
var MigratorInterface = require( './interface/migratorInterface.js');

Migrator = function(driver, migrationsDir, empty, intern) {
  this.driver = dbmUtil.reduceToInterface( driver, MigratorInterface );
  console.log( this.driver );
  this.migrationsDir = migrationsDir;
  this.internals = intern;

  this.internals.migrationOptions.relation = require('./relation');

  Migration.exportInternals(intern);
};

Migrator.prototype = {
  createMigrationTable: function(callback) {
    this.driver.createMigrationTable(callback);
  },

  writeMigrationRecord: function(migration, callback) {
    function onComplete(err) {
      if (err) {
        log.error(migration.name, err);
      } else {
        log.info('Processed migration', migration.name);
      }
      callback(err);
    }
    this.driver.addMigrationRecord(this.internals.matching + '/' + migration.name, onComplete);
  },

  deleteMigrationRecord: function(migration, callback) {
    function onComplete(err) {
      if (err) {
        log.error(migration.name, err);
      } else {
        log.info('Processed migration', migration.name);
      }
      callback(err);
    }
    this.driver.deleteMigration(this.internals.matching + '/' + migration.name, function(err) {

      if(!this.internals.matching) {

        this.driver.deleteMigration(migration.name, onComplete);
      }
      else {

        onComplete.apply(err);
      }
    }.bind(this));
  },

  up: function(funcOrOpts, callback) {
    if (dbmUtil.isFunction(funcOrOpts)) {
      funcOrOpts(this.driver, callback);
    } else {
      this.upToBy(funcOrOpts.destination, funcOrOpts.count, callback);
    }
  },

  down: function(funcOrOpts, callback) {
    if (dbmUtil.isFunction(funcOrOpts)) {
      funcOrOpts(this.driver, callback);
    } else {
      this.downToBy(funcOrOpts.count, callback);
    }
  },

  upToBy: function(partialName, count, callback) {
    var self = this;
    Migration.loadFromFilesystem(self.migrationsDir, function(err, allMigrations) {
      if (err) { callback(err); return; }

      Migration.loadFromDatabase(self.migrationsDir, self.driver, self.internals, function(err, completedMigrations) {
        if (err) { callback(err); return; }
        var toRun = dbmUtil.filterUp(allMigrations, completedMigrations, partialName, count);

        if (toRun.length === 0) {
          log.info('No migrations to run');
          callback(null);
          return;
        }

        return Promise.resolve(toRun).each(function(migration) {

          log.verbose('preparing to run up migration:', migration.name);

          return self.driver.startMigration()
          .then(function() {

            var setup = migration.setup();

            if(typeof(setup) === 'function')
              setup(self.internals.migrationOptions);

            return (Promise.promisify(self.up.bind(self)))(migration.up.bind(migration));
          })
          .then(function() {

            return (Promise.promisify(self.writeMigrationRecord.bind(self)))(migration);
          })
          .then(self.driver.endMigration.bind(self.driver));
        })
        .catch(function(e) {

          throw e;
        })
        .nodeify(callback);

      });
    });
  },

  downToBy: function(count, callback) {
    var self = this;
    Migration.loadFromDatabase(self.migrationsDir, self.driver, self.internals, function(err, completedMigrations) {
      if (err) { return callback(err); }

      var toRun = dbmUtil.filterDown(completedMigrations, count);

      if (toRun.length === 0) {
        log.info('No migrations to run');
        callback(null);
        return;
      }

      return Promise.resolve(toRun).each(function(migration) {

        log.verbose('preparing to run down migration:', migration.name);

        return self.driver.startMigration()
        .then(function() {
          var setup = migration.setup();

          if(typeof(setup) === 'function')
            setup(self.internals.migrationOptions);

          return (Promise.promisify(self.down.bind(self)))(migration.down.bind(migration));
        })
        .then(function() {
          return (Promise.promisify(self.deleteMigrationRecord.bind(self)))(migration);
        })
        .then(self.driver.endMigration.bind(self.driver));
      })
      .catch(function(e) {

        throw e;
      })
      .nodeify(callback);
    });
  }
};

module.exports = Migrator;
<commit_msg>remove logging<commit_after>var dbmUtil = require('./util');
var Migration = require('./migration');
var log = require('./log');
var Promise = require('bluebird');
var MigratorInterface = require( './interface/migratorInterface.js');

Migrator = function(driver, migrationsDir, empty, intern) {
  this.driver = dbmUtil.reduceToInterface( driver, MigratorInterface );
  this.migrationsDir = migrationsDir;
  this.internals = intern;

  this.internals.migrationOptions.relation = require('./relation');

  Migration.exportInternals(intern);
};

Migrator.prototype = {
  createMigrationTable: function(callback) {
    this.driver.createMigrationTable(callback);
  },

  writeMigrationRecord: function(migration, callback) {
    function onComplete(err) {
      if (err) {
        log.error(migration.name, err);
      } else {
        log.info('Processed migration', migration.name);
      }
      callback(err);
    }
    this.driver.addMigrationRecord(this.internals.matching + '/' + migration.name, onComplete);
  },

  deleteMigrationRecord: function(migration, callback) {
    function onComplete(err) {
      if (err) {
        log.error(migration.name, err);
      } else {
        log.info('Processed migration', migration.name);
      }
      callback(err);
    }
    this.driver.deleteMigration(this.internals.matching + '/' + migration.name, function(err) {

      if(!this.internals.matching) {

        this.driver.deleteMigration(migration.name, onComplete);
      }
      else {

        onComplete.apply(err);
      }
    }.bind(this));
  },

  up: function(funcOrOpts, callback) {
    if (dbmUtil.isFunction(funcOrOpts)) {
      funcOrOpts(this.driver, callback);
    } else {
      this.upToBy(funcOrOpts.destination, funcOrOpts.count, callback);
    }
  },

  down: function(funcOrOpts, callback) {
    if (dbmUtil.isFunction(funcOrOpts)) {
      funcOrOpts(this.driver, callback);
    } else {
      this.downToBy(funcOrOpts.count, callback);
    }
  },

  upToBy: function(partialName, count, callback) {
    var self = this;
    Migration.loadFromFilesystem(self.migrationsDir, function(err, allMigrations) {
      if (err) { callback(err); return; }

      Migration.loadFromDatabase(self.migrationsDir, self.driver, self.internals, function(err, completedMigrations) {
        if (err) { callback(err); return; }
        var toRun = dbmUtil.filterUp(allMigrations, completedMigrations, partialName, count);

        if (toRun.length === 0) {
          log.info('No migrations to run');
          callback(null);
          return;
        }

        return Promise.resolve(toRun).each(function(migration) {

          log.verbose('preparing to run up migration:', migration.name);

          return self.driver.startMigration()
          .then(function() {

            var setup = migration.setup();

            if(typeof(setup) === 'function')
              setup(self.internals.migrationOptions);

            return (Promise.promisify(self.up.bind(self)))(migration.up.bind(migration));
          })
          .then(function() {

            return (Promise.promisify(self.writeMigrationRecord.bind(self)))(migration);
          })
          .then(self.driver.endMigration.bind(self.driver));
        })
        .catch(function(e) {

          throw e;
        })
        .nodeify(callback);

      });
    });
  },

  downToBy: function(count, callback) {
    var self = this;
    Migration.loadFromDatabase(self.migrationsDir, self.driver, self.internals, function(err, completedMigrations) {
      if (err) { return callback(err); }

      var toRun = dbmUtil.filterDown(completedMigrations, count);

      if (toRun.length === 0) {
        log.info('No migrations to run');
        callback(null);
        return;
      }

      return Promise.resolve(toRun).each(function(migration) {

        log.verbose('preparing to run down migration:', migration.name);

        return self.driver.startMigration()
        .then(function() {
          var setup = migration.setup();

          if(typeof(setup) === 'function')
            setup(self.internals.migrationOptions);

          return (Promise.promisify(self.down.bind(self)))(migration.down.bind(migration));
        })
        .then(function() {
          return (Promise.promisify(self.deleteMigrationRecord.bind(self)))(migration);
        })
        .then(self.driver.endMigration.bind(self.driver));
      })
      .catch(function(e) {

        throw e;
      })
      .nodeify(callback);
    });
  }
};

module.exports = Migrator;
<|endoftext|>


<commit_before>
/**
 * Navigation
 */

/* Auto close navbar on click (mobile menu) */

$(".navbar-nav > li > a").click(function() {
    $(".navbar-collapse").collapse('hide');
});

/* Change navbar class on scroll */

$(".wrapper").waypoint(function() {
    $(".navbar").toggleClass("js-navbar-top");
    $(".navbar.js-toggleClass").toggleClass("navbar-default navbar-inverse");
    return false;
}, { offset: "-20px" });

/* Change navbar class on collapse/uncollapse in its top position */

$('.wrapper .navbar-collapse').on('show.bs.collapse', function () {
    $(".navbar.js-navbar-top").toggleClass("navbar-default navbar-inverse");
    $(".navbar").toggleClass("js-toggleClass js-noToggleClass");
});

$('.wrapper .navbar-collapse').on('hide.bs.collapse', function () {
    $(".navbar.js-navbar-top").toggleClass("navbar-default navbar-inverse");
    $(".navbar").toggleClass("js-toggleClass js-noToggleClass");
});

/* Sidebar */

$(".js-toggle-sidebar").on('click', function() {
    $(".wrapper").toggleClass("js-wrapper-aside");
    $(".navbar").toggleClass("js-navbar-aside");
    $(".sidebar").toggleClass("js-sidebar-aside");
    return false;
});

/**
 * Smooth scroll to anchor
 */

$(function() {
    $('a[href*=#]:not([href=#])').click(function() {
        if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
            var target = $(this.hash);
            target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
            if (target.length) {
                $('html,body').animate({
                    scrollTop: (target.offset().top - 70) // 70px offset for navbar menu
                }, 1000);
                return false;
            }
        }
    });
});

// Bootstrap Custom JS
$(document).ready(function() {

  // Tooltip opt-in
  $('[data-toggle="tooltip"]').tooltip()

  // Carousel controls
  $('.carousel-control.left').click(function() {
    $('#myCarousel').carousel('prev');
  });

  $('.carousel-control.right').click(function() {
    $('#myCarousel').carousel('next');
  });

  // About Us Show full Bio
  $('#jmbutton').click(function () {
    $('#jmbio').collapse('toggle');
  });
  $('#kmbutton').click(function () {
    $('#kmbio').collapse('toggle');
  });
  $('#dpbutton').click(function () {
    $('#dpbio').collapse('toggle');
  });
  $('#dgbutton').click(function () {
    $('#dgbio').collapse('toggle');
  });

  // Hide full Bio details
  $('body').click(function() {
    $('.collapse').collapse('hide');
  });

});

/**
 * Own carousel :: Sponsors
 */

// $(document).ready(function() {
//   var owl = $('.owl-carousel');
//   owl.owlCarousel({
//       items:4,
//       loop:true,
//       margin:5,
//       responsiveBaseElement:".owl-wrapper",
//       autoplay:true,
//       autoplayTimeout:1000,
//       autoplayHoverPause:true
//   });
// });
/**
 * Doughnut charts :: Skills
 */

/* Base donut styles */

// $.fn.peity.defaults.donut = {
//     delimiter: null,
//     fill: ["#F67280", "#eee"],
//     height: null,
//     innerRadius: 68,
//     radius: 70,
//     width: null
// };

/* Animating donuts */

// $(document).ready(function() {
//     $(".js-skills__item_first").waypoint(function() {
//
//         setTimeout(function () {
//             $('.skills__item').css("visibility", "visible");
//         }, 11);
//
//         $('.skills-item__donut').each(function () {
//             var $this = $(this);
//
//             var updateChart = $this.peity('donut');
//             var text = "";
//             var i = 0;
//             var str = $this.html();
//             var arr = str.split("/");
//             var value = arr[0];
//             var maxValue = arr[1];
//             var step = value/100;
//
//             function myLoop() {
//                 setTimeout(function () {
//
//                     text = i + "/" + maxValue;
//
//                     updateChart.text(text)
//                         .change()
//
//                     i = i + step;
//
//                     if (i <= value) myLoop();
//
//                 }, 10)
//             }
//             myLoop();
//         });
//
//         this.destroy();
//
//     }, { offset: 'bottom-in-view' });
// });

// Wow Plugins

$(".wow").each(function() {
    var wowHeight = $(this).height();
    $(this).attr("data-wow-offset", wowHeight);
});

new WOW().init();

// E-mail submittal to Formspree
$(document).ready(function() {

  $( "#form" ).submit(function( event ) {
    $.ajax({
      url: "//formspree.io/jmatthews@thegreatacademy.org",
      method: "POST",
      data: $(this).serialize(),
      dataType: 'json',
    });
  });

});
<commit_msg>changed formspree e-mail for test<commit_after>
/**
 * Navigation
 */

/* Auto close navbar on click (mobile menu) */

$(".navbar-nav > li > a").click(function() {
    $(".navbar-collapse").collapse('hide');
});

/* Change navbar class on scroll */

$(".wrapper").waypoint(function() {
    $(".navbar").toggleClass("js-navbar-top");
    $(".navbar.js-toggleClass").toggleClass("navbar-default navbar-inverse");
    return false;
}, { offset: "-20px" });

/* Change navbar class on collapse/uncollapse in its top position */

$('.wrapper .navbar-collapse').on('show.bs.collapse', function () {
    $(".navbar.js-navbar-top").toggleClass("navbar-default navbar-inverse");
    $(".navbar").toggleClass("js-toggleClass js-noToggleClass");
});

$('.wrapper .navbar-collapse').on('hide.bs.collapse', function () {
    $(".navbar.js-navbar-top").toggleClass("navbar-default navbar-inverse");
    $(".navbar").toggleClass("js-toggleClass js-noToggleClass");
});

/* Sidebar */

$(".js-toggle-sidebar").on('click', function() {
    $(".wrapper").toggleClass("js-wrapper-aside");
    $(".navbar").toggleClass("js-navbar-aside");
    $(".sidebar").toggleClass("js-sidebar-aside");
    return false;
});

/**
 * Smooth scroll to anchor
 */

$(function() {
    $('a[href*=#]:not([href=#])').click(function() {
        if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
            var target = $(this.hash);
            target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
            if (target.length) {
                $('html,body').animate({
                    scrollTop: (target.offset().top - 70) // 70px offset for navbar menu
                }, 1000);
                return false;
            }
        }
    });
});

// Bootstrap Custom JS
$(document).ready(function() {

  // Tooltip opt-in
  $('[data-toggle="tooltip"]').tooltip()

  // Carousel controls
  $('.carousel-control.left').click(function() {
    $('#myCarousel').carousel('prev');
  });

  $('.carousel-control.right').click(function() {
    $('#myCarousel').carousel('next');
  });

  // About Us Show full Bio
  $('#jmbutton').click(function () {
    $('#jmbio').collapse('toggle');
  });
  $('#kmbutton').click(function () {
    $('#kmbio').collapse('toggle');
  });
  $('#dpbutton').click(function () {
    $('#dpbio').collapse('toggle');
  });
  $('#dgbutton').click(function () {
    $('#dgbio').collapse('toggle');
  });

  // Hide full Bio details
  $('body').click(function() {
    $('.collapse').collapse('hide');
  });

});

/**
 * Own carousel :: Sponsors
 */

// $(document).ready(function() {
//   var owl = $('.owl-carousel');
//   owl.owlCarousel({
//       items:4,
//       loop:true,
//       margin:5,
//       responsiveBaseElement:".owl-wrapper",
//       autoplay:true,
//       autoplayTimeout:1000,
//       autoplayHoverPause:true
//   });
// });
/**
 * Doughnut charts :: Skills
 */

/* Base donut styles */

// $.fn.peity.defaults.donut = {
//     delimiter: null,
//     fill: ["#F67280", "#eee"],
//     height: null,
//     innerRadius: 68,
//     radius: 70,
//     width: null
// };

/* Animating donuts */

// $(document).ready(function() {
//     $(".js-skills__item_first").waypoint(function() {
//
//         setTimeout(function () {
//             $('.skills__item').css("visibility", "visible");
//         }, 11);
//
//         $('.skills-item__donut').each(function () {
//             var $this = $(this);
//
//             var updateChart = $this.peity('donut');
//             var text = "";
//             var i = 0;
//             var str = $this.html();
//             var arr = str.split("/");
//             var value = arr[0];
//             var maxValue = arr[1];
//             var step = value/100;
//
//             function myLoop() {
//                 setTimeout(function () {
//
//                     text = i + "/" + maxValue;
//
//                     updateChart.text(text)
//                         .change()
//
//                     i = i + step;
//
//                     if (i <= value) myLoop();
//
//                 }, 10)
//             }
//             myLoop();
//         });
//
//         this.destroy();
//
//     }, { offset: 'bottom-in-view' });
// });

// Wow Plugins

$(".wow").each(function() {
    var wowHeight = $(this).height();
    $(this).attr("data-wow-offset", wowHeight);
});

new WOW().init();

// E-mail submittal to Formspree
$(document).ready(function() {

  $( "#form" ).submit(function( event ) {
    $.ajax({
      url: "//formspree.io/darrenjack79@yahoo.com",
      method: "POST",
      data: $(this).serialize(),
      dataType: 'json',
    });
  });

});
<|endoftext|>


<commit_before>/* global d3 */
;(function () {
  'use strict'

  // inspired by http://bl.ocks.org/mbostock/3902569
  ;[
    'repos',
    'events'
  ].forEach(function (type) {
    d3.json('/public/data/' + type + '-per-week.json', function (error, data) {
      if (error) {
        console.log(error)
      }

      var margin = {top: 20, right: 50, bottom: 30, left: 50}
      var width = 960 - margin.left - margin.right
      var height = 500 - margin.top - margin.bottom
      var parseDate = d3.time.format('%d-%b-%y').parse
      var bisectDate = d3.bisector(function (d) { return d.date }).left
      var formatDate = function (d) {
        return d[ type ] + ' ' + type + ' in the week of ' + d.formatted_date
      }

      var x = d3.time.scale().range([0, width])
      var y = d3.scale.linear().range([height, 0])
      var xAxis = d3.svg.axis().scale(x).orient('bottom')
      var yAxis = d3.svg.axis().scale(y).orient('left')

      var line = d3.svg.line()
        .x(function (d) { return x(d.date) })
        .y(function (d) { return y(d[ type ]) })

      var svg = d3.select('#' + type + '-per-week').append('svg')
        .attr('width', width + margin.left + margin.right)
        .attr('height', height + margin.top + margin.bottom)
        .append('g')
        .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')

      data.forEach(function (d) {
        d.date = parseDate(d.date)
        d[ type ] = +d[ type ]
      })

      data.sort(function (a, b) {
        return a.date - b.date
      })

      x.domain([data[0].date, data[data.length - 1].date])
      y.domain(d3.extent(data, function (d) {
        return d[ type ]
      }))

      svg.append('g')
        .attr('class', 'x axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(xAxis)

      svg.append('g')
        .attr('class', 'y axis')
        .call(yAxis)
        .append('text')
        .attr('transform', 'rotate(-90)')
        .attr('y', 6)
        .attr('dy', '.71em')
        .style('text-anchor', 'end')
        .text('No. of ' + type)

      svg.append('path')
        .datum(data)
        .attr('class', 'line')
        .attr('d', line)

      var focus = svg.append('g')
        .attr('class', 'focus')
        .style('display', 'block')

      focus.append('circle')
        .attr('r', 7)

      focus.append('text')
        .attr('x', 9)
        .attr('dx', '-8em')
        .attr('dy', '1.5em')

      svg.append('rect')
        .attr('class', 'overlay')
        .attr('width', width)
        .attr('height', height)
        .on('mouseover', function () { focus.style('display', null) })
        .on('mouseout', function () { focus.style('display', 'none') })
        .on('mousemove', mousemove)

      function mousemove () {
        var x0 = x.invert(d3.mouse(this)[0])
        var i = bisectDate(data, x0, 1)
        var d0 = data[i - 1]
        var d1 = data[i]
        var d = x0 - d0.date > d1.date - x0 ? d1 : d0

        focus.attr('transform', 'translate(' + x(d.date) + ',' + y(d[ type ]) + ')')
        focus
          .select('text')
          .text(formatDate(d))
          .attr('class', 'label')
      }
    })
  })
})()
<commit_msg>refactor: shorter x axis name<commit_after>/* global d3 */
;(function () {
  'use strict'

  // inspired by http://bl.ocks.org/mbostock/3902569
  ;[
    'repos',
    'events'
  ].forEach(function (type) {
    d3.json('/public/data/' + type + '-per-week.json', function (error, data) {
      if (error) {
        console.log(error)
      }

      var margin = {top: 20, right: 50, bottom: 30, left: 50}
      var width = 960 - margin.left - margin.right
      var height = 500 - margin.top - margin.bottom
      var parseDate = d3.time.format('%d-%b-%y').parse
      var bisectDate = d3.bisector(function (d) { return d.date }).left
      var formatDate = function (d) {
        return d[ type ] + ' ' + type + ' in the week of ' + d.formatted_date
      }

      var x = d3.time.scale().range([0, width])
      var y = d3.scale.linear().range([height, 0])
      var xAxis = d3.svg.axis().scale(x).orient('bottom')
        .tickFormat(function (d) {
          console.log(d)
          return d.toString().substring(4, 7) + '\'' + d.toString().substring(13, 15)
        })
      var yAxis = d3.svg.axis().scale(y).orient('left')

      var line = d3.svg.line()
        .x(function (d) { return x(d.date) })
        .y(function (d) { return y(d[ type ]) })

      var svg = d3.select('#' + type + '-per-week').append('svg')
        .attr('width', width + margin.left + margin.right)
        .attr('height', height + margin.top + margin.bottom)
        .append('g')
        .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')

      data.forEach(function (d) {
        d.date = parseDate(d.date)
        d[ type ] = +d[ type ]
      })

      data.sort(function (a, b) {
        return a.date - b.date
      })

      x.domain([data[0].date, data[data.length - 1].date])
      y.domain(d3.extent(data, function (d) {
        return d[ type ]
      }))

      svg.append('g')
        .attr('class', 'x axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(xAxis)

      svg.append('g')
        .attr('class', 'y axis')
        .call(yAxis)
        .append('text')
        .attr('transform', 'rotate(-90)')
        .attr('y', 6)
        .attr('dy', '.71em')
        .style('text-anchor', 'end')
        .text('No. of ' + type)

      svg.append('path')
        .datum(data)
        .attr('class', 'line')
        .attr('d', line)

      var focus = svg.append('g')
        .attr('class', 'focus')
        .style('display', 'block')

      focus.append('circle')
        .attr('r', 7)

      focus.append('text')
        .attr('x', 9)
        .attr('dx', '-8em')
        .attr('dy', '1.5em')

      svg.append('rect')
        .attr('class', 'overlay')
        .attr('width', width)
        .attr('height', height)
        .on('mouseover', function () { focus.style('display', null) })
        .on('mouseout', function () { focus.style('display', 'none') })
        .on('mousemove', mousemove)

      function mousemove () {
        var x0 = x.invert(d3.mouse(this)[0])
        var i = bisectDate(data, x0, 1)
        var d0 = data[i - 1]
        var d1 = data[i]
        var d = x0 - d0.date > d1.date - x0 ? d1 : d0

        focus.attr('transform', 'translate(' + x(d.date) + ',' + y(d[ type ]) + ')')
        focus
          .select('text')
          .text(formatDate(d))
          .attr('class', 'label')
      }
    })
  })
})()
<|endoftext|>


<commit_before>const mongoose = require('mongoose')
const Schema = mongoose.Schema
const ObjectId = Schema.ObjectId
const _ = require('lodash')

//Models
var models = {
  History: () => {
    //Model info
    var collectionName = 'history'
    var modelName = 'History'
    var model =  {
      user: {
        type: ObjectId,
        required: false
      },
      solveType: {
        type: String,
        required: true,
        enum: ['mathjs', 'wolfram']
      }
      query: {
        type: String,
        required: true
      },
      result: {
        type: String,
        required: true
      },
      date: {
        type: Date,
        default: Date.now
      }
    }

    //Define Schema
    var dataSchema = mongoose.Schema(model, {collection: collectionName})

    //Define hooks
    dataSchema.pre('save', function(next){
      next()
    })

    //return Schema and Model Name
    return {
      schema: dataSchema,
      name: modelName
    }
  },
  User: () => {
    //Model info
    var collectionName = ''
    var modelName = ''
    var model = {
      email: {
        type: String,
        required: true
      },
      name: {
        type: String,
        required: false,
      },
      password: {
        type: String,
        required: true
      },
      date_registered: {
        type: Date,
        default: Date.now
      }
    }

    //Define Schema
    var dataSchema = mongoose.Schema(model, {collection: collectionName})

    //Define hooks
    dataSchema.pre('save', function(next){
      next()
    })

    //return Schema and Model Name
    return {
      schema: dataSchema,
      name: modelName
    }
  }

}

module.exports = () => _.mapValue(models, (value, key) => {
  var model = value()
  return mongoose.model(model.modelName, model.schema)
})
<commit_msg>Changed mongoose initialization process to make sure every module can import it form main file<commit_after>const _ = require('lodash')
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const ObjectId = Schema.Types.ObjectId
const Mixed = Schema.Types.Mixed
const mongoAddress = 'mongodb://localhost'
mongoose.connect(mongoAddress)

//Models
var models = {
  History: () => {
    //Model info
    var collectionName = 'history'
    var modelName = 'History'
    var model =  {
      user: {
        type: ObjectId,
        required: false
      },
      solveType: {
        type: String,
        required: true,
        enum: ['mathjs', 'wolfram']
      },
      query: {
        type: String,
        required: true
      },
      result: {
        type: Mixed,
        required: true
      },
      date: {
        type: Date,
        default: Date.now
      },
      active: {
        type: Boolean,
        default: true
      }
    }

    //Define Schema
    var dataSchema = mongoose.Schema(model, {collection: collectionName})

    //Define hooks
    dataSchema.pre('save', function(next){
      next()
    })

    //return Schema and Model Name
    return {
      schema: dataSchema,
      name: modelName
    }
  }
  // User: () => {
  //   //Model info
  //   var collectionName = ''
  //   var modelName = ''
  //   var model = {
  //     email: {
  //       type: String,
  //       required: true
  //     },
  //     name: {
  //       type: String,
  //       required: false,
  //     },
  //     password: {
  //       type: String,
  //       required: true
  //     },
  //     date_registered: {
  //       type: Date,
  //       default: Date.now
  //     }
  //   }
  //
  //   //Define Schema
  //   var dataSchema = mongoose.Schema(model, {collection: collectionName})
  //
  //   //Define hooks
  //   dataSchema.pre('save', function(next){
  //     next()
  //   })
  //
  //   //return Schema and Model Name
  //   return {
  //     schema: dataSchema,
  //     name: modelName
  //   }
  // }
}

module.exports = () => {

  var compiled = _.mapValues(models, (value, key) => {
    var model = value()
    return mongoose.model(model.modelName, model.schema)
  })

  return {
    models: compiled,
    mongoose: mongoose
  }
}
<|endoftext|>


<commit_before>(function() {

// Localize jQuery variable
var jQuery
var baseURL = "//oghma.herokuapp.com";

/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '2.1.1') {
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type","text/javascript");
    script_tag.setAttribute("src",
        "//code.jquery.com/jquery-2.1.1.min.js");
    if (script_tag.readyState) {
      script_tag.onreadystatechange = function () { // For old versions of IE
          if (this.readyState == 'complete' || this.readyState == 'loaded') {
              scriptLoadHandler();
          }
      };
    } else { // Other browsers
      script_tag.onload = scriptLoadHandler;
    }
    // Try to find the head, otherwise default to the documentElement
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
    // The jQuery version on the window is the one we want to use
    jQuery = window.jQuery;
    main();
}

/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
    // Restore $ and window.jQuery to their previous values and store the
    // new jQuery in our local jQuery variable
    jQuery = window.jQuery.noConflict(true);
    // Call our main function
    main();
}

/******** Our main function ********/
function main() {
    jQuery(document).ready(function($)
    {
        $.urlParam = function(name, url) {
            var results = new RegExp('[?|&|#]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(url);
            return results[1] || 0;
        }

        $.loadCSS = function(href) {
            var cssLink = $("<link rel='stylesheet' type='text/css' href='"+href+"'>");
            $("head").append(cssLink);
        }

        $.findJS = function() {
            var elems = document.getElementsByTagName('script');
            var re = /.*oghma-chat\.js/;

            for(var i = 0; i < elems.length; i++) {
                if(elems[i].src.match(re))
                    return elems[i];
            }

            throw "Could not find the script from Oghma.";
        }

        $.getSettings = function() {
            var el = $.findJS();
            var params = ['token'];
            var settings = new Object();

            for(var i = 0; i < params.length; i++) {
                var p = params[i];
                settings[p] = $.urlParam(p, el.src);
            }

            if (typeof window._LBSettings != 'undefined') {
                for (var attrname in window._LBSettings) {
                    settings[attrname] = window._LBSettings[attrname];
                }
            }

            return settings;
        }

        $.createButton = function() {
            var button = $('

');
            $("body").append(button);
        }

        $.loadJS = function(href) {
            var jsLink = $("");
            $("head").append(jsLink);
        }

        $.scrollChat = function(to) {
            $(to).animate({
                scrollTop: $(to).height()
            }, 'slow');
        }

        /**
        * Set cookie with name @var cookie with value @var value for @var days period.
        */
        $.setCookie = function(cookie, value, days) {
            days = days || 730; // 2 years

            var date = new Date();
            date.setTime(date.getTime() + (days*24*60*60*1000));

            // Set Cookie
            document.cookie = cookie + "=" + value + "; expires=" + date.toGMTString() + "; path=/";
        }

        /**
        * Get a cookie named @var cookie
        */
        $.getCookie(name) {
            var value = " " + document.cookie;
            var start = value.indexOf(" " + name + "=");
            if (start == -1) {
                value = null;
            }
            else {
                start = value.indexOf("=", start) + 1;
                var end = value.indexOf(";", start);
                if (end == -1) {
                    end = value.length;
                }
                value = unescape(value.substring(start,end));
            }
            return value;
        }

        /**
        * Gets the UUID for this user. If doesn't exist, creates a new UUID.
        */

        $.getUUID = function() {
            var cookieName = "oghma-uuid";
            if($.getCookie(cookieName) === null) {
                // Does not exists; Lets create a UUID for this user
                $.loadJS(baseURL + "/js/uuid.js");
                var cuuid = uuid.v4();
                $.setCookie(cookieName, cuuid);

                return cuuid;
            }
            return $.getCookie(cookieName);
        }

        $.loadCSS(baseURL + "/css/chat-styles.css");
        $.loadJS( baseURL + "/socket.io/socket.io.js");

        $.createButton();

        $('#oghma-button').click(function() {

            var settings = $.getSettings();

            console.log("Token: " + settings.token);

            var messages = [];

            var messageField = document.getElementById('messageField');
            var content = document.getElementById('conversation');
            var ENTER_KEY_CODE = 13;

            // If they exist.
            var channel   = $.getCookie('oghma-channel');
            var signature = $.getCookie('oghma-signature');

            $.ajax({
                url: baseURL + "/chat/create",
                method: 'POST',
                data: {
                    token:     settings.token,
                    channel:   channel,
                    signature: signature
                },
                success: function(data) {

                    console.log(data);

                    // Save connection to cookies
                    $.setCookie('oghma-channel',   data.channel);
                    $.setCookie('oghma-signature', data.signature);

                    var socket = io.connect("http:" + baseURL + '/chat');

                    var domContent = [
                        '',
                        '
Chat
',
                        '

',
                        '       <input type="text" name="message">',
                        '   ',
                        ].join('');

                    $('body').append(domContent);

                    $.scrollChat('#cbp-spmenu-s2 ul');

                    $('#cbp-spmenu-s2').toggleClass('cbp-spmenu-open' );

                    $('#cbp-spmenu-s2 input').bind('keypress', function(e){
                        // if enter key
                        if (e.keyCode == ENTER_KEY_CODE && $(this).val() != "") {
                            var message = $(this).val();

                            socket.emit('noncryptSend', {
                                message: message,
                            });

                            console.log("SEND: " + message);
                            $('#cbp-spmenu-s2 ul').append('
' + message + '
');

                            $.scrollChat('#cbp-spmenu-s2 ul');

                            $(this).val(''); // clear message field after sending
                        }
                    });

                    socket.on('connect', function(){
                        console.log("Connected to " + data.channel);
                        socket.emit('joinRoom', settings.token, data.channel, data.signature);
                    });

                    // On message
                    socket.on('noncryptMessage', function (data) {
                        if(data.sender == "Other") {
                            $('#cbp-spmenu-s2 ul').append('
' + data.message + '
');
                            $.scrollChat('#cbp-spmenu-s2 ul');
                        }
                    });

                    socket.on('serverMessage', function (data) {
                        $('#cbp-spmenu-s2 ul').append('
Server: ' + data.message + '
');
                        $.scrollChat('#cbp-spmenu-s2 ul');
                    });
                }
            });

            // Get Channel from LB API with token
            // If no users online (not possible right now in Slack) show form for e-mail message.
            // Else create chat window and connect socket

        });

    });
}

})(); // We call our anonymous function immediately
<commit_msg>getCookies error<commit_after>(function() {

// Localize jQuery variable
var jQuery
var baseURL = "//oghma.herokuapp.com";

/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '2.1.1') {
    var script_tag = document.createElement('script');
    script_tag.setAttribute("type","text/javascript");
    script_tag.setAttribute("src",
        "//code.jquery.com/jquery-2.1.1.min.js");
    if (script_tag.readyState) {
      script_tag.onreadystatechange = function () { // For old versions of IE
          if (this.readyState == 'complete' || this.readyState == 'loaded') {
              scriptLoadHandler();
          }
      };
    } else { // Other browsers
      script_tag.onload = scriptLoadHandler;
    }
    // Try to find the head, otherwise default to the documentElement
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
    // The jQuery version on the window is the one we want to use
    jQuery = window.jQuery;
    main();
}

/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
    // Restore $ and window.jQuery to their previous values and store the
    // new jQuery in our local jQuery variable
    jQuery = window.jQuery.noConflict(true);
    // Call our main function
    main();
}

/******** Our main function ********/
function main() {
    jQuery(document).ready(function($)
    {
        $.urlParam = function(name, url) {
            var results = new RegExp('[?|&|#]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(url);
            return results[1] || 0;
        }

        $.loadCSS = function(href) {
            var cssLink = $("<link rel='stylesheet' type='text/css' href='"+href+"'>");
            $("head").append(cssLink);
        }

        $.findJS = function() {
            var elems = document.getElementsByTagName('script');
            var re = /.*oghma-chat\.js/;

            for(var i = 0; i < elems.length; i++) {
                if(elems[i].src.match(re))
                    return elems[i];
            }

            throw "Could not find the script from Oghma.";
        }

        $.getSettings = function() {
            var el = $.findJS();
            var params = ['token'];
            var settings = new Object();

            for(var i = 0; i < params.length; i++) {
                var p = params[i];
                settings[p] = $.urlParam(p, el.src);
            }

            if (typeof window._LBSettings != 'undefined') {
                for (var attrname in window._LBSettings) {
                    settings[attrname] = window._LBSettings[attrname];
                }
            }

            return settings;
        }

        $.createButton = function() {
            var button = $('

');
            $("body").append(button);
        }

        $.loadJS = function(href) {
            var jsLink = $("");
            $("head").append(jsLink);
        }

        $.scrollChat = function(to) {
            $(to).animate({
                scrollTop: $(to).height()
            }, 'slow');
        }

        /**
        * Set cookie with name @var cookie with value @var value for @var days period.
        */
        $.setCookie = function(cookie, value, days) {
            days = days || 730; // 2 years

            var date = new Date();
            date.setTime(date.getTime() + (days*24*60*60*1000));

            // Set Cookie
            document.cookie = cookie + "=" + value + "; expires=" + date.toGMTString() + "; path=/";
        }

        /**
        * Get a cookie named @var cookie
        */
        $.getCookie = function(name) {
            var value = " " + document.cookie;
            var start = value.indexOf(" " + name + "=");
            if (start == -1) {
                value = null;
            }
            else {
                start = value.indexOf("=", start) + 1;
                var end = value.indexOf(";", start);
                if (end == -1) {
                    end = value.length;
                }
                value = unescape(value.substring(start,end));
            }
            return value;
        }

        /**
        * Gets the UUID for this user. If doesn't exist, creates a new UUID.
        */

        $.getUUID = function() {
            var cookieName = "oghma-uuid";
            if($.getCookie(cookieName) === null) {
                // Does not exists; Lets create a UUID for this user
                $.loadJS(baseURL + "/js/uuid.js");
                var cuuid = uuid.v4();
                $.setCookie(cookieName, cuuid);

                return cuuid;
            }
            return $.getCookie(cookieName);
        }

        $.loadCSS(baseURL + "/css/chat-styles.css");
        $.loadJS( baseURL + "/socket.io/socket.io.js");

        $.createButton();

        $('#oghma-button').click(function() {

            var settings = $.getSettings();

            console.log("Token: " + settings.token);

            var messages = [];

            var messageField = document.getElementById('messageField');
            var content = document.getElementById('conversation');
            var ENTER_KEY_CODE = 13;

            // If they exist.
            var channel   = $.getCookie('oghma-channel');
            var signature = $.getCookie('oghma-signature');

            $.ajax({
                url: baseURL + "/chat/create",
                method: 'POST',
                data: {
                    token:     settings.token,
                    channel:   channel,
                    signature: signature
                },
                success: function(data) {

                    console.log(data);

                    // Save connection to cookies
                    $.setCookie('oghma-channel',   data.channel);
                    $.setCookie('oghma-signature', data.signature);

                    var socket = io.connect("http:" + baseURL + '/chat');

                    var domContent = [
                        '',
                        '
Chat
',
                        '

',
                        '       <input type="text" name="message">',
                        '   ',
                        ].join('');

                    $('body').append(domContent);

                    $.scrollChat('#cbp-spmenu-s2 ul');

                    $('#cbp-spmenu-s2').toggleClass('cbp-spmenu-open' );

                    $('#cbp-spmenu-s2 input').bind('keypress', function(e){
                        // if enter key
                        if (e.keyCode == ENTER_KEY_CODE && $(this).val() != "") {
                            var message = $(this).val();

                            socket.emit('noncryptSend', {
                                message: message,
                            });

                            console.log("SEND: " + message);
                            $('#cbp-spmenu-s2 ul').append('
' + message + '
');

                            $.scrollChat('#cbp-spmenu-s2 ul');

                            $(this).val(''); // clear message field after sending
                        }
                    });

                    socket.on('connect', function(){
                        console.log("Connected to " + data.channel);
                        socket.emit('joinRoom', settings.token, data.channel, data.signature);
                    });

                    // On message
                    socket.on('noncryptMessage', function (data) {
                        if(data.sender == "Other") {
                            $('#cbp-spmenu-s2 ul').append('
' + data.message + '
');
                            $.scrollChat('#cbp-spmenu-s2 ul');
                        }
                    });

                    socket.on('serverMessage', function (data) {
                        $('#cbp-spmenu-s2 ul').append('
Server: ' + data.message + '
');
                        $.scrollChat('#cbp-spmenu-s2 ul');
                    });
                }
            });

            // Get Channel from LB API with token
            // If no users online (not possible right now in Slack) show form for e-mail message.
            // Else create chat window and connect socket

        });

    });
}

})(); // We call our anonymous function immediately
<|endoftext|>