<commit_before>import { getRandomInt } from '@utils/general.utils';
import * as StorageUtils from '@utils/storage.utils';
import cacheConfigs from '../configs/cache.config';
import categoriesConfig from '../configs/categories.config';

const categoriesBasePath = '../images/categories';
const localPhotosCacheKey = cacheConfigs.localPhotos;

/**
 * Gets the local photos object from cache if present.
 *
 * @return {Object} Photos object with `localPath` as the key
 */
function getLocalPhotosFromCache() {
    const localPhotos = StorageUtils.get(localPhotosCacheKey);

    // no local photos, return
    if (!localPhotos || !Object.keys(localPhotos).length) {
        return;
    }

    return localPhotos;
}

const categories = Object.keys(categoriesConfig);

// if the local photo paths are not populated
// dynamically import all locally stored photos json
// along with their paths and update the local storage
// to indicate they are available for the next usage
// storage format -> { 'local/path/to/photo' : {photo_json} }
!getLocalPhotosFromCache() && categories.forEach(c => {
    import(`${categoriesBasePath}/${c}.json`)
        .then(photos => {
            photos.forEach(p => {
                import(`${categoriesBasePath}/${c}/${p.id}.jpg`)
                    .then(path => StorageUtils.update(localPhotosCacheKey, {[path]: p}))
                    .catch(error => error)
            });
        }).catch(error => error);
});

/**
 * Extracts local path from the photo object.
 *
 * @param  {Object} photo   Photo object returned by the API
 * @return {String}         Local path to use
 */
export function getLocalPhotoPath(photo = {}) {
    return photo.localPath;
}

/**
 * Returns a random local photo object from the cache.
 * The returned photo object is extended with `localPath` property.
 *
 * @todo: accept param to allow getting
 * a random photo from specific category(ies)
 *
 * @return {Object}     Photo object as per the API
 */
export function getRandomLocalPhoto() {
    const localPhotos = getLocalPhotosFromCache();

    // no local photos, return
    if (!localPhotos) return;

    // there is at least one local photo, pick a random one
    // @todo: optimize randomness to favour least shown photo
    // one strategy would be to store the display timestamp
    // of each photo in the local storage and favour the
    // photos without a timestamp or the one with oldest timestamp
    const prefetchedPhotosIds = Object.keys(localPhotos);
    const selectedLocalPhotoPath = prefetchedPhotosIds[getRandomInt(0, prefetchedPhotosIds.length)];
    const randomLocalPhoto = localPhotos[selectedLocalPhotoPath];

    // add an extra property `localPath`
    // to indicate the locally stored location
    return { ...randomLocalPhoto, localPath: selectedLocalPhotoPath };
}
<commit_msg>:bug: Fix dynamic import for local background photos<commit_after>import { getRandomInt } from '@utils/general.utils';
import * as StorageUtils from '@utils/storage.utils';
import cacheConfigs from '../configs/cache.config';
import categoriesConfig from '../configs/categories.config';

const localPhotosCacheKey = cacheConfigs.localPhotos;

/**
 * Gets the local photos object from cache if present.
 *
 * @return {Object} Photos object with `localPath` as the key
 */
function getLocalPhotosFromCache() {
    const localPhotos = StorageUtils.get(localPhotosCacheKey);

    // no local photos, return
    if (!localPhotos || !Object.keys(localPhotos).length) {
        return;
    }

    return localPhotos;
}

const categories = Object.keys(categoriesConfig);

// if the local photo paths are not populated
// dynamically import all locally stored photos json
// along with their paths and update the local storage
// to indicate they are available for the next usage
// storage format -> { 'local/path/to/photo' : {photo_json} }
!getLocalPhotosFromCache() && categories.forEach(c => {
    // @todo: Investigate
    // cannot store ../images/categories as a variable
    // as the base path would not be identified by
    // webpack for some reason and import would fail
    import(`../images/categories/${c}.json`)
        .then(photos => {
            photos.forEach(p => {
                import(`../images/categories/${c}/${p.id}.jpg`)
                    .then(path => StorageUtils.update(localPhotosCacheKey, {[path]: p}))
                    .catch(error => error);
            });
        }).catch(error => error);
});

/**
 * Extracts local path from the photo object.
 *
 * @param  {Object} photo   Photo object returned by the API
 * @return {String}         Local path to use
 */
export function getLocalPhotoPath(photo = {}) {
    return photo.localPath;
}

/**
 * Returns a random local photo object from the cache.
 * The returned photo object is extended with `localPath` property.
 *
 * @todo: accept param to allow getting
 * a random photo from specific category(ies)
 *
 * @return {Object}     Photo object as per the API
 */
export function getRandomLocalPhoto() {
    const localPhotos = getLocalPhotosFromCache();

    // no local photos, return
    if (!localPhotos) return;

    // there is at least one local photo, pick a random one
    // @todo: optimize randomness to favour least shown photo
    // one strategy would be to store the display timestamp
    // of each photo in the local storage and favour the
    // photos without a timestamp or the one with oldest timestamp
    const prefetchedPhotosIds = Object.keys(localPhotos);
    const selectedLocalPhotoPath = prefetchedPhotosIds[getRandomInt(0, prefetchedPhotosIds.length)];
    const randomLocalPhoto = localPhotos[selectedLocalPhotoPath];

    // add an extra property `localPath`
    // to indicate the locally stored location
    return { ...randomLocalPhoto, localPath: selectedLocalPhotoPath };
}
<|endoftext|>


<commit_before>require('babel-register')
var config = require('../../config')

// http://nightwatchjs.org/gettingstarted#settings-file
module.exports = {
  src_folders: ['test/e2e/specs'],
  output_folder: 'test/e2e/reports',
  custom_assertions_path: ['test/e2e/custom-assertions'],

  selenium: {
    start_process: true,
    server_path: require('selenium-server').path,
    host: '127.0.0.1',
    port: 4444,
    cli_args: {
      'webdriver.chrome.driver': require('chromedriver').path
    }
  },

  test_settings: {
    default: {
      selenium_port: 4444,
      selenium_host: 'localhost',
      silent: false,
      globals: {
        devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
      }
    },

    chrome: {
      desiredCapabilities: {
        browserName: 'chrome',
        javascriptEnabled: true,
        acceptSslCerts: true,
        chromeOptions: {
          args: [
            '--disable-gpu --no-sandbox --window-size=1920,1080 --verbose'
          ]
        }
      }
    },

    chromeheadless: {
      silent: false,
      retry_attempts: 1,
      desiredCapabilities: {
        browserName: 'chrome',
        javascriptEnabled: true,
        acceptSslCerts: true,
        chromeOptions: {
          args: [
            '--disable-gpu --no-sandbox --headless --window-size=1920,1080 --verbose'
          ]
        }
      }
    },

    firefox: {
      desiredCapabilities: {
        browserName: 'firefox',
        javascriptEnabled: true,
        acceptSslCerts: true
      }
    }
  }
}
<commit_msg>Make Firefox e2e test non-silent and enable retry<commit_after>require('babel-register')
var config = require('../../config')

// http://nightwatchjs.org/gettingstarted#settings-file
module.exports = {
  src_folders: ['test/e2e/specs'],
  output_folder: 'test/e2e/reports',
  custom_assertions_path: ['test/e2e/custom-assertions'],

  selenium: {
    start_process: true,
    server_path: require('selenium-server').path,
    host: '127.0.0.1',
    port: 4444,
    cli_args: {
      'webdriver.chrome.driver': require('chromedriver').path
    }
  },

  test_settings: {
    default: {
      selenium_port: 4444,
      selenium_host: 'localhost',
      silent: false,
      globals: {
        devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
      }
    },

    chrome: {
      desiredCapabilities: {
        browserName: 'chrome',
        javascriptEnabled: true,
        acceptSslCerts: true,
        chromeOptions: {
          args: [
            '--disable-gpu --no-sandbox --window-size=1920,1080 --verbose'
          ]
        }
      }
    },

    chromeheadless: {
      silent: false,
      retry_attempts: 1,
      desiredCapabilities: {
        browserName: 'chrome',
        javascriptEnabled: true,
        acceptSslCerts: true,
        chromeOptions: {
          args: [
            '--disable-gpu --no-sandbox --headless --window-size=1920,1080 --verbose'
          ]
        }
      }
    },

    firefox: {
      silent: false,
      retry_attempts: 1,
      desiredCapabilities: {
        browserName: 'firefox',
        javascriptEnabled: true,
        acceptSslCerts: true
      }
    }
  }
}
<|endoftext|>


<commit_before>function initBookList() {
    var loader = $('#ajaxList').first();
    ajaxLoad(loader.attr('data-href'), loader.attr('href'));

    $(document).on('click', '#ajaxList', function (e) {
        e.preventDefault();
        var dataLink = $(this).attr('data-href');
        var tab = $('a[data-href="' + dataLink + '"]').attr('href');

        if (tab.length > 1) {
            ajaxLoad(dataLink, tab);
        } else {
            ajaxLoad(dataLink, $('.tab-pane.active'));
        }
    });
}

function ajaxLoad(url, tab) {
    $('.tab-content').addClass('hidden');

    $.ajax({
        type: 'GET',
        url: url,
        beforeSend: function () {
            $('.spinner').removeClass('hidden');
        }
    })
        .done(function (data) {
            $('.spinner').addClass('hidden');
            $(tab).html(data.list);
            $('.tab-content').removeClass('hidden');
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
            alert(errorThrown);
        });
}

$(document).ready(function () {/* off-canvas sidebar toggle */

    $('[data-toggle=offcanvas]').click(function () {
        $(this).toggleClass('visible-xs text-center');
        $(this).find('i').toggleClass('glyphicon-chevron-right glyphicon-chevron-left');
        $('.row-offcanvas').toggleClass('active');
        $('#lg-menu').toggleClass('hidden-xs').toggleClass('visible-xs');
        $('#xs-menu').toggleClass('visible-xs').toggleClass('hidden-xs');
        $('#btnShow').toggle();
    });
});
<commit_msg>Update ajax functions.<commit_after>function initBookList() {
    var loader = $('#ajaxList').first();
    ajaxLoad(loader.attr('data-href'), loader.attr('href'));

    $(document).on('click', '#ajaxList', function (e) {
        e.preventDefault();
        var dataLink = $(this).attr('data-href');
        var tab = $('a[data-href="' + dataLink + '"]').attr('href');

        if (tab.length > 1) {
            ajaxLoad(dataLink, tab);
        } else {
            ajaxLoad(dataLink, $('.tab-pane.active'));
        }
    });
}

function ajaxLoad(url, tab) {
    $('.tab-content').addClass('hidden');

    $.ajax({
        type: 'GET',
        url: url,
        beforeSend: function () {
            $('.spinner').removeClass('hidden');
        }
    })
        .done(function (data) {
            $('.spinner').addClass('hidden');
            $(tab).html(data.list);
            $('.tab-content').removeClass('hidden');
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
            alert(errorThrown);
        });
}

function initRating(rating) {
    $('i.rating').removeClass('text-success text-danger');
    if (rating == 1) {
        $('i.rating.glyphicon-thumbs-up').addClass('text-success');
        $('input[name="rating"]').val(1);
    } else {
        $('i.rating.glyphicon-thumbs-down').addClass('text-danger');
        $('input[name="rating"]').val(2);
    }
}

$(document).ready(function () {/* off-canvas sidebar toggle */
    $('[data-toggle=offcanvas]').click(function () {
        $(this).toggleClass('visible-xs text-center');
        $(this).find('i').toggleClass('glyphicon-chevron-right glyphicon-chevron-left');
        $('.row-offcanvas').toggleClass('active');
        $('#lg-menu').toggleClass('hidden-xs').toggleClass('visible-xs');
        $('#xs-menu').toggleClass('visible-xs').toggleClass('hidden-xs');
        $('#btnShow').toggle();
    });
});
<|endoftext|>


<commit_before>$.extend({
    api:{
        get_access_token:function(){
            return $("meta[name=access_token]").attr("content");
        },
        request:function(method,endpoint,params){
            return $.ajax({
                url:CONFIG.api+"/"+endpoint,
                type:method,
                data:params,
                headers:{
                    "X-Kyoppie-Access-Token":$.api.get_access_token()
                }
            })
        },
        get:function(endpoint,params){
            return $.api.request("GET",endpoint,params);
        },
        post:function(endpoint,params){
            return $.api.request("POST",endpoint,params);
        },
        websocket:function(endpoint){
            return new WebSocket(CONFIG.api.replace("http","ws")+"/"+endpoint+"?access_token="+$.api.get_access_token());
         }
    }
})
<commit_msg>add websocket ping<commit_after>$.extend({
    api:{
        get_access_token:function(){
            return $("meta[name=access_token]").attr("content");
        },
        request:function(method,endpoint,params){
            return $.ajax({
                url:CONFIG.api+"/"+endpoint,
                type:method,
                data:params,
                headers:{
                    "X-Kyoppie-Access-Token":$.api.get_access_token()
                }
            })
        },
        get:function(endpoint,params){
            return $.api.request("GET",endpoint,params);
        },
        post:function(endpoint,params){
            return $.api.request("POST",endpoint,params);
        },
        websocket:function(endpoint){
            var ws = new WebSocket(CONFIG.api.replace("http","ws")+"/"+endpoint+"?access_token="+$.api.get_access_token());
            var wsTimer = setInterval(function(){
                ws.send(JSON.stringify({type:"ping"}))
            },20*1000);
            ws.addEventListener("close",function(){
                clearInterval(wsTimer);
            })
            return ws
         }
    }
})
<|endoftext|>


<commit_before>pc.script.attribute('PLAYER_START_X', 'number', 0)
pc.script.attribute('PLAYER_START_Y', 'number', 10)
pc.script.attribute('PLAYER_START_Z', 'number', 0)

pc.script.attribute('thrust', 'number', 350)
pc.script.attribute('torque', 'number', 40)

pc.script.create('player', function (context) {

    var Player = function (entity) {
        // self-reference
        this.entity = entity

        // vectors
        this.thrustVec = new pc.Vec3()
    }

    Player.prototype = {
        initialize: function () {
            // start at reset position
            // this.reset()
        },

        update: function (dt) {
            // rotation control
            if (context.keyboard.isPressed(pc.input.KEY_A)) {
                this.entity.rigidbody.applyTorqueImpulse(0, 0, this.torque)
            }

            if (context.keyboard.isPressed(pc.input.KEY_D)) {
                this.entity.rigidbody.applyTorqueImpulse(0, 0, -this.torque)
            }

            // thrust control
            if (context.keyboard.isPressed(pc.input.KEY_SPACE)) {
                this.thrustVec.copy(this.entity.up).scale(this.thrust)
                this.entity.rigidbody.applyImpulse(this.thrustVec)
            }

            // player rest
            if (context.keyboard.isPressed(pc.input.KEY_ENTER)) {
                this.reset()
            }
        },

        reset: function () {
            this.entity.setPosition(this.PLAYER_START_X, this.PLAYER_START_Y, this.PLAYER_START_Z)
            this.entity.setEulerAngles(0, 0, 0)

            this.entity.rigidbody.syncEntityToBody()
            this.entity.rigidbody.linearVelocity = pc.Vec3.ZERO
            this.entity.rigidbody.angularVelocity = pc.Vec3.ZERO
        }
    }

    return Player
})
<commit_msg>Added Light entity to player script for detection<commit_after>pc.script.attribute('PLAYER_START_X', 'number', 0)
pc.script.attribute('PLAYER_START_Y', 'number', 10)
pc.script.attribute('PLAYER_START_Z', 'number', 0)

pc.script.attribute('thrust', 'number', 350)
pc.script.attribute('torque', 'number', 40)

pc.script.create('player', function (context) {

    var Player = function (entity) {
        // self-reference
        this.entity = entity

        // vectors
        this.thrustVec = new pc.Vec3()
    }

    Player.prototype = {
        initialize: function () {
            // start at reset position
            this.reset()

            // entities
            this.light = this.entity.findByName('Light')
        },

        update: function (dt) {
            var KEY_A_PRESSED = context.keyboard.isPressed(pc.input.KEY_A)
            var KEY_D_PRESSED = context.keyboard.isPressed(pc.input.KEY_D)
            var KEY_SPACE_PRESSED = context.keyboard.isPressed(pc.input.KEY_SPACE)
            var KEY_ENTER_PRESSED = context.keyboard.isPressed(pc.input.KEY_ENTER)

            // rotation control
            if (KEY_A_PRESSED || KEY_D_PRESSED)
                this.entity.rigidbody.applyTorqueImpulse(0, 0, (KEY_A_PRESSED ? +1 : -1) * this.torque)

            // thrust control
            this[(KEY_SPACE_PRESSED ? 'start' : 'stop') + 'Thrust']()

            // player rest
            if (KEY_ENTER_PRESSED) this.reset()
        },

        reset: function () {
            this.entity.setPosition(this.PLAYER_START_X, this.PLAYER_START_Y, this.PLAYER_START_Z)
            this.entity.setEulerAngles(0, 0, 0)

            this.entity.rigidbody.syncEntityToBody()
            this.entity.rigidbody.linearVelocity = pc.Vec3.ZERO
            this.entity.rigidbody.angularVelocity = pc.Vec3.ZERO
        },

        startThrust: function () {
            this.thrustVec.copy(this.entity.up).scale(this.thrust)
            this.entity.rigidbody.applyImpulse(this.thrustVec)

            if (!this.thrusting) {
                this.thrusting = true
                this.light.enabled = true
            }
        },

        stopThrust: function () {
            if (this.thrusting) {
                this.thrusting = false
                this.light.enabled = false
            }
        }
    }

    return Player
})
<|endoftext|>


<commit_before>
var semver = require('semver')
  , async = require('async')
  , fs = require('fs')
  , path = require('path')
  , exec = require("child_process").exec
  ;

exports._loadFiles = function (callback) {
  async.parallel({
    'pkg': function (done) {
      fs.readFile(path.join(process.cwd(), "package.json"), function (err, data) {
        done(null, data);
      });
    }

    , 'cpt': function (done) {
      fs.readFile(path.join(process.cwd(), "component.json"), function (err, data) {
        done(null, data);
      });
    }
  }, function (err, result) {
    var ret = {};

    if (!result.pkg && !result.cpt) {
      callback(new Error("Need one of package.json or component.json"));
      return void 0;
    }

    try {
      ret.pkg = JSON.parse(result.pkg)
    } catch (er) {
      ret.pkg = null;
    }

    try {
      ret.cpt = JSON.parse(result.cpt)
    } catch (er) {
      ret.cpt = null;
    }

    callback(null, ret);
  });
};

exports._saveFiles = function (pkg, cpt, callback) {
  // Save package/component file.
  async.parallel({
    'pkg': function (done) {
      if (!pkg) {
        return done(null, null);
      }

      fs.writeFile( path.join(process.cwd(), "package.json"),
          new Buffer(JSON.stringify(pkg, null, 2) + "\n"), function (err) {
            if (err) {
              return done(err);
            }
            done(null, "Updated package.json");
      });
    }

    , 'cpt': function (done) {
      if (!cpt) {
        return done(null, null);
      }
      fs.writeFile( path.join(process.cwd(), "component.json"),
          new Buffer(JSON.stringify(cpt, null, 2) + "\n"), function (err) {
            if (err) {
              return done(err);
            }
            done(null, "Updated component.json");
      });
    }
  }, callback);
};

var makeCommit = function (files, message, newVer, callback) {
    var git = 'git'
      , extra = {env: process.env}
      ;

    message = message.replace('%s', newVer);

    exec(git + " " + [ "status", "--porcelain" ].join(' '), extra, function (er, stdout, stderr) {

      var lines = stdout.trim().split("\n").filter(function (line) {
        return line.trim() && !line.match(/^\?\? /)
      }).map(function (line) {
        return line.trim()
      });

      if (lines.length) {
        return callback(new Error("Git working directory not clean.\n"+lines.join("\n")));
      }

      async.series(
        [
          function (done) {
            exec(git + " add " + files.join(' '), extra, done);
          }

          , function (done) {
            exec(git + " " + ["commit", "-m", message].join(' '), extra, done);
          }

          , function (done) {
            exec(git + " " + ["tag", "-", "v" + newVer, "-m", message].join(' '), extra, done);
          }
        ]
        , callback
      );
    });
  }
;

exports.get = function (callback) {
  exports._loadFiles(function(err, result) {
    var v1, v2, ret = {};

    if (err) {
      callback(err);
      return void 0;
    }

    v1 = result.pkg;
    v2 = result.cpt;

    if (v1 && v1.version) {
      ret['package.json'] = v1.version;
    }

    if (v2 && v2.version) {
      ret['component.json'] = v2.version;
    }

    callback(null, ret);
  });
};

exports.update = function (ver, commitMessage, callback) {
  var validVer = semver.valid(ver);
  ver = ver.toLowerCase();

  if (!callback && commitMessage && typeof commitMessage  === 'function') {
    callback = commitMessage;
    commitMessage = null;
  }
  if (!callback) {
    callback = function () { };
  }

  exports._loadFiles(function(err, result) {
    var pkg = result.pkg
      , cpt = result.cpt
      , currentVer = pkg ? pkg.version : cpt.version;

    if (err) {
      callback(err);
      return void 0;
    }

    if (validVer === null) {
      validVer = semver.inc(currentVer, ver);
    }

    if (validVer === null) {
      callback(new Error('No valid version given.'));
      return void 0;
    }

    if (pkg && pkg.version) {
      pkg.version = validVer;
    }
    if (cpt && cpt.version) {
      cpt.version = validVer;
    }

    exports._saveFiles(pkg, cpt, function (err, data) {
      var ret = {newVersion: validVer, versions: {}, message: []}
        , files = [];

      if (err) {
        callback(err);
        return void 0;
      }

      if (data.pkg) {
        ret.message.push(data.pkg);
      }
      if (data.cpt) {
        ret.message.push(data.cpt);
      }
      ret.message = ret.message.join("\n");

      if (pkg && pkg.version) {
        ret.versions['package.json'] = pkg.version;
        files.push('package.json');
      }

      if (cpt && cpt.version) {
        ret.versions['component.json'] = cpt.version;
        files.push('component.json');
      }

      if (!commitMessage) {
        callback(null, ret);
        return void 0;
      }

      makeCommit(files, commitMessage, validVer, function (err) {
        if (err) {
          callback(err);
          return void 0;
        }

        callback(null, ret);
      });
    });
  });
};<commit_msg>Ignoring package/component when checking git<commit_after>
var semver = require('semver')
  , async = require('async')
  , fs = require('fs')
  , path = require('path')
  , exec = require("child_process").exec
  ;

exports._loadFiles = function (callback) {
  async.parallel({
    'pkg': function (done) {
      fs.readFile(path.join(process.cwd(), "package.json"), function (err, data) {
        done(null, data);
      });
    }

    , 'cpt': function (done) {
      fs.readFile(path.join(process.cwd(), "component.json"), function (err, data) {
        done(null, data);
      });
    }
  }, function (err, result) {
    var ret = {};

    if (!result.pkg && !result.cpt) {
      callback(new Error("Need one of package.json or component.json"));
      return void 0;
    }

    try {
      ret.pkg = JSON.parse(result.pkg)
    } catch (er) {
      ret.pkg = null;
    }

    try {
      ret.cpt = JSON.parse(result.cpt)
    } catch (er) {
      ret.cpt = null;
    }

    callback(null, ret);
  });
};

exports._saveFiles = function (pkg, cpt, callback) {
  // Save package/component file.
  async.parallel({
    'pkg': function (done) {
      if (!pkg) {
        return done(null, null);
      }

      fs.writeFile( path.join(process.cwd(), "package.json"),
          new Buffer(JSON.stringify(pkg, null, 2) + "\n"), function (err) {
            if (err) {
              return done(err);
            }
            done(null, "Updated package.json");
      });
    }

    , 'cpt': function (done) {
      if (!cpt) {
        return done(null, null);
      }
      fs.writeFile( path.join(process.cwd(), "component.json"),
          new Buffer(JSON.stringify(cpt, null, 2) + "\n"), function (err) {
            if (err) {
              return done(err);
            }
            done(null, "Updated component.json");
      });
    }
  }, callback);
};

var makeCommit = function (files, message, newVer, callback) {
    var git = 'git'
      , extra = {env: process.env}
      ;

    message = message.replace('%s', newVer);

    exec(git + " " + [ "status", "--porcelain" ].join(' '), extra, function (er, stdout, stderr) {

      var lines = stdout.trim().split("\n").filter(function (line) {
        return line.trim() && !line.match(/^\?\? /)
                  && line.indexOf('package.json') === -1
                  && line.indexOf('component.json') === -1
      }).map(function (line) {
        return line.trim()
      });

      if (lines.length) {
        return callback(new Error("Git working directory not clean.\n"+lines.join("\n")));
      }

      async.series(
        [
          function (done) {
            exec(git + " add " + files.join(' '), extra, done);
          }

          , function (done) {
            exec(git + " " + ["commit", "-m", message].join(' '), extra, done);
          }

          , function (done) {
            exec(git + " " + ["tag", "-", "v" + newVer, "-m", message].join(' '), extra, done);
          }
        ]
        , callback
      );
    });
  }
;

exports.get = function (callback) {
  exports._loadFiles(function(err, result) {
    var v1, v2, ret = {};

    if (err) {
      callback(err);
      return void 0;
    }

    v1 = result.pkg;
    v2 = result.cpt;

    if (v1 && v1.version) {
      ret['package.json'] = v1.version;
    }

    if (v2 && v2.version) {
      ret['component.json'] = v2.version;
    }

    callback(null, ret);
  });
};

exports.update = function (ver, commitMessage, callback) {
  var validVer = semver.valid(ver);
  ver = ver.toLowerCase();

  if (!callback && commitMessage && typeof commitMessage  === 'function') {
    callback = commitMessage;
    commitMessage = null;
  }
  if (!callback) {
    callback = function () { };
  }

  exports._loadFiles(function(err, result) {
    var pkg = result.pkg
      , cpt = result.cpt
      , currentVer = pkg ? pkg.version : cpt.version;

    if (err) {
      callback(err);
      return void 0;
    }

    if (validVer === null) {
      validVer = semver.inc(currentVer, ver);
    }

    if (validVer === null) {
      callback(new Error('No valid version given.'));
      return void 0;
    }

    if (pkg && pkg.version) {
      pkg.version = validVer;
    }
    if (cpt && cpt.version) {
      cpt.version = validVer;
    }

    exports._saveFiles(pkg, cpt, function (err, data) {
      var ret = {newVersion: validVer, versions: {}, message: []}
        , files = [];

      if (err) {
        callback(err);
        return void 0;
      }

      if (data.pkg) {
        ret.message.push(data.pkg);
      }
      if (data.cpt) {
        ret.message.push(data.cpt);
      }
      ret.message = ret.message.join("\n");

      if (pkg && pkg.version) {
        ret.versions['package.json'] = pkg.version;
        files.push('package.json');
      }

      if (cpt && cpt.version) {
        ret.versions['component.json'] = cpt.version;
        files.push('component.json');
      }

      if (!commitMessage) {
        callback(null, ret);
        return void 0;
      }

      makeCommit(files, commitMessage, validVer, function (err) {
        if (err) {
          callback(err);
          return void 0;
        }

        callback(null, ret);
      });
    });
  });
};<|endoftext|>


<commit_before>/**
 *    Copyright (C) 2015 Deciso B.V.
 *
 *    All rights reserved.
 *
 *    Redistribution and use in source and binary forms, with or without
 *    modification, are permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 *    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 *    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *    AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 *    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *    POSSIBILITY OF SUCH DAMAGE.
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *    User interface shared components, requires opnsense.js for supporting functions.
 */

/**
 * save form to server
 * @param url endpoint url
 * @param formid parent id to grep input data from
 * @param disable_dialog don't show input validation message box on failure
 */
function saveFormToEndpoint(url,formid,callback_ok, disable_dialog) {
    disable_dialog = disable_dialog || false;
    var data = getFormData(formid);
    ajaxCall(url=url,sendData=data,callback=function(data,status){
        if ( status == "success") {
            // update field validation
            handleFormValidation(formid,data['validations']);

            // if there are validation issues, update our screen and show a dialog.
            if (data['validations'] != undefined) {
                if (!disable_dialog) {
                    // validation message box is optional, form is already updated using handleFormValidation
                    BootstrapDialog.show({
                        type:BootstrapDialog.TYPE_WARNING,
                        title: 'Input validation',
                        message: 'Please correct validation errors in form',
                        buttons: [{
                            label: 'Dismiss',
                            action: function(dialogRef){
                                dialogRef.close();
                            }
                        }]

                    });
                }
            } else if ( callback_ok != undefined ) {
                // execute callback function
                callback_ok();
            }

        } else {
            // error handling, show internal errors
            // Normally the form should only return validation issues, if other things go wrong throw an error.
            BootstrapDialog.show({
                type: BootstrapDialog.TYPE_ERROR,
                title: 'save',
                message: 'Unable to save data, an internal error occurred.
 ' +
                'Response from server was:
 '+JSON.stringify(data)+''
            });
        }

    });
}

/**
 * standard data mapper to map json request data to forms on this page
 * @param data_get_map named array containing form names and source url's to get data from {'frm_example':"/api/example/settings/get"};
 * @return promise object, resolves when all are loaded
 */
function mapDataToFormUI(data_get_map) {
    var dfObj = new $.Deferred();

    // calculate number of items for deferred object to resolve
    var data_map_seq = 1;
    var data_map_count = 0;
    $.each(data_get_map, function(){
        data_map_count += 1;
    });

    var collected_data = {};
    $.each(data_get_map, function(data_index, data_url) {
        ajaxGet(url=data_url,sendData={}, callback=function(data, status) {
            if (status == "success") {
                $("form").each(function( index ) {
                    if ( $(this).attr('id').split('-')[0] == data_index) {
                        // related form found, load data
                        setFormData($(this).attr('id'), data);
                        collected_data[$(this).attr('id')] = data;
                    }
                });
            }
            if (data_map_seq == data_map_count) {
                dfObj.resolve(collected_data);
            }
            data_map_seq += 1;
        });
    });

    return dfObj;
}

/**
 * update service status buttons in user interface
 */
function updateServiceStatusUI(status) {

    var status_html = '';

    if (status == "running") {
        status_html += '' ;
    } else if (status == "stopped") {
        status_html += '' ;
    } else {
        status_html += '' ;
    }

    status_html += '  ';

    $('#service_status_container').html(status_html);
}

/**
 * reformat all tokenizers on this document
 */
function formatTokenizersUI(){
    $('select[class="tokenize"]').each(function(){
        if ($(this).prop("size")==0) {
            maxDropdownHeight=String(36*5)+"px"; // default number of items

        } else {
            number_of_items = $(this).prop("size");
            maxDropdownHeight=String(36*number_of_items)+"px";
        }
        hint=$(this).data("hint");
        width=$(this).data("width");
        allownew=$(this).data("allownew");
        maxTokenContainerHeight=$(this).data("maxheight");

        $(this).tokenize({
            displayDropdownOnFocus: true,
            newElements: allownew,
            placeholder:hint
        });
        $(this).parent().find('ul[class="TokensContainer"]').parent().css("width",width);
        $(this).parent().find('ul[class="Dropdown"]').css("max-height", maxDropdownHeight);
        if ( maxDropdownHeight != undefined ) {
            $(this).parent().find('ul[class="TokensContainer"]').css("max-height", maxTokenContainerHeight);
        }
    });
}

/**
 * clear multiselect boxes on click event, works on standard and tokenized versions
 */
function addMultiSelectClearUI() {
    $('[id*="clear-options"]').each(function() {
        $(this).click(function() {
            var id = $(this).attr("for");
            BootstrapDialog.confirm({
                title: 'Deselect or remove all items ?',
                message: 'Deselect or remove all items ?',
                type: BootstrapDialog.TYPE_DANGER,
                closable: true,
                draggable: true,
                btnCancelLabel: 'Cancel',
                btnOKLabel: 'Yes',
                btnOKClass: 'btn-primary',
                callback: function(result) {
                    if(result) {
                        if ($('select[id="' + id + '"]').hasClass("tokenize")) {
                            // trigger close on all Tokens
                            $('select[id="' + id + '"]').parent().find('ul[class="TokensContainer"]').find('li[class="Token"]').find('a').trigger("click");
                        } else {
                            // remove options from selection
                            $('select[id="' + id + '"]').find('option').prop('selected',false);
                        }
                    }
                }
            });
        });
    });
}

/**
 * setup form help buttons
 */
function initFormHelpUI() {
    // handle help messages show/hide
    $("a[class='showhelp']").click(function () {
        $("*[for='" + $(this).attr('id') + "']").toggleClass("hidden show");
    });

    // handle all help messages show/hide
    $('[id*="show_all_help"]').click(function() {
        $('[id*="show_all_help"]').toggleClass("fa-toggle-on fa-toggle-off");
        $('[id*="show_all_help"]').toggleClass("text-success text-danger");
        if ($('[id*="show_all_help"]').hasClass("fa-toggle-on")) {
            $('[for*="help_for"]').addClass("show");
            $('[for*="help_for"]').removeClass("hidden");
        } else {
            $('[for*="help_for"]').addClass("hidden");
            $('[for*="help_for"]').removeClass("show");
        }
    });
}

/**
 * handle advanced show/hide
 */
function initFormAdvancedUI() {
    $('[data-advanced*="true"]').hide(function(){
        $('[data-advanced*="true"]').after("

"); // the table row is added to keep correct table striping
    });
    $('[id*="show_advanced"]').click(function() {
        $('[id*="show_advanced"]').toggleClass("fa-toggle-on fa-toggle-off");
        $('[id*="show_advanced"]').toggleClass("text-success text-danger");
        if ($('[id*="show_advanced"]').hasClass("fa-toggle-on")) {
            $('[data-advanced*="true"]').show();
            $('[data-advanced*="hidden_row"]').remove(); // the table row is deleted to keep correct table striping
        } else {
            $('[data-advanced*="true"]').after("

").hide(); // the table row is added to keep correct table striping
        }
    });
}

/**
 * standard remove items dialog, wrapper around BootstrapDialog
 */
function stdDialogRemoveItem(message, callback) {
    BootstrapDialog.confirm({
        title: 'Remove',
        message: message,
        type:BootstrapDialog.TYPE_WARNING,
        btnCancelLabel: 'Cancel',
        btnOKLabel: 'Yes',
        btnOKClass: 'btn-primary',
        callback: function(result) {
            if(result) {
                callback();
            }
        }
    });
}
<commit_msg>(ui) make formatTokenizersUI repeatable by removing old tokenizers first<commit_after>/**
 *    Copyright (C) 2015 Deciso B.V.
 *
 *    All rights reserved.
 *
 *    Redistribution and use in source and binary forms, with or without
 *    modification, are permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 *    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 *    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *    AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 *    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *    POSSIBILITY OF SUCH DAMAGE.
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *    User interface shared components, requires opnsense.js for supporting functions.
 */

/**
 * save form to server
 * @param url endpoint url
 * @param formid parent id to grep input data from
 * @param disable_dialog don't show input validation message box on failure
 */
function saveFormToEndpoint(url,formid,callback_ok, disable_dialog) {
    disable_dialog = disable_dialog || false;
    var data = getFormData(formid);
    ajaxCall(url=url,sendData=data,callback=function(data,status){
        if ( status == "success") {
            // update field validation
            handleFormValidation(formid,data['validations']);

            // if there are validation issues, update our screen and show a dialog.
            if (data['validations'] != undefined) {
                if (!disable_dialog) {
                    // validation message box is optional, form is already updated using handleFormValidation
                    BootstrapDialog.show({
                        type:BootstrapDialog.TYPE_WARNING,
                        title: 'Input validation',
                        message: 'Please correct validation errors in form',
                        buttons: [{
                            label: 'Dismiss',
                            action: function(dialogRef){
                                dialogRef.close();
                            }
                        }]

                    });
                }
            } else if ( callback_ok != undefined ) {
                // execute callback function
                callback_ok();
            }

        } else {
            // error handling, show internal errors
            // Normally the form should only return validation issues, if other things go wrong throw an error.
            BootstrapDialog.show({
                type: BootstrapDialog.TYPE_ERROR,
                title: 'save',
                message: 'Unable to save data, an internal error occurred.
 ' +
                'Response from server was:
 '+JSON.stringify(data)+''
            });
        }

    });
}

/**
 * standard data mapper to map json request data to forms on this page
 * @param data_get_map named array containing form names and source url's to get data from {'frm_example':"/api/example/settings/get"};
 * @return promise object, resolves when all are loaded
 */
function mapDataToFormUI(data_get_map) {
    var dfObj = new $.Deferred();

    // calculate number of items for deferred object to resolve
    var data_map_seq = 1;
    var data_map_count = 0;
    $.each(data_get_map, function(){
        data_map_count += 1;
    });

    var collected_data = {};
    $.each(data_get_map, function(data_index, data_url) {
        ajaxGet(url=data_url,sendData={}, callback=function(data, status) {
            if (status == "success") {
                $("form").each(function( index ) {
                    if ( $(this).attr('id').split('-')[0] == data_index) {
                        // related form found, load data
                        setFormData($(this).attr('id'), data);
                        collected_data[$(this).attr('id')] = data;
                    }
                });
            }
            if (data_map_seq == data_map_count) {
                dfObj.resolve(collected_data);
            }
            data_map_seq += 1;
        });
    });

    return dfObj;
}

/**
 * update service status buttons in user interface
 */
function updateServiceStatusUI(status) {

    var status_html = '';

    if (status == "running") {
        status_html += '' ;
    } else if (status == "stopped") {
        status_html += '' ;
    } else {
        status_html += '' ;
    }

    status_html += '  ';

    $('#service_status_container').html(status_html);
}

/**
 * reformat all tokenizers on this document
 */
function formatTokenizersUI(){
    // remove old tokenizers (if any)
    $('div[class="tokenize Tokenize"]').each(function(){
        $(this).remove();
    });
    $('select[class="tokenize"]').each(function(){
        if ($(this).prop("size")==0) {
            maxDropdownHeight=String(36*5)+"px"; // default number of items

        } else {
            number_of_items = $(this).prop("size");
            maxDropdownHeight=String(36*number_of_items)+"px";
        }
        hint=$(this).data("hint");
        width=$(this).data("width");
        allownew=$(this).data("allownew");
        maxTokenContainerHeight=$(this).data("maxheight");

        $(this).tokenize({
            displayDropdownOnFocus: true,
            newElements: allownew,
            placeholder:hint
        });
        $(this).parent().find('ul[class="TokensContainer"]').parent().css("width",width);
        $(this).parent().find('ul[class="Dropdown"]').css("max-height", maxDropdownHeight);
        if ( maxDropdownHeight != undefined ) {
            $(this).parent().find('ul[class="TokensContainer"]').css("max-height", maxTokenContainerHeight);
        }
    });
}

/**
 * clear multiselect boxes on click event, works on standard and tokenized versions
 */
function addMultiSelectClearUI() {
    $('[id*="clear-options"]').each(function() {
        $(this).click(function() {
            var id = $(this).attr("for");
            BootstrapDialog.confirm({
                title: 'Deselect or remove all items ?',
                message: 'Deselect or remove all items ?',
                type: BootstrapDialog.TYPE_DANGER,
                closable: true,
                draggable: true,
                btnCancelLabel: 'Cancel',
                btnOKLabel: 'Yes',
                btnOKClass: 'btn-primary',
                callback: function(result) {
                    if(result) {
                        if ($('select[id="' + id + '"]').hasClass("tokenize")) {
                            // trigger close on all Tokens
                            $('select[id="' + id + '"]').parent().find('ul[class="TokensContainer"]').find('li[class="Token"]').find('a').trigger("click");
                        } else {
                            // remove options from selection
                            $('select[id="' + id + '"]').find('option').prop('selected',false);
                        }
                    }
                }
            });
        });
    });
}

/**
 * setup form help buttons
 */
function initFormHelpUI() {
    // handle help messages show/hide
    $("a[class='showhelp']").click(function () {
        $("*[for='" + $(this).attr('id') + "']").toggleClass("hidden show");
    });

    // handle all help messages show/hide
    $('[id*="show_all_help"]').click(function() {
        $('[id*="show_all_help"]').toggleClass("fa-toggle-on fa-toggle-off");
        $('[id*="show_all_help"]').toggleClass("text-success text-danger");
        if ($('[id*="show_all_help"]').hasClass("fa-toggle-on")) {
            $('[for*="help_for"]').addClass("show");
            $('[for*="help_for"]').removeClass("hidden");
        } else {
            $('[for*="help_for"]').addClass("hidden");
            $('[for*="help_for"]').removeClass("show");
        }
    });
}

/**
 * handle advanced show/hide
 */
function initFormAdvancedUI() {
    $('[data-advanced*="true"]').hide(function(){
        $('[data-advanced*="true"]').after("

"); // the table row is added to keep correct table striping
    });
    $('[id*="show_advanced"]').click(function() {
        $('[id*="show_advanced"]').toggleClass("fa-toggle-on fa-toggle-off");
        $('[id*="show_advanced"]').toggleClass("text-success text-danger");
        if ($('[id*="show_advanced"]').hasClass("fa-toggle-on")) {
            $('[data-advanced*="true"]').show();
            $('[data-advanced*="hidden_row"]').remove(); // the table row is deleted to keep correct table striping
        } else {
            $('[data-advanced*="true"]').after("

").hide(); // the table row is added to keep correct table striping
        }
    });
}

/**
 * standard remove items dialog, wrapper around BootstrapDialog
 */
function stdDialogRemoveItem(message, callback) {
    BootstrapDialog.confirm({
        title: 'Remove',
        message: message,
        type:BootstrapDialog.TYPE_WARNING,
        btnCancelLabel: 'Cancel',
        btnOKLabel: 'Yes',
        btnOKClass: 'btn-primary',
        callback: function(result) {
            if(result) {
                callback();
            }
        }
    });
}
<|endoftext|>


<commit_before>l = console.log;

function toNum(c) {
    switch(c) {
        case 'J':
            return 11;
            break;
        case 'Q':
            return 12;
            break;
        case 'K':
            return 13;
            break;
        case 'A':
            return 14;
            break;

        default:
            return c;
    }
}

function compute_avg_stack(players) {
    var sum = 0;
    for (var i in players) {
        if (players[i].status == "active") {
            sum += players[i].stack;
        }
    }
    return sum / players.length;
}

function compute_chip_factor(g) {
    var average_stack = compute_avg_stack(g.players);
    var myself = g.players[g.in_action];

    var strength = (myself.stack > average_stack) ? (myself.stack / average_stack) : 0.5;

    if (g.current_buy_in < g.pot) {
        return strength;
    }
    else {
        return strength * g.pot / g.current_buy_in;
    }
}

function lameCards(cards) {
    // return TRUE if the cards are LAME
    l(
        "my cards: ",
        cards[0].rank,
        cards[0].suit,
        " ",
        cards[1].rank,
        cards[1].suit
     )

    if (
        toNum(cards[0].rank) < 9 &&
        toNum(cards[1].rank) < 9 &&
        cards[0].rank != cards[1].rank
       ) {
        return true
    } else {
        return false
    }
}

module.exports = {

    VERSION: "Jofogas's Zsozsobot v4.2",

  bet_request: function(g) {
    l("----", this.VERSION);
    l(new Date());
    var myself = g.players[g.in_action];
    var call = g.current_buy_in - myself["bet"];
    var min_raise = call + g.minimum_raise;

    // just in case!!!
    if (myself.status != "active") {
        return "OK";
    }

    // don't bet before flop if our hand is crap
    if (g.community_cards.length < 1) {
        // we're before flop
        if (lameCards(myself.hole_cards)) {
            l("folding because cards too lame");
            return 0;
        } else {
            if (toNum(myself.hole_cards[0].rank) > 9) {
              l("Go all in");
              return myself.stack;
            }
            l("calling because cards seem OK");
            return call;
        }
    }

    var average_stack = compute_avg_stack(g.players);
    l("Average stack is: ", average_stack);
    l("My stack is : ", myself.stack);
    l("chip_factor returns: ", compute_chip_factor(g));

    if (myself.stack > average_stack * 0.7) {
        /* brave */
        var bet = min_raise * 2;
        l("fearlessly raising: ", bet);
        return bet;
    }
    else {
        /* tight */
        l("fearfully not raising: ", 0);
        return 0;
    }
  },

    showdown: function(g) {
        return 'what is this for?';
    }
};
<commit_msg>Fold less easily<commit_after>l = console.log;

function toNum(c) {
    switch(c) {
        case 'J':
            return 11;
            break;
        case 'Q':
            return 12;
            break;
        case 'K':
            return 13;
            break;
        case 'A':
            return 14;
            break;

        default:
            return c;
    }
}

function compute_avg_stack(players) {
    var sum = 0;
    for (var i in players) {
        if (players[i].status == "active") {
            sum += players[i].stack;
        }
    }
    return sum / players.length;
}

function compute_chip_factor(g) {
    var average_stack = compute_avg_stack(g.players);
    var myself = g.players[g.in_action];

    var strength = (myself.stack > average_stack) ? (myself.stack / average_stack) : 0.5;

    if (g.current_buy_in < g.pot) {
        return strength;
    }
    else {
        return strength * g.pot / g.current_buy_in;
    }
}

function lameCards(cards) {
    // return TRUE if the cards are LAME
    l(
        "my cards: ",
        cards[0].rank,
        cards[0].suit,
        " ",
        cards[1].rank,
        cards[1].suit
     )

    if (
        toNum(cards[0].rank) < 4 &&
        toNum(cards[1].rank) < 4 &&
        cards[0].rank != cards[1].rank
       ) {
        return true
    } else {
        return false
    }
}

module.exports = {

    VERSION: "Jofogas's Zsozsobot v4.2",

  bet_request: function(g) {
    l("----", this.VERSION);
    l(new Date());
    var myself = g.players[g.in_action];
    var call = g.current_buy_in - myself["bet"];
    var min_raise = call + g.minimum_raise;

    // just in case!!!
    if (myself.status != "active") {
        return "OK";
    }

    // don't bet before flop if our hand is crap
    if (g.community_cards.length < 1) {
        // we're before flop
        if (lameCards(myself.hole_cards)) {
            l("folding because cards too lame");
            return 0;
        } else {
            if (toNum(myself.hole_cards[0].rank) > 9) {
              l("Go all in");
              return myself.stack;
            }
            l("calling because cards seem OK");
            return call;
        }
    }

    var average_stack = compute_avg_stack(g.players);
    l("Average stack is: ", average_stack);
    l("My stack is : ", myself.stack);
    l("chip_factor returns: ", compute_chip_factor(g));

    if (myself.stack > average_stack * 0.7) {
        /* brave */
        var bet = min_raise * 2;
        l("fearlessly raising: ", bet);
        return bet;
    }
    else {
        /* tight */
        l("fearfully not raising: ", 0);
        return 0;
    }
  },

    showdown: function(g) {
        return 'what is this for?';
    }
};
<|endoftext|>


<commit_before>
$('window').ready(function(){

  //Viajes por mes
	var viajesMes = new Array();
	var pos = 1;

	$.getJSON('/statistics/gettravelsbymonth/', function(json) {
    $.each( json, function( key, val ) {
			viajesMes[pos] = val;
			pos = pos + 1;
		});

		var barChartData = {
      labels : ["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],
			datasets : [{
        fillColor : "rgba(120,120,120,0.5)",
        strokeColor : "rgba(120,120,120,1)",
        pointColor : "rgba(120,120,120,1)",
        pointStrokeColor : "#fff",
				data : [viajesMes[1],viajesMes[2],viajesMes[3],viajesMes[4],viajesMes[5],viajesMes[6],viajesMes[7],viajesMes[8],viajesMes[9],viajesMes[10],viajesMes[11],viajesMes[12]]
			},]
		};

		var options = {
			scaleShowGridLines: true,
			scaleOverride: true,
			scaleSteps: 2,
			scaleStepWidth: 5,
			scaleStartValue: 0,
      scaleLineColor: "rgba(0.9,0.2,0,.1)",
			scaleLineWidth: 0,
			scaleShowLabels: true,
			scaleFontColor: "#000",
			barDatasetSpacing: 2,
			barStrokeWidth: 2
		};

    new Chart(document.getElementById("travelsByMonth").getContext("2d")).Line(lineChartData, options);

  });

  //Viajes en el ultimo mes
	var posDias = 1;
	var dias = new Array();
	var diasMes = new Array();

	$.getJSON('/statistics/gettravelsbylastmonth/', function(json) {
    $.each( json, function( key, val ) {
			diasMes[posDias] = val;
			dias[posDias] = key;
			posDias = posDias + 1;
		});

		var lineChartData = {
     	labels : [dias[1],dias[2],dias[3],dias[4],dias[5],dias[6],
           			dias[7],dias[8],dias[9],dias[10],dias[11],dias[12],
          			dias[13],dias[14],dias[15],dias[16],dias[17],dias[18],
          			dias[19],dias[20],dias[21],dias[22],dias[23],dias[24],
          			dias[25],dias[26],dias[27],dias[28],dias[29],dias[30],dias[31]
               ],
      datasets : [{
        fillColor : "rgba(120,120,120,0.5)",
        strokeColor : "rgba(120,120,120,1)",
        pointColor : "rgba(120,120,120,1)",
        pointStrokeColor : "#fff",
  			data : [diasMes[1],diasMes[2],diasMes[3],diasMes[4],diasMes[5],diasMes[6],
            		diasMes[7],diasMes[8],diasMes[9],diasMes[10],diasMes[11],diasMes[12],
            		diasMes[13],diasMes[14],diasMes[15],diasMes[16],diasMes[17],diasMes[18],
            		diasMes[19],diasMes[20],diasMes[21],diasMes[22],diasMes[23],diasMes[24],
            		diasMes[25],diasMes[26],diasMes[27],diasMes[28],diasMes[29],diasMes[30],diasMes[31]
               ]
			},]
	  };

		var options = {
			scaleShowGridLines: true,
			scaleOverride: true,
			scaleSteps: 2,
			scaleStepWidth: 5,
			scaleStartValue: 0,
      scaleLineColor: "rgba(0.9,0.2,0,.1)",
			scaleLineWidth: 0,
			scaleShowLabels: true,
			scaleFontColor: "#000",
			barDatasetSpacing: 2,
			barStrokeWidth: 2
		};

		new Chart(document.getElementById("travelsLastMonth").getContext("2d")).Bar(lineChartData,options);

  });

  //Viajes en el último año
	var posMes = 1;
	var meses = new Array();
	var viajesUYear = new Array();

	$.getJSON('/statistics/gettravelsbylastyear/', function(json) {
    $.each( json, function( key, val ) {
			viajesUYear[posMes] = val;
			meses[posMes] = key;
			posMes = posMes + 1;
  	});

		var lineChartData = {
     	labels : ["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],
			datasets : [ {
        fillColor : "rgba(120,120,120,0.5)",
        strokeColor : "rgba(120,120,120,1)",
        pointColor : "rgba(120,120,120,1)",
        pointStrokeColor : "#fff",
				data : [viajesUYear[1],viajesUYear[2],viajesUYear[3],viajesUYear[4],viajesUYear[5],viajesUYear[6],viajesUYear[7],viajesUYear[8],viajesUYear[9],viajesUYear[10],viajesUYear[11],viajesUYear[12]]
			}, ]
    };

		var options = {
  		scaleShowGridLines: true,
  		scaleOverride: true,
  		scaleSteps: 2,
  		scaleStepWidth: 5,
  		scaleStartValue: 0,
      scaleLineColor: "rgba(0.9,0.2,0,.1)",
  		scaleLineWidth: 0,
  		scaleShowLabels: true,
  		scaleFontColor: "#000",
  		barDatasetSpacing: 2,
  		barStrokeWidth: 2
  	};

		new Chart(document.getElementById("travelsLastYear").getContext("2d")).Bar(lineChartData, options);

	});

  //Viajes por dia
  var posi = 0;
	var viajesDias = new Array();

	$.getJSON('/statistics/gettravelsbyday/', function(json) {
    $.each( json, function( key, val ) {
			viajesDias[posi] = val;
			posi = posi + 1;
		});

  	var barChartData = {
     	labels : ["Lun","Mar","Mie","Jue","Vie","Sab","Dom"],
			datasets : [{
  			fillColor : "rgba(120,120,120,0.5)",
  			strokeColor : "rgba(120,120,120,1)",
  			pointColor : "rgba(120,120,120,1)",
  			pointStrokeColor : "#fff",
				data : [viajesDias[0],viajesDias[1],viajesDias[2],viajesDias[3],viajesDias[4],viajesDias[5],viajesDias[6]]
			}, ]
  	};

  	var options = {
  		scaleShowGridLines: true,
  		scaleOverride: true,
  		scaleSteps: 2,
  		scaleStepWidth: 5,
  		scaleStartValue: 0,
  		scaleLineColor: "rgba(0.9,0.2,0,.1)",
  		scaleLineWidth: 0,
  		scaleShowLabels: true,
  		scaleFontColor: "#000",
  		barDatasetSpacing: 2,
  		barStrokeWidth: 2
  	};

  	new Chart(document.getElementById("travelsByDay").getContext("2d")).Bar(barChartData, options);

  });

});

/*
var doughnutData = [
				{
					value: 30,
					color:"#F7464A"
				},
				{
					value : 50,
					color : "#46BFBD"
				},
				{
					value : 100,
					color : "#FDB45C"
				},
				{
					value : 40,
					color : "#949FB1"
				},
				{
					value : 120,
					color : "#4D5360"
				}

			];

*/
<commit_msg>bug fixed<commit_after>
$('window').ready(function(){

  //Viajes en el ultimo mes
	var posDias = 1;
	var dias = new Array();
	var diasMes = new Array();

	$.getJSON('/statistics/gettravelsbylastmonth/', function(json) {
    $.each( json, function( key, val ) {
			diasMes[posDias] = val;
			dias[posDias] = key;
			posDias = posDias + 1;
		});

		var lineChartData = {
     	labels : [dias[1],dias[2],dias[3],dias[4],dias[5],dias[6],
           			dias[7],dias[8],dias[9],dias[10],dias[11],dias[12],
          			dias[13],dias[14],dias[15],dias[16],dias[17],dias[18],
          			dias[19],dias[20],dias[21],dias[22],dias[23],dias[24],
          			dias[25],dias[26],dias[27],dias[28],dias[29],dias[30],dias[31]
               ],
      datasets : [{
        fillColor : "rgba(120,120,120,0.5)",
        strokeColor : "rgba(120,120,120,1)",
        pointColor : "rgba(120,120,120,1)",
        pointStrokeColor : "#fff",
  			data : [diasMes[1],diasMes[2],diasMes[3],diasMes[4],diasMes[5],diasMes[6],
            		diasMes[7],diasMes[8],diasMes[9],diasMes[10],diasMes[11],diasMes[12],
            		diasMes[13],diasMes[14],diasMes[15],diasMes[16],diasMes[17],diasMes[18],
            		diasMes[19],diasMes[20],diasMes[21],diasMes[22],diasMes[23],diasMes[24],
            		diasMes[25],diasMes[26],diasMes[27],diasMes[28],diasMes[29],diasMes[30],diasMes[31]
               ]
			},]
	  };

		var options = {
			scaleShowGridLines: true,
			scaleOverride: true,
			scaleSteps: 2,
			scaleStepWidth: 5,
			scaleStartValue: 0,
      scaleLineColor: "rgba(0.9,0.2,0,.1)",
			scaleLineWidth: 0,
			scaleShowLabels: true,
			scaleFontColor: "#000",
			barDatasetSpacing: 2,
			barStrokeWidth: 2
		};

		new Chart(document.getElementById("travelsLastMonth").getContext("2d")).Line(lineChartData,options);

  });

  //Viajes en el último año
	var posMes = 1;
	var meses = new Array();
	var viajesUYear = new Array();

	$.getJSON('/statistics/gettravelsbylastyear/', function(json) {
    $.each( json, function( key, val ) {
			viajesUYear[posMes] = val;
			meses[posMes] = key;
			posMes = posMes + 1;
  	});

		var lineChartData = {
     	labels : ["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],
			datasets : [ {
        fillColor : "rgba(120,120,120,0.5)",
        strokeColor : "rgba(120,120,120,1)",
        pointColor : "rgba(120,120,120,1)",
        pointStrokeColor : "#fff",
				data : [viajesUYear[1],viajesUYear[2],viajesUYear[3],viajesUYear[4],viajesUYear[5],viajesUYear[6],viajesUYear[7],viajesUYear[8],viajesUYear[9],viajesUYear[10],viajesUYear[11],viajesUYear[12]]
			}, ]
    };

		var options = {
  		scaleShowGridLines: true,
  		scaleOverride: true,
  		scaleSteps: 2,
  		scaleStepWidth: 5,
  		scaleStartValue: 0,
      scaleLineColor: "rgba(0.9,0.2,0,.1)",
  		scaleLineWidth: 0,
  		scaleShowLabels: true,
  		scaleFontColor: "#000",
  		barDatasetSpacing: 2,
  		barStrokeWidth: 2
  	};

		new Chart(document.getElementById("travelsLastYear").getContext("2d")).Line(lineChartData, options);

	});

  //Viajes por mes
  var viajesMes = new Array();
  var pos = 1;

  $.getJSON('/statistics/gettravelsbymonth/', function(json) {
    $.each( json, function( key, val ) {
      viajesMes[pos] = val;
      pos = pos + 1;
    });

    var barChartData = {
      labels : ["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],
      datasets : [{
        fillColor : "rgba(120,120,120,0.5)",
        strokeColor : "rgba(120,120,120,1)",
        pointColor : "rgba(120,120,120,1)",
        pointStrokeColor : "#fff",
        data : [viajesMes[1],viajesMes[2],viajesMes[3],viajesMes[4],viajesMes[5],viajesMes[6],viajesMes[7],viajesMes[8],viajesMes[9],viajesMes[10],viajesMes[11],viajesMes[12]]
      },]
    };

    var options = {
      scaleShowGridLines: true,
      scaleOverride: true,
      scaleSteps: 2,
      scaleStepWidth: 5,
      scaleStartValue: 0,
      scaleLineColor: "rgba(0.9,0.2,0,.1)",
      scaleLineWidth: 0,
      scaleShowLabels: true,
      scaleFontColor: "#000",
      barDatasetSpacing: 2,
      barStrokeWidth: 2
    };

    new Chart(document.getElementById("travelsByMonth").getContext("2d")).Bar(barChartData, options);

  });

  //Viajes por dia
  var posi = 0;
	var viajesDias = new Array();

	$.getJSON('/statistics/gettravelsbyday/', function(json) {
    $.each( json, function( key, val ) {
			viajesDias[posi] = val;
			posi = posi + 1;
		});

  	var barChartData = {
     	labels : ["Lun","Mar","Mie","Jue","Vie","Sab","Dom"],
			datasets : [{
  			fillColor : "rgba(120,120,120,0.5)",
  			strokeColor : "rgba(120,120,120,1)",
  			pointColor : "rgba(120,120,120,1)",
  			pointStrokeColor : "#fff",
				data : [viajesDias[0],viajesDias[1],viajesDias[2],viajesDias[3],viajesDias[4],viajesDias[5],viajesDias[6]]
			}, ]
  	};

  	var options = {
  		scaleShowGridLines: true,
  		scaleOverride: true,
  		scaleSteps: 2,
  		scaleStepWidth: 5,
  		scaleStartValue: 0,
  		scaleLineColor: "rgba(0.9,0.2,0,.1)",
  		scaleLineWidth: 0,
  		scaleShowLabels: true,
  		scaleFontColor: "#000",
  		barDatasetSpacing: 2,
  		barStrokeWidth: 2
  	};

  	new Chart(document.getElementById("travelsByDay").getContext("2d")).Bar(barChartData, options);

  });

});

/*
var doughnutData = [
				{
					value: 30,
					color:"#F7464A"
				},
				{
					value : 50,
					color : "#46BFBD"
				},
				{
					value : 100,
					color : "#FDB45C"
				},
				{
					value : 40,
					color : "#949FB1"
				},
				{
					value : 120,
					color : "#4D5360"
				}

			];

*/
<|endoftext|>


<commit_before>'use strict'

describe('tzAlign', function () {
  var scope, $filter, $compile, $timeout, $sandbox

  beforeEach(module('Timezones', function ($provide) {
    $provide.constant('$timezones.definitions.location', 'base/tz/data')
  }))

  beforeEach(inject(function ($injector, $rootScope, _$filter_, _$compile_, _$timeout_, $rootElement) {
    scope = $rootScope.$new(true)
    $filter = _$filter_
    $compile = _$compile_
    $timeout = _$timeout_

    $sandbox = $rootElement.append(angular.element('

'))
  }))

  var compile = function (markup, timezone, reference) {
    angular.extend(scope, {
      timezone : timezone,
      reference : reference
    })

    var $element = $(markup).appendTo($sandbox)

    $element = $compile($element)(scope)
    scope.$digest()

    return $element
  }

  afterEach(function () {
    $sandbox.remove()
    scope.$destroy()
  })

  var scenarios = [
    {
      timezone : 'America/New_York',
      reference : new Date(Date.parse('1970-01-01T00:00:00+00:00')),
      markup : '{{reference|tzAlign:timezone|date:"yyyy-MM-dd HH:mm:ss Z"}}',
      expected : {
        fullYear : 1969,
        month : 11,
        date : 31,
        hours : 19,
        text : '1969-12-31 19:00:00 -0500'
      }
    },
    {
      timezone : 'America/Los_Angeles',
      reference : new Date(Date.parse('1970-01-01T00:00:00+00:00')),
      markup : '{{reference|tzAlign:timezone|date:"yyyy-MM-dd HH:mm:ss Z"}}',
      expected : {
        fullYear : 1969,
        month : 11,
        date : 31,
        hours : 16,
        text : '1969-12-31 16:00:00 -0800'
      }
    },
    {
      timezone : 'Europe/Berlin',
      reference : new Date(Date.parse('1970-01-01T00:00:00+00:00')),
      markup : '{{reference|tzAlign:timezone|date:"yyyy-MM-dd HH:mm:ss Z"}}',
      expected : {
        fullYear : 1970,
        month : 0,
        date : 1,
        hours : 1,
        text : '1970-01-01 01:00:00 +0100'
      }
    },
    {
      timezone : 'Australia/Sydney',
      reference : new Date(Date.parse('1970-01-01T00:00:00+00:00')),
      markup : '{{reference|tzAlign:timezone|date:"yyyy-MM-dd HH:mm:ss Z"}}',
      expected : {
        fullYear : 1970,
        month : 0,
        date : 1,
        hours : 10,
        text : '1970-01-01 10:00:00 +1000'
      }
    }
  ]

  it('should align dates to expected timezones', function () {
    scenarios.forEach(function (scenario) {
      var timezone = scenario.timezone
        , reference = scenario.reference
        , expected = scenario.expected

      var actual = $filter('tzAlign')(reference, timezone)

      expect(actual.getTimezone()).toEqual(timezone)
      expect(actual.getFullYear()).toEqual(expected.fullYear)
      expect(actual.getMonth()).toEqual(expected.month)
      expect(actual.getDate()).toEqual(expected.date)
      expect(actual.getHours()).toEqual(expected.hours)
    })
  })

  it('should pass the date through unchanged when timezone is undefined', function () {
    scenarios.forEach(function (scenario) {
      var reference = scenario.reference
        , expected = scenario.reference
        , actual

      expect(function () {
        actual = $filter('tzAlign')(reference, undefined)
      }).not.toThrow()

      expect(actual).toBe(expected)
    })
  })

  it('should pass through invalid date values', function () {
    var expected = 'bogus value'
      , actual

    expect(function () {
      actual = $filter('tzAlign')(expected)
    }).not.toThrow()

    expect(actual).toBe(expected)
  })

  it('should pass through null date values', function () {
    var actual

    expect(function () {
      actual = $filter('tzAlign')(null)
    }).not.toThrow()

    expect(actual).toBeNull()
  })

  it('should pass through undefined date values', function () {
    var actual

    expect(function () {
      actual = $filter('tzAlign')(undefined)
    }).not.toThrow()

    expect(actual).toBeUndefined()
  })

  it('should align date objects that are formatted correctly', function () {
    scenarios.forEach(function (scenario) {
      var expected = scenario.expected
        , el = compile(scenario.markup, scenario.timezone, scenario.reference)

      expect(el.text()).toEqual(expected.text)

      scope.timezone = 'America/Chicago'
      scope.$digest()

      expect(el.text()).not.toEqual(expected.text)
    })
  })

  it('should align milliseconds from epoch as numeric literals that are formatted', function () {
    scenarios.forEach(function (scenario) {
      var expected = scenario.expected
        , el = compile(scenario.markup, scenario.timezone, scenario.reference.getTime())

      expect(el.text()).toEqual(expected.text)
    })
  })

  it('should align milliseconds from epoch as string literals that are formatted', function () {
    scenarios.forEach(function (scenario) {
      var expected = scenario.expected
        , el = compile(scenario.markup, scenario.timezone, '' + scenario.reference.getTime())

      expect(el.text()).toEqual(expected.text)
    })
  })
})<commit_msg>Got it!<commit_after>'use strict'

describe('tzAlign', function () {
  var scope, $filter, $compile, $timeout, $sandbox

  beforeEach(module('Timezones', function ($provide) {
    $provide.constant('$timezones.definitions.location', 'base/tz/data')
  }))

  beforeEach(inject(function ($injector, $rootScope, _$filter_, _$compile_, _$timeout_, $rootElement) {
    scope = $rootScope.$new(true)
    $filter = _$filter_
    $compile = _$compile_
    $timeout = _$timeout_

    $sandbox = $rootElement.append(angular.element('

'))
  }))

  var compile = function (markup, timezone, reference) {
    angular.extend(scope, {
      timezone : timezone,
      reference : reference
    })

    var $element = $(markup).appendTo($sandbox)

    $element = $compile($element)(scope)
    scope.$digest()

    return $element
  }

  afterEach(function () {
    $sandbox.remove()
    scope.$destroy()
  })

  var scenarios = [
    {
      timezone : 'America/New_York',
      reference : new Date(Date.parse('1970-01-01T00:00:00+00:00')),
      markup : '{{reference|tzAlign:timezone|date:"yyyy-MM-dd HH:mm:ss Z"}}',
      expected : {
        fullYear : 1969,
        month : 11,
        date : 31,
        hours : 19,
        text : '1969-12-31 19:00:00 -0500'
      }
    },
    {
      timezone : 'America/Los_Angeles',
      reference : new Date(Date.parse('1970-01-01T00:00:00+00:00')),
      markup : '{{reference|tzAlign:timezone|date:"yyyy-MM-dd HH:mm:ss Z"}}',
      expected : {
        fullYear : 1969,
        month : 11,
        date : 31,
        hours : 16,
        text : '1969-12-31 16:00:00 -0800'
      }
    },
    {
      timezone : 'Europe/Berlin',
      reference : new Date(Date.parse('1970-01-01T00:00:00+00:00')),
      markup : '{{reference|tzAlign:timezone|date:"yyyy-MM-dd HH:mm:ss Z"}}',
      expected : {
        fullYear : 1970,
        month : 0,
        date : 1,
        hours : 1,
        text : '1970-01-01 01:00:00 +0100'
      }
    },
    {
      timezone : 'Australia/Sydney',
      reference : new Date(Date.parse('1970-01-01T00:00:00+00:00')),
      markup : '{{reference|tzAlign:timezone|date:"yyyy-MM-dd HH:mm:ss Z"}}',
      expected : {
        fullYear : 1970,
        month : 0,
        date : 1,
        hours : 10,
        text : '1970-01-01 10:00:00 +1000'
      }
    }
  ]

  it('should align dates to expected timezones', function () {
    scenarios.forEach(function (scenario) {
      var timezone = scenario.timezone
        , reference = scenario.reference
        , expected = scenario.expected

      var actual = $filter('tzAlign')(reference, timezone)

      expect(actual.getTimezone()).toEqual(timezone)
      expect(actual.getFullYear()).toEqual(expected.fullYear)
      expect(actual.getMonth()).toEqual(expected.month)
      expect(actual.getDate()).toEqual(expected.date)
      expect(actual.getHours()).toEqual(expected.hours)
    })
  })

  it('should pass the date through unchanged when timezone is undefined', function () {
    scenarios.forEach(function (scenario) {
      var reference = scenario.reference
        , expected = scenario.reference
        , actual

      expect(function () {
        actual = $filter('tzAlign')(reference, undefined)
      }).not.toThrow()

      expect(actual).toBe(expected)
    })
  })

  it('should pass through invalid date values', function () {
    var expected = 'bogus value'
      , actual

    expect(function () {
      actual = $filter('tzAlign')(expected, 'America/New_York')
    }).not.toThrow()

    expect(actual).toBe(expected)
  })

  it('should pass through null date values', function () {
    var actual

    expect(function () {
      actual = $filter('tzAlign')(null, 'America/New_York')
    }).not.toThrow()

    expect(actual).toBeNull()
  })

  it('should pass through undefined date values', function () {
    var actual

    expect(function () {
      actual = $filter('tzAlign')(undefined, 'America/New_York')
    }).not.toThrow()

    expect(actual).toBeUndefined()
  })

  it('should align date objects that are formatted correctly', function () {
    scenarios.forEach(function (scenario) {
      var expected = scenario.expected
        , el = compile(scenario.markup, scenario.timezone, scenario.reference)

      expect(el.text()).toEqual(expected.text)

      scope.timezone = 'America/Chicago'
      scope.$digest()

      expect(el.text()).not.toEqual(expected.text)
    })
  })

  it('should align milliseconds from epoch as numeric literals that are formatted', function () {
    scenarios.forEach(function (scenario) {
      var expected = scenario.expected
        , el = compile(scenario.markup, scenario.timezone, scenario.reference.getTime())

      expect(el.text()).toEqual(expected.text)
    })
  })

  it('should align milliseconds from epoch as string literals that are formatted', function () {
    scenarios.forEach(function (scenario) {
      var expected = scenario.expected
        , el = compile(scenario.markup, scenario.timezone, '' + scenario.reference.getTime())

      expect(el.text()).toEqual(expected.text)
    })
  })
})<|endoftext|>


<commit_before>var events = require('events')
var network = require('network-address')

module.exports = function ($video) {
  var that = new events.EventEmitter()
  var atEnd = false
  var lastUrl = null

  that.setMaxListeners(0)

  that.width = 0
  that.height = 0
  that.element = $video

  var chromecast = null
  var chromecastTime = 0
  var chromecastOffset = 0
  var chromecastSubtitles = 1
  var interval = null

  var onerror = function () {
    if (chromecast) chromecast.removeListener('error', onerror)
    that.chromecast(null)
  }

  var onmetadata = function (err, status) {
    if (err) return onerror(err)
    if (chromecastTime) chromecastOffset = 0
    chromecastTime = status.currentTime
    chromecastSubtitles = 1
    that.duration = status.media.duration
    that.emit('metadata')

    clearInterval(interval)
    interval = setInterval(function () {
      chromecast.status(function (err, status) {
        if (err) return onerror(err)

        if (!status) {
          chromecastOffset = 0
          clearInterval(interval)
          atEnd = true
          that.playing = false
          that.emit('pause')
          that.emit('end')
          return
        }

        if (chromecastTime) chromecastOffset = 0
        chromecastTime = status.currentTime
      })
    }, 1000)
  }

  that.casting = false
  that.chromecast = function (player) {
    chromecastOffset = chromecast ? 0 : $video.currentTime
    clearInterval(interval)
    if (chromecast && that.playing) chromecast.stop()
    chromecast = player
    that.casting = player
    if (chromecast) chromecast.on('error', onerror)
    if (!that.playing) return
    media.play(lastUrl, that.casting ? chromecastOffset : chromecastTime)
  }

  $video.addEventListener('seeked', function () {
    if (chromecast) return
    that.emit('seek')
  }, false)

  $video.addEventListener('ended', function () {
    if (chromecast) return
    atEnd = true
    that.playing = false
    that.emit('pause')
    that.emit('end')
  }, false)

  $video.addEventListener('loadedmetadata', function () {
    if (chromecast) return
    that.width = $video.videoWidth
    that.height =  $video.videoHeight
    that.ratio = that.width / that.height
    that.duration = $video.duration
    that.emit('metadata')
  }, false)

  that.time = function (time) {
    atEnd = false
    if (chromecast) {
      if (arguments.length) {
        chromecastOffset = 0
        chromecast.seek(time)
      }
      return chromecastOffset || chromecastTime
    }
    if (arguments.length) $video.currentTime = time
    return $video.currentTime
  }

  that.playing = false

  that.play = function (url, time) {
    if (!url && !lastUrl) return
    var changed = url && lastUrl !== url
    if (changed) subs = null
    if (chromecast) {
      $video.innerHTML = '' // clear
      $video.pause()
      $video.load()
      lastUrl = url
      atEnd = false
      if (url) {
        var mediaUrl = url.replace('127.0.0.1', network())
        var subsUrl = mediaUrl.replace(/(:\/\/.+)\/.*/, '$1/subtitles')
        var subsList = []
        for (var i = 0; i < 100; i++) subsList.push(subsUrl)
        chromecast.play(mediaUrl, {title: 'Playback', seek: time || 0, subtitles: subsList, autoSubtitles: !!subs }, onmetadata)
      } else {
        chromecast.resume()
      }
    } else {
      if (atEnd && url === lastUrl) $video.time(0)
      lastUrl = url
      atEnd = false
      $video.innerHTML = '' // clear
      var $src = document.createElement('source')
      $src.setAttribute('src', url)
      $src.setAttribute('type', 'video/mp4')
      $video.appendChild($src)
      if (changed) $video.load()
      $video.play()
      if (time) $video.currentTime = time
    }
    that.playing = true
    that.emit('play')
  }

  that.pause = function () {
    if (chromecast) chromecast.pause()
    else $video.pause()
    that.playing = false
    that.emit('pause')
  }

  var subs = null
  that.subtitles = function (buf) {
    if (!arguments.length) return subs
    subs = buf

    if (chromecast) {
      if (!buf) chromecast.subtitles(false)
      else chromecast.subtitles(++chromecastSubtitles)
      return
    }

    if ($video.querySelector('track')) $video.removeChild($video.querySelector('track'))
    if (!buf) return null
    var $track = document.createElement('track')
    $track.setAttribute('default', 'default')
    $track.setAttribute('src', 'data:text/vtt;base64,'+buf.toString('base64'))
    $track.setAttribute('label', 'Subtitles')
    $track.setAttribute('kind', 'subtitles')
    $video.appendChild($track)
    that.emit('subtitles', buf)
    return buf
  }

  return that
}
<commit_msg>fix pause regression. fixes #29<commit_after>var events = require('events')
var network = require('network-address')

module.exports = function ($video) {
  var that = new events.EventEmitter()
  var atEnd = false
  var lastUrl = null

  that.setMaxListeners(0)

  that.width = 0
  that.height = 0
  that.element = $video

  var chromecast = null
  var chromecastTime = 0
  var chromecastOffset = 0
  var chromecastSubtitles = 1
  var interval = null

  var onerror = function () {
    if (chromecast) chromecast.removeListener('error', onerror)
    that.chromecast(null)
  }

  var onmetadata = function (err, status) {
    if (err) return onerror(err)
    if (chromecastTime) chromecastOffset = 0
    chromecastTime = status.currentTime
    chromecastSubtitles = 1
    that.duration = status.media.duration
    that.emit('metadata')

    clearInterval(interval)
    interval = setInterval(function () {
      chromecast.status(function (err, status) {
        if (err) return onerror(err)

        if (!status) {
          chromecastOffset = 0
          clearInterval(interval)
          atEnd = true
          that.playing = false
          that.emit('pause')
          that.emit('end')
          return
        }

        if (chromecastTime) chromecastOffset = 0
        chromecastTime = status.currentTime
      })
    }, 1000)
  }

  that.casting = false
  that.chromecast = function (player) {
    chromecastOffset = chromecast ? 0 : $video.currentTime
    clearInterval(interval)
    if (chromecast && that.playing) chromecast.stop()
    chromecast = player
    that.casting = player
    if (chromecast) chromecast.on('error', onerror)
    if (!that.playing) return
    media.play(lastUrl, that.casting ? chromecastOffset : chromecastTime)
  }

  $video.addEventListener('seeked', function () {
    if (chromecast) return
    that.emit('seek')
  }, false)

  $video.addEventListener('ended', function () {
    if (chromecast) return
    atEnd = true
    that.playing = false
    that.emit('pause')
    that.emit('end')
  }, false)

  $video.addEventListener('loadedmetadata', function () {
    if (chromecast) return
    that.width = $video.videoWidth
    that.height =  $video.videoHeight
    that.ratio = that.width / that.height
    that.duration = $video.duration
    that.emit('metadata')
  }, false)

  that.time = function (time) {
    atEnd = false
    if (chromecast) {
      if (arguments.length) {
        chromecastOffset = 0
        chromecast.seek(time)
      }
      return chromecastOffset || chromecastTime
    }
    if (arguments.length) $video.currentTime = time
    return $video.currentTime
  }

  that.playing = false

  that.play = function (url, time) {
    if (!url && !lastUrl) return
    var changed = url && lastUrl !== url
    if (changed) subs = null
    if (chromecast) {
      $video.innerHTML = '' // clear
      $video.pause()
      $video.load()
      if (url) lastUrl = url
      else url = lastUrl
      atEnd = false
      if (url) {
        var mediaUrl = url.replace('127.0.0.1', network())
        var subsUrl = mediaUrl.replace(/(:\/\/.+)\/.*/, '$1/subtitles')
        var subsList = []
        for (var i = 0; i < 100; i++) subsList.push(subsUrl)
        chromecast.play(mediaUrl, {title: 'Playback', seek: time || 0, subtitles: subsList, autoSubtitles: !!subs }, onmetadata)
      } else {
        chromecast.resume()
      }
    } else {
      if (atEnd && url === lastUrl) $video.time(0)
      if (!url) {
        $video.play()
      } else {
        lastUrl = url
        atEnd = false
        $video.innerHTML = '' // clear
        var $src = document.createElement('source')
        $src.setAttribute('src', url)
        $src.setAttribute('type', 'video/mp4')
        $video.appendChild($src)
        if (changed) $video.load()
        $video.play()
        if (time) $video.currentTime = time
      }
    }
    that.playing = true
    that.emit('play')
  }

  that.pause = function () {
    if (chromecast) chromecast.pause()
    else $video.pause()
    that.playing = false
    that.emit('pause')
  }

  var subs = null
  that.subtitles = function (buf) {
    if (!arguments.length) return subs
    subs = buf

    if (chromecast) {
      if (!buf) chromecast.subtitles(false)
      else chromecast.subtitles(++chromecastSubtitles)
      return
    }

    if ($video.querySelector('track')) $video.removeChild($video.querySelector('track'))
    if (!buf) return null
    var $track = document.createElement('track')
    $track.setAttribute('default', 'default')
    $track.setAttribute('src', 'data:text/vtt;base64,'+buf.toString('base64'))
    $track.setAttribute('label', 'Subtitles')
    $track.setAttribute('kind', 'subtitles')
    $video.appendChild($track)
    that.emit('subtitles', buf)
    return buf
  }

  return that
}
<|endoftext|>


<commit_before>
function addCardFormHandler(non_idolized_card_url, idolized_card_url, card) {
    $('#addCardModal #id_max_level').parent().hide();
    $('#addCardModal #id_max_bond').parent().hide();

    var expirationHandler = function() {
	if ($('#addCardModal #id_stored').val() == 'Box') {
	    $('#addCardModal label[for=id_expires_in]').parent().show();
	} else {
	    $('#addCardModal label[for=id_expires_in]').parent().hide();
	    $('#addCardModal label[for=id_expires_in]').parent().find('input').val('');
	}
    };
    expirationHandler();

    var storedOnChange = function() {
	if ($('#addCardModal #id_stored').val() != 'Deck') {
	    $('#addCardModal #id_skill').closest('.form-group').hide();
	    $('#addCardModal #id_skill').val(1);
	    $('#addCardModal #id_skill_slots').closest('.form-group').hide();
	} else {
	    $('#addCardModal #id_skill').closest('.form-group').show();
	    $('#addCardModal #id_skill_slots').closest('.form-group').show();
	}
    };
    storedOnChange();

    if (typeof non_idolized_card_url == 'undefined') {
	$('#addCardModal #id_idolized').prop('checked', true);
	$('#addCardModal #id_max_level').parent().show();
	$('#addCardModal #id_max_bond').parent().show();
	$('#addCardModal #id_idolized').parent().hide();
	$('#addCardModal img.non_idolized').hide();
	$('#addCardModal img.idolized').prop('src', idolized_card_url);
    } else {
	$('#addCardModal #id_idolized').parent().show();
	$('#addCardModal img.non_idolized').prop('src', non_idolized_card_url);
	$('#addCardModal img.idolized').prop('src', idolized_card_url).hide();

	var idolizedCheckBoxHandler = function() {
	    if($('#addCardModal #id_idolized').is(":checked") || $('#addCardModal #id_idolized').val() == 'True') {
		$('#addCardModal #id_prefer_unidolized_image').parent().show();
		$('#addCardModal #id_max_level').parent().show();
		$('#addCardModal #id_max_bond').parent().show();
    if($('#addCardModal #id_prefer_unidolized_image').is(":checked") || $('#addCardModal #id_prefer_unidolized_image').val() == 'True') {
			$('#addCardModal img.idolized').hide();
			$('#addCardModal img.non_idolized').show();
		} else {
			$('#addCardModal img.idolized').show();
			$('#addCardModal img.non_idolized').hide();
	  }
	    } else {
		$('#addCardModal #id_prefer_unidolized_image').parent().hide();
		$('#addCardModal #id_max_level').parent().hide();
		$('#addCardModal #id_max_bond').parent().hide();
		$('#addCardModal #id_max_level').prop('checked', false);
		$('#addCardModal #id_max_bond').prop('checked', false);
		$('#addCardModal img.idolized').hide();
		$('#addCardModal img.non_idolized').show();
	    }
	};
	idolizedCheckBoxHandler();

	var cardImagePreferenceHandler = function() {
	    if($('#addCardModal #id_idolized').is(":checked") || $('#addCardModal #id_idolized').val() == 'True') {
		    if($('#addCardModal #id_prefer_unidolized_image').is(":checked") || $('#addCardModal #id_prefer_unidolized_image').val() == 'True') {
					$('#addCardModal img.idolized').hide();
					$('#addCardModal img.non_idolized').show();
		    } else {
					$('#addCardModal img.idolized').show();
					$('#addCardModal img.non_idolized').hide();
		    }
		  }
	};
	cardImagePreferenceHandler();

	$('#addCardModal #id_idolized').unbind('change');
	$('#addCardModal #id_idolized').change(idolizedCheckBoxHandler);

	$('#addCardModal #id_prefer_unidolized_image').unbind('change');
	$('#addCardModal #id_prefer_unidolized_image').change(cardImagePreferenceHandler);
    }

    $('#addCardModal #id_stored').unbind('change');
    $('#addCardModal #id_stored').change(function() {
	expirationHandler();
	storedOnChange();
    });
}

function onClickEditCard(cardButton, ownedcardelt) {
    var saveAddForm = $('#addCardModal .modal-body').html();
    var saveAddTitle = $('#addCardModal .modal-title').text();
    var card = cardButton.closest('.card');
    $.get('/ajax/editcard/' + ownedcardelt.attr('data-id') + '/', function(data) {
	$('#addCardModal .modal-body').html(data);
	$('#addCardModal .modal-title').text((is_japanese ? 'カードの変更' : 'Edit card'));
	$('#addCardModal').modal('show');
	hidePopovers();

	addCardFormHandler($('#addCardModal img.non_idolized').prop('src'),
			   $('#addCardModal img.idolized').prop('src'),
			   card);

	var onDone = function() {
	    $('#addCardModal').modal('hide');
	    $('#addCardModal .modal-body').html(saveAddForm);
	    $('#addCardModal .modal-title').text(saveAddTitle);
	};

	$('#addCardModal form.edit').unbind('submit');
	var onSubmit = function(e) {
	    e.preventDefault();
	    $(this).ajaxSubmit({
		success: function(data) {
		    if ($(data).hasClass('ownedcardonbottom')) {
			ownedcardelt.replaceWith(data);
			onDone();
			editCardFormHandler();
			$('[data-toggle="popover"]').popover();
		    } else {
			$('#addCardModal .modal-body').html(data);
			$('#addCardModal form.edit').submit(onSubmit);
			addCardFormHandler($('#addCardModal img.non_idolized').prop('src'),
					   $('#addCardModal img.idolized').prop('src'),
					   card);
		    }
		},
		error: function() {
		    onDone();
		    alert('Opps! Something bad happened. Try again.');
		}
	    });
	};
	$('#addCardModal form.edit').submit(onSubmit);
	$('#addCardModal form.delete').unbind('submit');
	$('#addCardModal form.delete').submit(function(e) {
	    e.preventDefault();
	    $(this).ajaxSubmit({
		success: function(data) {
		    ownedcardelt.replaceWith(data);
		    onDone();
		    editCardFormHandler();
		},
		error: function() {
		    onDone();
		    alert('Opps! Something bad happened. Try again.');
		}
	    });
	});
	$('#addCardModal').on('hidden.bs.modal', function (e) {
	    onDone();
	})
    });
}

function editCardFormHandler() {
    // EDIT CARD
    $('a[href="#editCard"]').unbind('click');
    $('a[href="#editCard"]').click(function(e) {
	var cardButton = $(this);
	onClickEditCard(cardButton, cardButton);
	return false;
    });
}

$(document).ready(function() {
    editCardFormHandler();
});
<commit_msg>Uncheck id_prefer_unidolized_image when id_idolized is unchecked<commit_after>
function addCardFormHandler(non_idolized_card_url, idolized_card_url, card) {
    $('#addCardModal #id_max_level').parent().hide();
    $('#addCardModal #id_max_bond').parent().hide();

    var expirationHandler = function() {
	if ($('#addCardModal #id_stored').val() == 'Box') {
	    $('#addCardModal label[for=id_expires_in]').parent().show();
	} else {
	    $('#addCardModal label[for=id_expires_in]').parent().hide();
	    $('#addCardModal label[for=id_expires_in]').parent().find('input').val('');
	}
    };
    expirationHandler();

    var storedOnChange = function() {
	if ($('#addCardModal #id_stored').val() != 'Deck') {
	    $('#addCardModal #id_skill').closest('.form-group').hide();
	    $('#addCardModal #id_skill').val(1);
	    $('#addCardModal #id_skill_slots').closest('.form-group').hide();
	} else {
	    $('#addCardModal #id_skill').closest('.form-group').show();
	    $('#addCardModal #id_skill_slots').closest('.form-group').show();
	}
    };
    storedOnChange();

    if (typeof non_idolized_card_url == 'undefined') {
	$('#addCardModal #id_idolized').prop('checked', true);
	$('#addCardModal #id_max_level').parent().show();
	$('#addCardModal #id_max_bond').parent().show();
	$('#addCardModal #id_idolized').parent().hide();
	$('#addCardModal img.non_idolized').hide();
	$('#addCardModal img.idolized').prop('src', idolized_card_url);
    } else {
	$('#addCardModal #id_idolized').parent().show();
	$('#addCardModal img.non_idolized').prop('src', non_idolized_card_url);
	$('#addCardModal img.idolized').prop('src', idolized_card_url).hide();

	var idolizedCheckBoxHandler = function() {
	    if($('#addCardModal #id_idolized').is(":checked") || $('#addCardModal #id_idolized').val() == 'True') {
		$('#addCardModal #id_prefer_unidolized_image').parent().show();
		$('#addCardModal #id_max_level').parent().show();
		$('#addCardModal #id_max_bond').parent().show();
    if($('#addCardModal #id_prefer_unidolized_image').is(":checked") || $('#addCardModal #id_prefer_unidolized_image').val() == 'True') {
			$('#addCardModal img.idolized').hide();
			$('#addCardModal img.non_idolized').show();
		} else {
			$('#addCardModal img.idolized').show();
			$('#addCardModal img.non_idolized').hide();
	  }
	    } else {
		$('#addCardModal #id_prefer_unidolized_image').parent().hide();
        $('#addCardModal #id_prefer_unidolized_image').prop('checked', false);
		$('#addCardModal #id_max_level').parent().hide();
		$('#addCardModal #id_max_bond').parent().hide();
		$('#addCardModal #id_max_level').prop('checked', false);
		$('#addCardModal #id_max_bond').prop('checked', false);
		$('#addCardModal img.idolized').hide();
		$('#addCardModal img.non_idolized').show();
	    }
	};
	idolizedCheckBoxHandler();

	var cardImagePreferenceHandler = function() {
	    if($('#addCardModal #id_idolized').is(":checked") || $('#addCardModal #id_idolized').val() == 'True') {
		    if($('#addCardModal #id_prefer_unidolized_image').is(":checked") || $('#addCardModal #id_prefer_unidolized_image').val() == 'True') {
					$('#addCardModal img.idolized').hide();
					$('#addCardModal img.non_idolized').show();
		    } else {
					$('#addCardModal img.idolized').show();
					$('#addCardModal img.non_idolized').hide();
		    }
		  }
	};
	cardImagePreferenceHandler();

	$('#addCardModal #id_idolized').unbind('change');
	$('#addCardModal #id_idolized').change(idolizedCheckBoxHandler);

	$('#addCardModal #id_prefer_unidolized_image').unbind('change');
	$('#addCardModal #id_prefer_unidolized_image').change(cardImagePreferenceHandler);
    }

    $('#addCardModal #id_stored').unbind('change');
    $('#addCardModal #id_stored').change(function() {
	expirationHandler();
	storedOnChange();
    });
}

function onClickEditCard(cardButton, ownedcardelt) {
    var saveAddForm = $('#addCardModal .modal-body').html();
    var saveAddTitle = $('#addCardModal .modal-title').text();
    var card = cardButton.closest('.card');
    $.get('/ajax/editcard/' + ownedcardelt.attr('data-id') + '/', function(data) {
	$('#addCardModal .modal-body').html(data);
	$('#addCardModal .modal-title').text((is_japanese ? 'カードの変更' : 'Edit card'));
	$('#addCardModal').modal('show');
	hidePopovers();

	addCardFormHandler($('#addCardModal img.non_idolized').prop('src'),
			   $('#addCardModal img.idolized').prop('src'),
			   card);

	var onDone = function() {
	    $('#addCardModal').modal('hide');
	    $('#addCardModal .modal-body').html(saveAddForm);
	    $('#addCardModal .modal-title').text(saveAddTitle);
	};

	$('#addCardModal form.edit').unbind('submit');
	var onSubmit = function(e) {
	    e.preventDefault();
	    $(this).ajaxSubmit({
		success: function(data) {
		    if ($(data).hasClass('ownedcardonbottom')) {
			ownedcardelt.replaceWith(data);
			onDone();
			editCardFormHandler();
			$('[data-toggle="popover"]').popover();
		    } else {
			$('#addCardModal .modal-body').html(data);
			$('#addCardModal form.edit').submit(onSubmit);
			addCardFormHandler($('#addCardModal img.non_idolized').prop('src'),
					   $('#addCardModal img.idolized').prop('src'),
					   card);
		    }
		},
		error: function() {
		    onDone();
		    alert('Opps! Something bad happened. Try again.');
		}
	    });
	};
	$('#addCardModal form.edit').submit(onSubmit);
	$('#addCardModal form.delete').unbind('submit');
	$('#addCardModal form.delete').submit(function(e) {
	    e.preventDefault();
	    $(this).ajaxSubmit({
		success: function(data) {
		    ownedcardelt.replaceWith(data);
		    onDone();
		    editCardFormHandler();
		},
		error: function() {
		    onDone();
		    alert('Opps! Something bad happened. Try again.');
		}
	    });
	});
	$('#addCardModal').on('hidden.bs.modal', function (e) {
	    onDone();
	})
    });
}

function editCardFormHandler() {
    // EDIT CARD
    $('a[href="#editCard"]').unbind('click');
    $('a[href="#editCard"]').click(function(e) {
	var cardButton = $(this);
	onClickEditCard(cardButton, cardButton);
	return false;
    });
}

$(document).ready(function() {
    editCardFormHandler();
});
<|endoftext|>