<commit_before>/*
* Code adapted from here: http://codepen.io/miam84/pen/aNMryw
* Original code by BY Yann L
*/
function getMouseOffset (e, id) {
    var xpos, ypos;
    if (typeof e.offsetX === 'undefined') { // ff hack
        xpos = e.pageX - $('#' + id).offset().left; //dans ce cas, jQuery nécessaire pour l'appel d'offset
        ypos = e.pageY - $('#' + id).offset().top;
    } else {
        xpos = e.offsetX;
        ypos = e.offsetY;
    }
    return { x: xpos, y: ypos };
}

/**
* Extends Canvas element to use it as a paint element
*/
var extendCanvas = function (canvas) {
  if (typeof canvas === 'string') {
    canvas = document.getElementById(canvas);
  }
  try {
    canvas.ctx = canvas.getContext('2d');
    canvas.ctx.strokeStyle = "black";
    canvas.ctx.lineWidth = 8;
    canvas.lineJoin = "round";
    canvas.ctx.scale(1, 1);
    canvas.isLocked = false;
    canvas.hasDrawn = false;

    canvas.disableSave = true;
    canvas.pixels = [];
    canvas.cpixels = [];
    canvas.xyLast = {};
    canvas.xyAddLast = {};
    canvas.calculate = false;

    //start drawing a stroke from a position
    canvas.draw = function (x, y) {
      this.ctx.lineTo(x, y);
      this.ctx.stroke();
    };
    //Get the mouse position in the canvas
    canvas.getCursorCoords = function (e) {
      return getMouseOffset(e, this.id);
    };
    //Clear the content of the canvas element
    canvas.clear = function () {
      if (!this.isLocked) {
        this.ctx.clearRect(0, 0, this.width, this.height);
        this.emptyRelatedField();
        this.isModified(false);
      }
    };
    //Lock the canvas element
    canvas.lock = function (shouldLock) {
      this.isLocked = shouldLock;
      if (shouldLock) {
        $(this).addClass('disabled');
      } else {
        $(this).removeClass('disabled');
      }
    };
    canvas.isModified = function (wasModified) {
      if (wasModified) {
        this.fillRelatedField();
        $(this).addClass('modified');
      } else {
        this.emptyRelatedField();
        $(this).removeClass('modified');
      }
    };
    //Empty the field that contains the base64 string
    canvas.emptyRelatedField = function () {
      var relatedField = document.getElementById('data-' + this.id);
      if (relatedField) {
        relatedField.value = "";
      }
    };
    //Fill the filed that contains the base64 string
    canvas.fillRelatedField = function () {
      document.getElementById('data-' + this.id).value = this.toDataURL();
    };
    //Load a passed image
    canvas.loadImage = function (base64Img) {
      //if (!canvas.isLocked) {
      var image = new Image();
      var thisCanvas = this;
      if (base64Img.indexOf("data:image/png;base64,") === -1) {
        base64Img = "data:image/png;base64," + base64Img;
      }
      image.src = base64Img;
      image.onload = function () {
        var offset = { x: 0, y: 0 };
        //center the image in the canvas
        try {
          offset.x = ((thisCanvas.width / 2) - (image.width / 2));
          offset.y = ((thisCanvas.height / 2) - (image.height / 2));
          if (offset.x < 0 || offset.y < 0) {
            throw {
              name: "Painting error",
              message: "Image has a negative offset.",
              toString: function () { return this.name + ": " + this.message; }
            };
          }
        } catch (err) {
          offset = { x: 0, y: 0 };
        }
        thisCanvas.ctx.drawImage(image, offset.x, offset.y);
      };
    };

    /**
            * This method remove the event by default, to load them only when clicking in the canvas
            */
    function remove_event_listeners() {
      canvas.removeEventListener('mousemove', on_mousemove, false);
      canvas.removeEventListener('mouseup', on_mouseup, false);
      canvas.removeEventListener('touchmove', on_mousemove, false);
      canvas.removeEventListener('touchend', on_mouseup, false);
      document.body.removeEventListener('mouseup', on_mouseup, false);
      document.body.removeEventListener('touchend', on_mouseup, false);
    };
    //Event when the mouse is clicked
    function on_mousedown(e) {
      if (!canvas.isLocked) {
        e.preventDefault();
        e.stopPropagation();

        canvas.hasDrawn = false;
        //we activate the mouse and touch events
        canvas.addEventListener('mouseup', on_mouseup, false);
        canvas.addEventListener('mousemove', on_mousemove, false);
        canvas.addEventListener('touchend', on_mouseup, false);
        canvas.addEventListener('touchmove', on_mousemove, false);
        document.body.addEventListener('mouseup', on_mouseup, false);
        document.body.addEventListener('touchend', on_mouseup, false);

        var xy = canvas.getCursorCoords(e);
        canvas.ctx.beginPath();
        canvas.pixels.push('moveStart');
        canvas.ctx.moveTo(xy.x, xy.y);
        canvas.pixels.push(xy.x, xy.y);
        canvas.xyLast = xy;
      }
    };
    //Event when the mouse is moving.
    function on_mousemove(e, finish) {
      if (!canvas.isLocked) {
        e.preventDefault();
        e.stopPropagation();

        canvas.hasDrawn = true;
        var xy = canvas.getCursorCoords(e);
        var xyAdd = {
          x: (canvas.xyLast.x + xy.x) / 2,
          y: (canvas.xyLast.y + xy.y) / 2
        };
        if (canvas.calculate) {
          var xLast = (canvas.xyAddLast.x + canvas.xyLast.x + xyAdd.x) / 3;
          var yLast = (canvas.xyAddLast.y + canvas.xyLast.y + xyAdd.y) / 3;
          canvas.pixels.push(xLast, yLast);
        } else {
          canvas.calculate = true;
        }
        canvas.ctx.quadraticCurveTo(canvas.xyLast.x, canvas.xyLast.y, xyAdd.x, xyAdd.y);
        canvas.pixels.push(xyAdd.x, xyAdd.y);
        canvas.ctx.stroke();
        canvas.ctx.beginPath();
        canvas.ctx.moveTo(xyAdd.x, xyAdd.y);
        canvas.xyAddLast = xyAdd;
        canvas.xyLast = xy;
      }
    };
    //Event when the click is released
    function on_mouseup(e) {
      if (!canvas.isLocked) {
        if (!canvas.hasDrawn) {//If there was no move, draw a single point
          var pos = canvas.getCursorCoords(e);
          canvas.ctx.rect(pos.x, pos.y, 1, 1);
        }
        remove_event_listeners();
        canvas.disableSave = false;
        canvas.ctx.stroke();
        canvas.pixels.push('e');
        canvas.calculate = false;
        canvas.isModified(true);
        canvas.hasDrawn = false;
      }
    };
    //We activate only the click or touch event.
    // ReSharper disable once Html.EventNotResolved correspond à un événement de toucher sur écran tactile
    canvas.addEventListener('touchstart', on_mousedown, false);
    canvas.addEventListener('mousedown', on_mousedown, false);

  } catch (err) {
    //If someting went wrong, notify the user.
    console.error("Canvas not initialized. Painting is not activated.");
  }

  return canvas;
};

var myC = extendCanvas('paint');
$('#clear').on('click', (e) => {
  myC.clear();
  myC.emptyRelatedField();
});
<commit_msg>Edited one comment<commit_after>/*
* Code adapted from here: http://codepen.io/miam84/pen/aNMryw
* Original code by BY Yann L
*/
function getMouseOffset (e, id) {
    var xpos, ypos;
    if (typeof e.offsetX === 'undefined') { // ff hack
        xpos = e.pageX - $('#' + id).offset().left; //dans ce cas, jQuery nécessaire pour l'appel d'offset
        ypos = e.pageY - $('#' + id).offset().top;
    } else {
        xpos = e.offsetX;
        ypos = e.offsetY;
    }
    return { x: xpos, y: ypos };
}

/**
* Extends Canvas element to use it as a paint element
*/
var extendCanvas = function (canvas) {
  if (typeof canvas === 'string') {
    canvas = document.getElementById(canvas);
  }
  try {
    canvas.ctx = canvas.getContext('2d');
    canvas.ctx.strokeStyle = "black";
    canvas.ctx.lineWidth = 8;
    canvas.lineJoin = "round";
    canvas.ctx.scale(1, 1);
    canvas.isLocked = false;
    canvas.hasDrawn = false;

    canvas.disableSave = true;
    canvas.pixels = [];
    canvas.cpixels = [];
    canvas.xyLast = {};
    canvas.xyAddLast = {};
    canvas.calculate = false;

    //start drawing a stroke from a position
    canvas.draw = function (x, y) {
      this.ctx.lineTo(x, y);
      this.ctx.stroke();
    };
    //Get the mouse position in the canvas
    canvas.getCursorCoords = function (e) {
      return getMouseOffset(e, this.id);
    };
    //Clear the content of the canvas element
    canvas.clear = function () {
      if (!this.isLocked) {
        this.ctx.clearRect(0, 0, this.width, this.height);
        this.emptyRelatedField();
        this.isModified(false);
      }
    };
    //Lock the canvas element
    canvas.lock = function (shouldLock) {
      this.isLocked = shouldLock;
      if (shouldLock) {
        $(this).addClass('disabled');
      } else {
        $(this).removeClass('disabled');
      }
    };
    canvas.isModified = function (wasModified) {
      if (wasModified) {
        this.fillRelatedField();
        $(this).addClass('modified');
      } else {
        this.emptyRelatedField();
        $(this).removeClass('modified');
      }
    };
    //Empty the field that contains the base64 string
    canvas.emptyRelatedField = function () {
      var relatedField = document.getElementById('data-' + this.id);
      if (relatedField) {
        relatedField.value = "";
      }
    };
    //Fill the filed that contains the base64 string
    canvas.fillRelatedField = function () {
      document.getElementById('data-' + this.id).value = this.toDataURL();
    };
    //Load a passed image
    canvas.loadImage = function (base64Img) {
      //if (!canvas.isLocked) {
      var image = new Image();
      var thisCanvas = this;
      if (base64Img.indexOf("data:image/png;base64,") === -1) {
        base64Img = "data:image/png;base64," + base64Img;
      }
      image.src = base64Img;
      image.onload = function () {
        var offset = { x: 0, y: 0 };
        //center the image in the canvas
        try {
          offset.x = ((thisCanvas.width / 2) - (image.width / 2));
          offset.y = ((thisCanvas.height / 2) - (image.height / 2));
          if (offset.x < 0 || offset.y < 0) {
            throw {
              name: "Painting error",
              message: "Image has a negative offset.",
              toString: function () { return this.name + ": " + this.message; }
            };
          }
        } catch (err) {
          offset = { x: 0, y: 0 };
        }
        thisCanvas.ctx.drawImage(image, offset.x, offset.y);
      };
    };

    /**
    * This method removes the event by default, to load it only when clicking in
    the canvas
    */
    function remove_event_listeners() {
      canvas.removeEventListener('mousemove', on_mousemove, false);
      canvas.removeEventListener('mouseup', on_mouseup, false);
      canvas.removeEventListener('touchmove', on_mousemove, false);
      canvas.removeEventListener('touchend', on_mouseup, false);
      document.body.removeEventListener('mouseup', on_mouseup, false);
      document.body.removeEventListener('touchend', on_mouseup, false);
    };
    //Event when the mouse is clicked
    function on_mousedown(e) {
      if (!canvas.isLocked) {
        e.preventDefault();
        e.stopPropagation();

        canvas.hasDrawn = false;
        //we activate the mouse and touch events
        canvas.addEventListener('mouseup', on_mouseup, false);
        canvas.addEventListener('mousemove', on_mousemove, false);
        canvas.addEventListener('touchend', on_mouseup, false);
        canvas.addEventListener('touchmove', on_mousemove, false);
        document.body.addEventListener('mouseup', on_mouseup, false);
        document.body.addEventListener('touchend', on_mouseup, false);

        var xy = canvas.getCursorCoords(e);
        canvas.ctx.beginPath();
        canvas.pixels.push('moveStart');
        canvas.ctx.moveTo(xy.x, xy.y);
        canvas.pixels.push(xy.x, xy.y);
        canvas.xyLast = xy;
      }
    };
    //Event when the mouse is moving.
    function on_mousemove(e, finish) {
      if (!canvas.isLocked) {
        e.preventDefault();
        e.stopPropagation();

        canvas.hasDrawn = true;
        var xy = canvas.getCursorCoords(e);
        var xyAdd = {
          x: (canvas.xyLast.x + xy.x) / 2,
          y: (canvas.xyLast.y + xy.y) / 2
        };
        if (canvas.calculate) {
          var xLast = (canvas.xyAddLast.x + canvas.xyLast.x + xyAdd.x) / 3;
          var yLast = (canvas.xyAddLast.y + canvas.xyLast.y + xyAdd.y) / 3;
          canvas.pixels.push(xLast, yLast);
        } else {
          canvas.calculate = true;
        }
        canvas.ctx.quadraticCurveTo(canvas.xyLast.x, canvas.xyLast.y, xyAdd.x, xyAdd.y);
        canvas.pixels.push(xyAdd.x, xyAdd.y);
        canvas.ctx.stroke();
        canvas.ctx.beginPath();
        canvas.ctx.moveTo(xyAdd.x, xyAdd.y);
        canvas.xyAddLast = xyAdd;
        canvas.xyLast = xy;
      }
    };
    //Event when the click is released
    function on_mouseup(e) {
      if (!canvas.isLocked) {
        if (!canvas.hasDrawn) {//If there was no move, draw a single point
          var pos = canvas.getCursorCoords(e);
          canvas.ctx.rect(pos.x, pos.y, 1, 1);
        }
        remove_event_listeners();
        canvas.disableSave = false;
        canvas.ctx.stroke();
        canvas.pixels.push('e');
        canvas.calculate = false;
        canvas.isModified(true);
        canvas.hasDrawn = false;
      }
    };
    //We activate only the click or touch event.
    // ReSharper disable once Html.EventNotResolved correspond à un événement de toucher sur écran tactile
    canvas.addEventListener('touchstart', on_mousedown, false);
    canvas.addEventListener('mousedown', on_mousedown, false);

  } catch (err) {
    //If someting went wrong, notify the user.
    console.error("Canvas not initialized. Painting is not activated.");
  }

  return canvas;
};

var myC = extendCanvas('paint');
$('#clear').on('click', (e) => {
  myC.clear();
  myC.emptyRelatedField();
});
<|endoftext|>


<commit_before>var sourcemaps = require('gulp-sourcemaps');
var babel = require('gulp-babel');
var concat = require('gulp-concat');
var invariant = require('invariant');

module.exports = function(gulp, opts){
    var config = opts.config;

    invariant(
        config.js && typeof config.js === 'object'
            && config.js.srcDir && config.js.target
            && config.js.distDir && config.js.distFilename,
        '{srcDir, target, distDir, distFilename} in config[\'js\'] is required.');

    gulp.task('default', function () {
        return gulp.src(config.js.target)
            .pipe(sourcemaps.init())
            .pipe(babel({sourceRoot: config.js.srcDir}))
            .pipe(concat(config.js.distFilename))
            .pipe(sourcemaps.write('.'))
            .pipe(gulp.dest(config.js.distDir));
    });
};
<commit_msg>rename to babel<commit_after>var sourcemaps = require('gulp-sourcemaps');
var babel = require('gulp-babel');
var concat = require('gulp-concat');
var invariant = require('invariant');

module.exports = function(gulp, opts){
    var config = opts.config;

    invariant(
        config.js && typeof config.js === 'object'
            && config.js.srcDir && config.js.target
            && config.js.distDir && config.js.distFilename,
        '{srcDir, target, distDir, distFilename} in config[\'js\'] is required.');

    gulp.task('babel', function () {
        return gulp.src(config.js.target)
            .pipe(sourcemaps.init())
            .pipe(babel({sourceRoot: config.js.srcDir}))
            .pipe(concat(config.js.distFilename))
            .pipe(sourcemaps.write('.'))
            .pipe(gulp.dest(config.js.distDir));
    });
};
<|endoftext|>


<commit_before>
(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(["drainpipe","sig-js"], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory(require('drainpipe'), require('sig-js'));
  } else {
    root.museq = factory(root.vv, root.sig);
  }
}(this, function(vv, sig) {

var museq = function() {
  var all = sig.all,
      cleanup = sig.cleanup,
      ensureSig = sig.ensure,
      spread = sig.spread,
      put = sig.put,
      then = sig.then,
      map = sig.map,
      redir = sig.redir,
      isSig = sig.isSig,
      val = sig.val,
      once = sig.once,
      update = sig.update,
      append = sig.append

  var globalOrigin = +(new Date())
  var _slice = Array.prototype.slice

  function tempo(s, ms) {
    s = ensure(s)
    s.tempo = then(ensureSig(ms), val())
    return s
  }

  function sync(s, origin) {
    s = ensure(s)
    origin = origin || globalOrigin

    return vv([s.tempo, origin])
      (all)
      (once)
      (update, spread, function(interval, origin) {
        return vv(nextIntersection(interval, origin))
          (sleep)
          (update, function() { return s })
          ()
      })
      (tempo, s.tempo)
      ()
  }

  function loop(s) {
    s = ensure(s)

    var v
    var out = sig()

    vv(s)
      (then, function(nextV) { v = nextV })
      (redir, out)

    vv(s.tempo)
      (update, tick)
      (then, function() {
        if (typeof v != 'undefined') put(this, v)
      })
      (redir, out)

    return out
  }

  function seq(s) {
    s = ensure(s)

    return append(s, function(values) {
      var i = -1

      return vv(s.tempo)
        (update, function(interval) {
          return tick(interval / values.length)
        })
        (then, function() {
          if (++i < values.length) put(this, values[i])
        })
        ()
    })
  }

  function every(s, n, fn) {
    s = ensure(s)
    var i = -n
    fn = prime(slice(arguments, 3), fn)

    return map(s, function(x) {
      return ++i % n === 0
        ? fn.call(this, x)
        : x
    })
  }

  function nextIntersection(interval, origin) {
    origin = +origin
    var now = +(new Date())
    var i = Math.ceil((now - origin) / interval)
    var then = origin + (i * interval)
    return then - now
  }

  function sleep(interval) {
    var s = sig()
    var delayId = setTimeout(resolve, interval, s)

    cleanup(s, function() {
      clearInterval(delayId)
    })

    return s
  }

  function tick(interval) {
    var s = sig()
    var intervalId = setInterval(resolve, interval, s)

    cleanup(s, function() {
      clearInterval(intervalId)
    })

    resolve(s)
    return s
  }

  function resolve(s) {
    put(s, null)
  }

  function prime(args, fn) {
    if (!args.length) return fn

    return function(x) {
      return fn.apply(this, [x].concat(args))
    }
  }

  function slice(arr, a, b) {
    return _slice.call(arr, a, b)
  }

  function ensure(v) {
    if ((v || 0).museq) return v

    // 'copy' signals to avoid assigning properties to non-museq signals
    if (isSig(v)) v = then(v, sig())

    v = ensureSig(v)
    v.museq = true
    return tempo(v, 2000)
  }

  return {
    tr: tr,
    seq: seq,
    run: run,
    loop: loop,
    sync: sync,
    every: every,
    tempo: tempo
  }
}();
museq;

return museq;

}));
<commit_msg>rebuild<commit_after>
(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(["drainpipe","sig-js"], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory(require('drainpipe'), require('sig-js'));
  } else {
    root.museq = factory(root.vv, root.sig);
  }
}(this, function(vv, sig) {

var museq = function() {
  var all = sig.all,
      cleanup = sig.cleanup,
      ensureSig = sig.ensure,
      spread = sig.spread,
      put = sig.put,
      then = sig.then,
      map = sig.map,
      redir = sig.redir,
      isSig = sig.isSig,
      val = sig.val,
      once = sig.once,
      update = sig.update,
      append = sig.append

  var globalOrigin = +(new Date())
  var _slice = Array.prototype.slice

  function tempo(s, ms) {
    s = ensure(s)
    s.tempo = then(ensureSig(ms), val())
    return s
  }

  function sync(s, origin) {
    s = ensure(s)
    origin = origin || globalOrigin

    return vv([s.tempo, origin])
      (all)
      (once)
      (update, spread, function(interval, origin) {
        return vv(nextIntersection(interval, origin))
          (sleep)
          (update, function() { return s })
          ()
      })
      (tempo, s.tempo)
      ()
  }

  function loop(s) {
    s = ensure(s)

    var v
    var out = sig()

    vv(s)
      (then, function(nextV) { v = nextV })
      (redir, out)

    vv(s.tempo)
      (update, tick)
      (then, function() {
        if (typeof v != 'undefined') put(this, v)
      })
      (redir, out)

    return out
  }

  function seq(s) {
    s = ensure(s)

    return append(s, function(values) {
      var i = -1

      return vv(s.tempo)
        (update, function(interval) {
          return tick(interval / values.length)
        })
        (then, function() {
          if (++i < values.length) put(this, values[i])
        })
        ()
    })
  }

  function every(s, n, fn) {
    s = ensure(s)
    var i = -n
    fn = prime(slice(arguments, 3), fn)

    return map(s, function(x) {
      return ++i % n === 0
        ? fn.call(this, x)
        : x
    })
  }

  function nextIntersection(interval, origin) {
    origin = +origin
    var now = +(new Date())
    var i = Math.ceil((now - origin) / interval)
    var then = origin + (i * interval)
    return then - now
  }

  function sleep(interval) {
    var s = sig()
    var delayId = setTimeout(resolve, interval, s)

    cleanup(s, function() {
      clearInterval(delayId)
    })

    return s
  }

  function tick(interval) {
    var s = sig()
    var intervalId = setInterval(resolve, interval, s)

    cleanup(s, function() {
      clearInterval(intervalId)
    })

    resolve(s)
    return s
  }

  function resolve(s) {
    put(s, null)
  }

  function prime(args, fn) {
    if (!args.length) return fn

    return function(x) {
      return fn.apply(this, [x].concat(args))
    }
  }

  function slice(arr, a, b) {
    return _slice.call(arr, a, b)
  }

  function ensure(v) {
    if ((v || 0).museq) return v

    // 'copy' signals to avoid assigning properties to non-museq signals
    if (isSig(v)) v = then(v, sig())

    v = ensureSig(v)
    v.museq = true
    return tempo(v, 2000)
  }

  return {
    seq: seq,
    loop: loop,
    sync: sync,
    every: every,
    tempo: tempo
  }
}();
museq;

return museq;

}));
<|endoftext|>


<commit_before>/* Tests for gpii-client.js
 *
 * Copyright 2017 Raising the Floor - International
 *
 * Licensed under the New BSD license. You may not use this file except in
 * compliance with this License.
 *
 * The R&D leading to these results received funding from the
 * Department of Education - Grant H421A150005 (GPII-APCP). However,
 * these results do not necessarily represent the policy of the
 * Department of Education, and you should not assume endorsement by the
 * Federal Government.
 *
 * You may obtain a copy of the License at
 * https://github.com/GPII/universal/blob/master/LICENSE.txt
 */

"use strict";

var jqUnit = require("node-jqunit"),
    gpiiClient = require("../src/gpiiClient.js");

var teardowns = [];

jqUnit.module("GPII client tests", {
    teardown: function () {
        while (teardowns.length) {
            teardowns.pop()();
        }
    }
});

var gpiiClientTests = {};

gpiiClientTests.requestTests = [
    {
        id: "execute: simple command",
        action: "execute",
        data: {
            command: "whoami"
        },
        expect: {
            promise: {
                pid: /^[0-9]+$/
            }
        }
    },
    {
        id: "execute: bad command",
        action: "execute",
        data: {
            command: "gpii-test-bad-command"
        },
        expect: {
            promise: "reject"
        }
    },
    {
        id: "execute: wait",
        action: "execute",
        data: {
            command: "whoami",
            wait: true
        },
        expect: {
            promise: {
                code: 0
            }
        }
    },
    {
        id: "execute: wait + exit code 1",
        action: "execute",
        data: {
            command: "whoami",
            args: ["/bad-option"],
            wait: true
        },
        expect: {
            promise: {
                code: 1
            }
        }
    },
    {
        id: "execute: capture output",
        action: "execute",
        data: {
            command: "cmd.exe",
            args: ["/c", "echo hello stdout & echo hello stderr 1>&2"],
            wait: true,
            capture: true
        },
        expect: {
            promise: {
                code: 0,
                signal: null,
                output: {
                    stdout: "hello stdout \r\n",
                    stderr: "hello stderr \r\n"
                }
            }
        }
    },
    {
        id: "sign",
        action: "sign",
        data: "hello",
        expect: "45be02a491dd3472deb1ec1b1a95ec50668e9b51d697cd060389a38d2c06be8d"
    },
    {
        id: "client credentials",
        action: "getClientCredentials",
        data: undefined,
        expect: {
            "client_id": "pilot-computer",
            "client_secret": "pilot-computer-secret"
        }
    }
];

/**
 * Check if all properties of expected are also in subject and are equal or match a regular expression, ignoring any
 * extra ones in subject.
 *
 * @param {Object} subject The object to check against
 * @param {Object} expected The object containing the values to check for.
 * @param {Number} maxDepth [Optional] How deep to check.
 * @return {Boolean} true if there's a match.
 */
gpiiClientTests.deepMatch = function (subject, expected, maxDepth) {
    var match = false;
    if (maxDepth < 0) {
        return false;
    } else if (!maxDepth && maxDepth !== 0) {
        maxDepth = 10;
    }

    if (!subject) {
        return subject === expected;
    }

    for (var prop in expected) {
        if (expected.hasOwnProperty(prop)) {
            var exp = expected[prop];
            if (["string", "number", "boolean"].indexOf(typeof(exp)) >= 0) {
                match = subject[prop] === exp;
            } else if (exp instanceof RegExp) {
                match = exp.test(subject[prop]);
            } else {
                match = gpiiClientTests.deepMatch(subject[prop], exp, maxDepth - 1);
            }
            if (!match) {
                break;
            }
        }
    }

    return match;
};

gpiiClientTests.assertDeepMatch = function (msg, expect, actual) {
    var match = gpiiClientTests.deepMatch(actual, expect);
    jqUnit.assertTrue(msg, match);
    if (!match) {
        console.log("expected:", expect);
        console.log("actual:", actual);
    }
};

jqUnit.asyncTest("Test request handlers", function () {

    var tests = gpiiClientTests.requestTests;
    jqUnit.expect(tests.length * 3);

    var testIndex = -1;
    var nextTest = function () {
        if (++testIndex >= tests.length) {
            jqUnit.start();
            return;
        }
        var test = tests[testIndex];

        var suffix = " - testIndex=" + testIndex + " (" + (test.id || test.action) + ")";

        var handler = gpiiClient.requestHandlers[test.action];

        jqUnit.assertEquals("request handler should be a function" + suffix, "function", typeof handler);

        var result = handler(test.data);

        if (test.expect.promise) {
            jqUnit.assertTrue("request handler should return a promise" + suffix,
                result && typeof(result.then) === "function");

            result.then(function (value) {
                gpiiClientTests.assertDeepMatch("request handler should resolve with the expected value" + suffix,
                    test.expect.promise, value);

                nextTest();
            }, function (err) {
                jqUnit.assertEquals("request handler should only reject if expected" + suffix,
                    test.expect.promise, "reject");

                if (test.expect.promise !== "reject") {
                    console.log("Rejection:", err);
                }

                nextTest();
            });
        } else {
            gpiiClientTests.assertDeepMatch("request handler should return the expected value" + suffix,
                test.expect, result);
            jqUnit.assert("balancing assert count");
            nextTest();
        }
    };

    nextTest();

});
<commit_msg>GPII-2338: Stopped cmd.exe complaining about a UNC path<commit_after>/* Tests for gpii-client.js
 *
 * Copyright 2017 Raising the Floor - International
 *
 * Licensed under the New BSD license. You may not use this file except in
 * compliance with this License.
 *
 * The R&D leading to these results received funding from the
 * Department of Education - Grant H421A150005 (GPII-APCP). However,
 * these results do not necessarily represent the policy of the
 * Department of Education, and you should not assume endorsement by the
 * Federal Government.
 *
 * You may obtain a copy of the License at
 * https://github.com/GPII/universal/blob/master/LICENSE.txt
 */

"use strict";

var jqUnit = require("node-jqunit"),
    gpiiClient = require("../src/gpiiClient.js");

var teardowns = [];

jqUnit.module("GPII client tests", {
    teardown: function () {
        while (teardowns.length) {
            teardowns.pop()();
        }
    }
});

var gpiiClientTests = {};

gpiiClientTests.requestTests = [
    {
        id: "execute: simple command",
        action: "execute",
        data: {
            command: "whoami"
        },
        expect: {
            promise: {
                pid: /^[0-9]+$/
            }
        }
    },
    {
        id: "execute: bad command",
        action: "execute",
        data: {
            command: "gpii-test-bad-command"
        },
        expect: {
            promise: "reject"
        }
    },
    {
        id: "execute: wait",
        action: "execute",
        data: {
            command: "whoami",
            wait: true
        },
        expect: {
            promise: {
                code: 0
            }
        }
    },
    {
        id: "execute: wait + exit code 1",
        action: "execute",
        data: {
            command: "whoami",
            args: ["/bad-option"],
            wait: true
        },
        expect: {
            promise: {
                code: 1
            }
        }
    },
    {
        id: "execute: capture output",
        action: "execute",
        data: {
            command: "cmd.exe",
            // Send something to stdout and stderr
            args: ["/c", "echo hello stdout & echo hello stderr 1>&2"],
            options: {
                // Set the working directory to prevent cmd.exe complaining about being on a UNC path.
                cwd: process.env.SystemRoot || "C:\\"
            },
            wait: true,
            capture: true
        },
        expect: {
            promise: {
                code: 0,
                signal: null,
                output: {
                    stdout: "hello stdout \r\n",
                    stderr: "hello stderr \r\n"
                }
            }
        }
    },
    {
        id: "sign",
        action: "sign",
        data: "hello",
        expect: "45be02a491dd3472deb1ec1b1a95ec50668e9b51d697cd060389a38d2c06be8d"
    },
    {
        id: "client credentials",
        action: "getClientCredentials",
        data: undefined,
        expect: {
            "client_id": "pilot-computer",
            "client_secret": "pilot-computer-secret"
        }
    }
];

/**
 * Check if all properties of expected are also in subject and are equal or match a regular expression, ignoring any
 * extra ones in subject.
 *
 * @param {Object} subject The object to check against
 * @param {Object} expected The object containing the values to check for.
 * @param {Number} maxDepth [Optional] How deep to check.
 * @return {Boolean} true if there's a match.
 */
gpiiClientTests.deepMatch = function (subject, expected, maxDepth) {
    var match = false;
    if (maxDepth < 0) {
        return false;
    } else if (!maxDepth && maxDepth !== 0) {
        maxDepth = 10;
    }

    if (!subject) {
        return subject === expected;
    }

    for (var prop in expected) {
        if (expected.hasOwnProperty(prop)) {
            var exp = expected[prop];
            if (["string", "number", "boolean"].indexOf(typeof(exp)) >= 0) {
                match = subject[prop] === exp;
            } else if (exp instanceof RegExp) {
                match = exp.test(subject[prop]);
            } else {
                match = gpiiClientTests.deepMatch(subject[prop], exp, maxDepth - 1);
            }
            if (!match) {
                break;
            }
        }
    }

    return match;
};

gpiiClientTests.assertDeepMatch = function (msg, expect, actual) {
    var match = gpiiClientTests.deepMatch(actual, expect);
    jqUnit.assertTrue(msg, match);
    if (!match) {
        console.log("expected:", expect);
        console.log("actual:", actual);
    }
};

jqUnit.asyncTest("Test request handlers", function () {

    var tests = gpiiClientTests.requestTests;
    jqUnit.expect(tests.length * 3);

    var testIndex = -1;
    var nextTest = function () {
        if (++testIndex >= tests.length) {
            jqUnit.start();
            return;
        }
        var test = tests[testIndex];

        var suffix = " - testIndex=" + testIndex + " (" + (test.id || test.action) + ")";

        var handler = gpiiClient.requestHandlers[test.action];

        jqUnit.assertEquals("request handler should be a function" + suffix, "function", typeof handler);

        var result = handler(test.data);

        if (test.expect.promise) {
            jqUnit.assertTrue("request handler should return a promise" + suffix,
                result && typeof(result.then) === "function");

            result.then(function (value) {
                gpiiClientTests.assertDeepMatch("request handler should resolve with the expected value" + suffix,
                    test.expect.promise, value);

                nextTest();
            }, function (err) {
                jqUnit.assertEquals("request handler should only reject if expected" + suffix,
                    test.expect.promise, "reject");

                if (test.expect.promise !== "reject") {
                    console.log("Rejection:", err);
                }

                nextTest();
            });
        } else {
            gpiiClientTests.assertDeepMatch("request handler should return the expected value" + suffix,
                test.expect, result);
            jqUnit.assert("balancing assert count");
            nextTest();
        }
    };

    nextTest();

});
<|endoftext|>


<commit_before>var ffmpeg = require('fluent-ffmpeg');
var fs = require('fs');
var Q = require('q');
var events = require('events');
var spawn = require('child_process').spawn;

var videos, inputs;
var output = process.argv[2];
var outfile;
var promises = [];
var threadsQueue = [];
var MAX_THREADS = 4;

fs.readdir('./video/', function (err, list) {
  videos = list;
  var filesPromise = Q.defer();
  promises.push(filesPromise.promise);
  muxing(list, filesPromise);
});

var muxing = function (list, filesPromise) {
  console.log('Getting duration of videos')
  list.forEach(function (video, i) {
    ffmpeg.ffprobe('./video/' + video, function (err, metadata) {
      theMachine(metadata, video, i, (i === list.length - 1), filesPromise);
    });
  });
};

var seekAndStrip = function (duration, video, promise, index) {
 ffmpeg('./video/' + video).seek(duration / 2).setDuration(2.0)
    .output('./tmp/' + index + '.mp4')
    .on('end', function () {
      console.log('################ Im resolvingyieha')
      promise.resolve();
    })
  .run()
};

Make promises -> add to queue.
If queue done, make more promises,
   until finally queue is empty.

var theMachine = function (metadata, video, index, last, filesPromise) {
  var emptyQueue = true;
  var threadsPromise;
  var duration = metadata.format.duration;
  var outfile;
  var promise = Q.defer();
  promises.push(promise.promise);

  if (threadsQueue.length < 4) {
    threadsQueue.push(promise.promise);
    emptyQueue = false;
    seekAndStrip(duration, video, promise, index);
    if (emptyQueue) {
    threadsPromise = Q.all(threadsQueue)
      .then(function () {
        emptyQueue = true;
        threadsQueue = [];
      });
    }
  }
    if (last) {
      Q.all(promises)
        .then(merger);
      filesPromise.resolve();
    }
}

var merger = function () {
  console.log('Concatenating videos, this takes a while');
  var concatString = "";
  fs.readdir('./tmp/', function (err, list) {
    list.forEach(function (tmp, i) {
      concatString += 'file tmp/' + tmp + "\n";
    });
    fs.writeFileSync('input.txt', concatString);
    concat = spawn('ffmpeg', ['-y', '-f', 'concat', '-i', 'input.txt', 'out.mp4']);
    concat.stderr.on('data', function (data) {
      console.log('error' + data)
    });
    concat.on('close', function (code) {
      console.log(code);
    });
  });

};

<commit_msg>i think it's working<commit_after>var ffmpeg = require('fluent-ffmpeg');
var fs = require('fs');
var Q = require('q');
var events = require('events');
var spawn = require('child_process').spawn;

var videos, inputs;
var output = process.argv[2];
var outfile;
var promises = [];
var threadsQueue = [];
var MAX_THREADS = 4;

fs.readdir('./video/', function (err, list) {
  videos = list;
  var filesPromise = Q.defer();
  promises.push(filesPromise.promise);
  muxing(list, filesPromise);
});

var muxing = function (list, filesPromise) {
  console.log('Getting duration of videos')
  list.forEach(function (video, i) {
    ffmpeg.ffprobe('./video/' + video, function (err, metadata) {
      theMachine(metadata, video, i, (i === list.length - 1), filesPromise);
    });
  });
};

var seekAndStrip = function (duration, video, promise, index) {
 ffmpeg('./video/' + video).seek(duration / 2).setDuration(2.0)
    .output('./tmp/' + index + '.mp4')
    .on('end', function () {
      console.log('################ Im resolvingyieha')
      promise.resolve();
    })
  .run()
};

//Make promises -> add to queue.
//If queue done, make more promises,
   //until finally queue is empty.

var worker = function () {
  var localPromises = [];
  var things = threadsQueue.splice(0, MAX_THREADS);
  things.forEach(function (thing, index) {
    localPromises.push(thing.promise.promise);
    seekAndStrip(thing.duration, thing.video, thing.promise, thing.index);
    if (things.length > 0 && index === things.length -1) {
      Q.all(localPromises).then(worker);
    }
  });
};

var theMachine = function (metadata, video, index, last, filesPromise) {
  var emptyQueue = true;
  var threadsPromise;
  var duration = metadata.format.duration;
  var outfile;
  var promise = Q.defer();
  promises.push(promise.promise);
  threadsQueue.push({
    duration: duration,
    video: video,
    promise: promise,
    index: index
  });

   if (last) {
      Q.all(promises)
        .finally(merger);
      filesPromise.resolve();
      worker();
    }
}

var merger = function () {
  console.log('Concatenating videos, this takes a while');
  var concatString = "";
  fs.readdir('./tmp/', function (err, list) {
    list.forEach(function (tmp, i) {
      concatString += 'file tmp/' + tmp + "\n";
    });
    fs.writeFileSync('input.txt', concatString);
    concat = spawn('ffmpeg', ['-y', '-f', 'concat', '-i', 'input.txt', 'out.mp4']);
    concat.stderr.on('data', function (data) {
      console.log('error' + data)
    });
    concat.on('close', function (code) {
      console.log(code);
    });
  });

};

<|endoftext|>


<commit_before><commit_msg>debug: print changelog sections<commit_after><|endoftext|>


<commit_before>var G = 6.67408 * Math.pow(10, -11); // m^3 kg^-1 s^-2

// An enum of available levels of logging.
var loglevels = {
  critical: {name: 'critical', value: 0},
  error: {name: 'error', value: 1},
  warn: {name: 'warn', value: 2},
  debug: {name: 'debug', value: 3},
  info: {name: 'info', value: 4},
  trace: {name: 'trace', value: 5}
};
// The default level of logging.  Set this to null to avoid logging entirely.
var loglevel = loglevels.warn;
var log = function(level, message) {
  // Log a message.
  //
  // Args:
  //  level: A member of loglevels.
  //  message: A message to log.
  if (loglevel === null) return;
  var l = loglevels[level];
  if (l.value <= loglevel.value) console.log('[' + loglevel.name + ']');
};

var State = function(x, v, a, m) {
  // A state of a body in the simulation.
  var self = this;

  // The position (m).
  self.x = x || new Vector([0, 0]);
  // The velocity (m s^-1).
  self.v = v || new Vector([0, 0]);
  // The acceleration (m s^-2).
  self.a = a || new Vector([0, 0]);
  // The mass (kg).
  self.m = m || 0;

  self.hash = function() {
    // Generate a hash of the state for use in caching.
    //
    // Returns:
    //  A hash of the state.
    return '[' + self.x.hash() + ',' + self.v.hash() + ',' + self.a.hash() + ',' + self.m + ']';
  };

  // A cache of get_force calculations.
  self._forces = {};
  self.get_force = function(other) {
    // Get the force on this state by another.
    //
    // This function is cached for each value of other.  In addition, this
    // function sets the cache on other.
    //
    // Args:
    //  other: Another body instance.
    //
    // Returns:
    //  The gravitational force vector of other applied on this state.
    var r;
    var f;
    var hash;
    var other_hash = other.hash();

    if (self._forces[other_hash] === undefined) {
      hash = self.hash();
      r = other.x.subtract(self.x);
      f = r.unit().multiply(
        1 * G * self.m * other.m /
        Math.pow(r.magnitude(), 2)); // (kg m s^-2)

      self._forces[other_hash] = f;
      // Every action has an equal and opposite reaction.
      other._forces[hash] = f.multiply(-1)
    }
    return self._forces[other_hash];
  };
};

var Body = function() {
  // A planetary body.
  //
  // Args:
  //  state: The initial state of the body.
  var self = this;

  // A list of states.
  self.states = [];

  self.set_state = function(state) {
    // Set the state of the body.
    //
    // Args:
    //  state: A State instance.
    //
    // Returns:
    //  self
    if (self.states.length > 5)
      self.states = self.states.slice(
        self.states.length - 5,
        self.states.length);
    self.states.push(state);
    return self;
  };

  self.get_state = function() {
    // Get the current state of the body.
    //
    // Returns:
    //  The last State in the body's history.
    return self.states[self.states.length - 1];
  };
};

var Simulation = function() {
  // An N-body simulation.
  var self = this;

  // The bodies of the simulation.
  self.bodies = [];

  // The size of the simulation timestep (s).
  self.step_size = .5;

  self.add_body = function(body) {
    // Add a body to the simulation.
    //
    // Args:
    //  body: A Body instance.
    //
    // Returns:
    //  self
    self.bodies.push(body);
    return self;
  };

  self.step = function() {
    // Generate the next step in the simulation and apply it.
    //
    // TODO: Add a half-step velocity calculation.
    // TODO: Add collision detection.
    //
    // Returns:
    //  self
    var i, j;
    var a, f;
    var old_state, new_state;
    var new_xs = [];
    var new_states = [];

    // Create a list of new states for each body in self.bodies.  And
    //  calculate their new position.
    for (i = 0; i < self.bodies.length; i++) {
      old_state = self.bodies[i].get_state();
      new_state = new State();

      // Velocity verlet.
      // x = x + vt + .5at^2
      new_state.x = old_state.x
        .add(old_state.v.multiply(self.step_size))
        .add(old_state.a.multiply(.5 * Math.pow(self.step_size, 2)));
      new_state.m = old_state.m;

      // Initially create the state with just the new position.
      new_states.push(new_state);
    }

    // Calculate the new velocity from the states created above.
    // This looks like it is O(n^2).  However, because State.get_force is
    //  cached (and reverse-cached), it's actually O(n log(n)).
    for (i = 0; i < new_states.length; i++) {
      old_state = self.bodies[i].get_state();
      new_state = new_states[i];

      // Calculate an force vector as the sum of the gravity due to every other
      //  body in the simulation.
      f = new Vector([0, 0]);
      for (j = 0; j < new_states.length; j++) {
        if (i != j) {
          f = f.add(new_state.get_force(new_states[j]));
        }
      }
      a = f.divide(old_state.m);

      // Velocity verlet.
      new_state.a = a;
      // v = v + .5(old_a + a)t
      new_state.v = old_state.v
        .add(new_state.a
          .add(old_state.a)
          .multiply(.5 * self.step_size));
    }

    // Set the new states.
    for (i = 0; i < self.bodies.length; i++) {
      self.bodies[i].set_state(new_states[i]);
    }

    return self;
  };
};
<commit_msg>Add additional clarification to the get_force comment.<commit_after>var G = 6.67408 * Math.pow(10, -11); // m^3 kg^-1 s^-2

// An enum of available levels of logging.
var loglevels = {
  critical: {name: 'critical', value: 0},
  error: {name: 'error', value: 1},
  warn: {name: 'warn', value: 2},
  debug: {name: 'debug', value: 3},
  info: {name: 'info', value: 4},
  trace: {name: 'trace', value: 5}
};
// The default level of logging.  Set this to null to avoid logging entirely.
var loglevel = loglevels.warn;
var log = function(level, message) {
  // Log a message.
  //
  // Args:
  //  level: A member of loglevels.
  //  message: A message to log.
  if (loglevel === null) return;
  var l = loglevels[level];
  if (l.value <= loglevel.value) console.log('[' + loglevel.name + ']');
};

var State = function(x, v, a, m) {
  // A state of a body in the simulation.
  var self = this;

  // The position (m).
  self.x = x || new Vector([0, 0]);
  // The velocity (m s^-1).
  self.v = v || new Vector([0, 0]);
  // The acceleration (m s^-2).
  self.a = a || new Vector([0, 0]);
  // The mass (kg).
  self.m = m || 0;

  self.hash = function() {
    // Generate a hash of the state for use in caching.
    //
    // Returns:
    //  A hash of the state.
    return '[' + self.x.hash() + ',' + self.v.hash() + ',' + self.a.hash() + ',' + self.m + ']';
  };

  // A cache of get_force calculations.
  self._forces = {};
  self.get_force = function(other) {
    // Get the force on this state by another.
    //
    // This function is cached for each value of other.  In addition, this
    // function sets the cache on other to the opposite of the force on this
    // (every action has an equal and opposite reaction).
    //
    // Args:
    //  other: Another body instance.
    //
    // Returns:
    //  The gravitational force vector of other applied on this state.
    var r;
    var f;
    var hash;
    var other_hash = other.hash();

    if (self._forces[other_hash] === undefined) {
      hash = self.hash();
      r = other.x.subtract(self.x);
      f = r.unit().multiply(
        1 * G * self.m * other.m /
        Math.pow(r.magnitude(), 2)); // (kg m s^-2)

      self._forces[other_hash] = f;
      // Every action has an equal and opposite reaction.
      other._forces[hash] = f.multiply(-1)
    }
    return self._forces[other_hash];
  };
};

var Body = function() {
  // A planetary body.
  //
  // Args:
  //  state: The initial state of the body.
  var self = this;

  // A list of states.
  self.states = [];

  self.set_state = function(state) {
    // Set the state of the body.
    //
    // Args:
    //  state: A State instance.
    //
    // Returns:
    //  self
    if (self.states.length > 5)
      self.states = self.states.slice(
        self.states.length - 5,
        self.states.length);
    self.states.push(state);
    return self;
  };

  self.get_state = function() {
    // Get the current state of the body.
    //
    // Returns:
    //  The last State in the body's history.
    return self.states[self.states.length - 1];
  };
};

var Simulation = function() {
  // An N-body simulation.
  var self = this;

  // The bodies of the simulation.
  self.bodies = [];

  // The size of the simulation timestep (s).
  self.step_size = .5;

  self.add_body = function(body) {
    // Add a body to the simulation.
    //
    // Args:
    //  body: A Body instance.
    //
    // Returns:
    //  self
    self.bodies.push(body);
    return self;
  };

  self.step = function() {
    // Generate the next step in the simulation and apply it.
    //
    // TODO: Add a half-step velocity calculation.
    // TODO: Add collision detection.
    //
    // Returns:
    //  self
    var i, j;
    var a, f;
    var old_state, new_state;
    var new_xs = [];
    var new_states = [];

    // Create a list of new states for each body in self.bodies.  And
    //  calculate their new position.
    for (i = 0; i < self.bodies.length; i++) {
      old_state = self.bodies[i].get_state();
      new_state = new State();

      // Velocity verlet.
      // x = x + vt + .5at^2
      new_state.x = old_state.x
        .add(old_state.v.multiply(self.step_size))
        .add(old_state.a.multiply(.5 * Math.pow(self.step_size, 2)));
      new_state.m = old_state.m;

      // Initially create the state with just the new position.
      new_states.push(new_state);
    }

    // Calculate the new velocity from the states created above.
    // This looks like it is O(n^2).  However, because State.get_force is
    //  cached (and reverse-cached), it's actually O(n log(n)).
    for (i = 0; i < new_states.length; i++) {
      old_state = self.bodies[i].get_state();
      new_state = new_states[i];

      // Calculate an force vector as the sum of the gravity due to every other
      //  body in the simulation.
      f = new Vector([0, 0]);
      for (j = 0; j < new_states.length; j++) {
        if (i != j) {
          f = f.add(new_state.get_force(new_states[j]));
        }
      }
      a = f.divide(old_state.m);

      // Velocity verlet.
      new_state.a = a;
      // v = v + .5(old_a + a)t
      new_state.v = old_state.v
        .add(new_state.a
          .add(old_state.a)
          .multiply(.5 * self.step_size));
    }

    // Set the new states.
    for (i = 0; i < self.bodies.length; i++) {
      self.bodies[i].set_state(new_states[i]);
    }

    return self;
  };
};
<|endoftext|>


<commit_before>import URL from 'url'
import Path from 'path'

export class UrlGenerator {
	app = null
	defaultUrl = null

	constructor(app) {
		this.app = app

		let defaultUrl = null

		if(this.app.port === 443) {
			defaultUrl = 'https://localhost'
		} else if(this.app.port === 80) {
			defaultUrl = 'http://localhost'
		} else {
			defaultUrl = `http://localhost:${this.app.port}`
		}

		this.defaultUrl = URL.parse(app.config.get('app.url', defaultUrl))

		if(!this.defaultUrl.path.isNil && this.defaultUrl.path !== '' && this.defaultUrl.path !== '/') {
			throw new Error('`app.url` can not contain a path.')
		}
	}

	route(name, parameters, req, secure = null) {
		const route = this.app.routes.namedRoutes[name]

		if(route.isNil) {
			throw new Error(`Undefined route name: ${name}`)
		}

		if(!Array.isArray(parameters)) {
			parameters = [ parameters ]
		}

		const numberOfParameters = parameters.length
		let isObject = false

		if(numberOfParameters === 1 && typeof parameters[0] === 'object') {
			isObject = true
			parameters = parameters[0]
		}

		let index = 0
		const path = route.path.replace(/:([a-z0-0_\-\.]+)(?:\(([^\)]+)\))?(\?)?/g, (_, name) => {
			if(isObject) {
				const value = parameters[name] || ''
				delete parameters[name]
				return value
			}

			if(numberOfParameters < index) {
				return ''
			}

			return parameters[index++] || ''
		})

		if(!isObject) {
			parameters = null
		}

		return this.make({
			pathname: path,
			query: { }
		}, parameters, req, secure)
	}

	make(url, parameters, req, secure = null) {
		if(typeof url === 'string') {
			if(url.indexOf('://') >= 0) {
				return url
			}

			url = { pathname: url }
		}

		if(!parameters.isNil) {
			if(url.query.isNil) {
				url.query = parameters
			} else {
				url.query = Object.assign({ }, url.query, parameters)
			}
		}

		url.pathname = Path.normalize(url.pathname || '').replace(/\/+$/, '')
		url.protocol = this.getProtocol(req, secure)
		url.host = this.getHost(req)

		return URL.format(url)
	}

	getProtocol(req = null, secure = null) {
		if(secure === true) {
			return 'https:'
		} else if(secure === false) {
			return 'http:'
		}

		if(req.isNil) {
			return this.defaultUrl.protocol || 'http:'
		}

		if(req.secure) {
			return 'https:'
		}

		return 'http:'
	}

	getHost(req = null) {
		if(req.isNil) {
			return this.defaultUrl.host || 'localhost'
		}

		return req.get('Host')
	}

}
<commit_msg>Added UrlGenerator.clone()<commit_after>import URL from 'url'
import Path from 'path'

export class UrlGenerator {
	app = null
	req = null
	defaultUrl = null

	constructor(app, defaultUrl = null) {
		this.app = app

		if(defaultUrl.isNil) {
			let defaultUrl = null

			if(this.app.port === 443) {
				defaultUrl = 'https://localhost'
			} else if(this.app.port === 80) {
				defaultUrl = 'http://localhost'
			} else {
				defaultUrl = `http://localhost:${this.app.port}`
			}

			this.defaultUrl = URL.parse(app.config.get('app.url', defaultUrl))

			if(!this.defaultUrl.path.isNil && this.defaultUrl.path !== '' && this.defaultUrl.path !== '/') {
				throw new Error('`app.url` can not contain a path.')
			}
		} else {
			this.defaultUrl = defaultUrl
		}
	}

	/**
	 * Clone the instance to be used within a
	 * request cycle.
	 *
	 * @param object req
	 *
	 * @return object
	 */
	clone(req) {
		const cloned = new this.constructor(this.app, this.defaultUrl)
		cloned.req = req
		return cloned
	}

	/**
	 * Generate a URL for a route name and it’s parameters
	 *
	 * @param  {string} name Name of the route to generate
	 * @param  {Object|Array|string} parameters Parameter values for the route.
	 * @param  {Object|null} req Origin request to generate URL from, uses correct host/protocol
	 * @param  {boolean|null} secure Whether or not to force https, null uses default behavior
	 * @return {string}
	 */
	route(name, parameters, req, secure) {
		const route = this.app.routes.namedRoutes[name]

		if(route.isNil) {
			throw new Error(`Undefined route name: ${name}`)
		}

		if(!Array.isArray(parameters)) {
			parameters = [ parameters ]
		}

		const numberOfParameters = parameters.length
		let isObject = false

		if(numberOfParameters === 1 && typeof parameters[0] === 'object') {
			isObject = true
			parameters = parameters[0]
		}

		let index = 0
		const path = route.path.replace(/:([a-z0-0_\-\.]+)(?:\(([^\)]+)\))?(\?)?/g, (_, name) => {
			if(isObject) {
				const value = parameters[name] || ''
				delete parameters[name]
				return value
			}

			if(numberOfParameters < index) {
				return ''
			}

			return parameters[index++] || ''
		})

		if(!isObject) {
			parameters = null
		}

		return this.make({
			pathname: path,
			query: { }
		}, parameters, req, secure)
	}

	/**
	 * Generate a URL
	 *
	 * @param  {string} url URL/Path to generate
	 * @param  {Object|Array|string} parameters Query string parameters
	 * @param  {Object|null} req Origin request to generate URL from, uses correct host/protocol
	 * @param  {boolean|null} secure Whether or not to force https, null uses default behavior
	 * @return {string}
	 */
	make(url, parameters, req, secure = null) {
		if(req === true || req === false) {
			secure = req
			req = null
		}

		if(req.isNil) {
			req = this.req
		}

		if(typeof url === 'string') {
			if(url.indexOf('://') >= 0) {
				return url
			}

			url = { pathname: url }
		}

		if(!parameters.isNil) {
			if(url.query.isNil) {
				url.query = parameters
			} else {
				url.query = Object.assign({ }, url.query, parameters)
			}
		}

		url.pathname = Path.normalize(url.pathname || '').replace(/\/+$/, '')
		url.protocol = this.getProtocol(req, secure)
		url.host = this.getHost(req)

		return URL.format(url)
	}

	getProtocol(req = null, secure = null) {
		if(secure === true) {
			return 'https:'
		} else if(secure === false) {
			return 'http:'
		}

		if(req.isNil) {
			return this.defaultUrl.protocol || 'http:'
		}

		if(req.secure) {
			return 'https:'
		}

		return 'http:'
	}

	getHost(req = null) {
		if(req.isNil) {
			return this.defaultUrl.host || 'localhost'
		}

		return req.get('Host')
	}

}
<|endoftext|>


<commit_before>/*!
 * jQuery-Img-Preload - 16th Out 2015
 * https://github.com/miamarti/jquery-img-preload
 *
 * Licensed under the MIT license.
 * http://opensource.org/licenses/MIT
 */
$.imgPreload=function(b,a,h){var c=0,d=0,e=new Function;"function"===typeof a&&(e=a,a=h);a=$.extend({},{attribute:"url"},a);for(var f in b)c++;for(f in b)$($("<img />").attr("src",b[f][a.attribute])).load(function(){d++});var g=function(){c===d?e():setTimeout(g,10)};g()};
<commit_msg>Update img-preload.min.js<commit_after>/*!
 * jQuery-Img-Preload - 16th Out 2015
 * https://github.com/miamarti/jquery-img-preload
 *
 * Licensed under the MIT license.
 * http://opensource.org/licenses/MIT
 */
 $.imgPreload=function(b,a,h){var d=0,e=0,f=new Function;"function"===typeof a&&(f=a,a=h);a=$.extend({},{attribute:"url"},a);for(var c in b)d++;for(c in b)(new Image).src=b[c][a.attribute],$($("<img />").attr("src",b[c][a.attribute])).load(function(){e++});var g=function(){d===e?f():setTimeout(g,10)};g()};
<|endoftext|>


<commit_before>if(!TASK_CONFIG.javascripts) return

var path            = require('path')
var pathToUrl       = require('./pathToUrl')
var webpack         = require('webpack')
var webpackManifest = require('./webpackManifest')

module.exports = function(env) {
  var jsSrc = path.resolve(process.env.PWD, PATH_CONFIG.src, PATH_CONFIG.assets.javascripts.src)
  var jsDest = path.resolve(process.env.PWD, PATH_CONFIG.dest, PATH_CONFIG.assets.javascripts.dest)
  var publicPath = pathToUrl(TASK_CONFIG.javascripts.publicPath || PATH_CONFIG.assets.javascripts.dest, '/')

  var extensions = TASK_CONFIG.javascripts.extensions.map(function(extension) {
    return '.' + extension
  })

  var rev = TASK_CONFIG.production.rev && env === 'production'
  var filenamePattern = rev ? '[name]-[hash].js' : '[name].js'

  // TODO: To work in < node 6, prepend process.env.PWD + node_modules/babel-preset- to each
  var defaultBabelConfig = {
    presets: ['es2015', 'stage-1']
  }

  var webpackConfig = {
    context: jsSrc,
    output: {},
    plugins: [],
    resolve: {
      root: jsSrc,
      extensions: [''].concat(extensions)
    },
    module: {
      loaders: [
        {
          test: /\.js$/,
          loader: 'babel-loader',
          exclude: /node_modules/,
          query: TASK_CONFIG.javascripts.babel || defaultBabelConfig
        }
      ]
    }
  }

  if(env === 'development') {
    webpackConfig.devtool = TASK_CONFIG.javascripts.devtool || 'eval-cheap-module-source-map'
    webpackConfig.output.pathinfo = true
    // Create new entries object with webpack-hot-middleware added
    for (var key in TASK_CONFIG.javascripts.entries) {
      var entry = TASK_CONFIG.javascripts.entries[key]
      // TODO: To work in < node 6, prepend process.env.PWD + node_modules/
      TASK_CONFIG.javascripts.entries[key] = ['webpack-hot-middleware/client?&reload=true'].concat(entry)
    }

    webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin())
  }

  if(env !== 'test') {
    // Karma doesn't need entry points or output settings
    webpackConfig.entry = TASK_CONFIG.javascripts.entries

    webpackConfig.output.path = path.normalize(jsDest),
    webpackConfig.output.filename = filenamePattern,
    webpackConfig.output.publicPath = publicPath

    if(TASK_CONFIG.javascripts.extractSharedJs) {
      // Factor out common dependencies into a shared.js
      webpackConfig.plugins.push(
        new webpack.optimize.CommonsChunkPlugin({
          name: 'shared',
          filename: filenamePattern,
        })
      )
    }
  }

  if(env === 'production') {
    if(rev) {
      webpackConfig.plugins.push(new webpackManifest(PATH_CONFIG.assets.javascripts.dest, PATH_CONFIG.dest))
    }
    webpackConfig.plugins.push(
      new webpack.DefinePlugin({
        'process.env': {
          'NODE_ENV': JSON.stringify('production')
        }
      }),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin(),
      new webpack.NoErrorsPlugin()
    )
  }

  return webpackConfig
}
<commit_msg>Support adding webpack loaders through task config.<commit_after>if(!TASK_CONFIG.javascripts) return

var path            = require('path')
var pathToUrl       = require('./pathToUrl')
var webpack         = require('webpack')
var webpackManifest = require('./webpackManifest')

module.exports = function(env) {
  var jsSrc = path.resolve(process.env.PWD, PATH_CONFIG.src, PATH_CONFIG.assets.javascripts.src)
  var jsDest = path.resolve(process.env.PWD, PATH_CONFIG.dest, PATH_CONFIG.assets.javascripts.dest)
  var publicPath = pathToUrl(TASK_CONFIG.javascripts.publicPath || PATH_CONFIG.assets.javascripts.dest, '/')

  var extensions = TASK_CONFIG.javascripts.extensions.map(function(extension) {
    return '.' + extension
  })

  var rev = TASK_CONFIG.production.rev && env === 'production'
  var filenamePattern = rev ? '[name]-[hash].js' : '[name].js'

  // TODO: To work in < node 6, prepend process.env.PWD + node_modules/babel-preset- to each
  var defaultBabelConfig = {
    presets: ['es2015', 'stage-1']
  }

  var webpackConfig = {
    context: jsSrc,
    output: {},
    plugins: [],
    resolve: {
      root: jsSrc,
      extensions: [''].concat(extensions)
    },
    module: {
      loaders: [
        {
          test: /\.js$/,
          loader: 'babel-loader',
          exclude: /node_modules/,
          query: TASK_CONFIG.javascripts.babel || defaultBabelConfig
        }
      ]
    }
  }

  // Add additional loaders from config
  webpackConfig.module.loaders = webpackConfig.module.loaders.concat(TASK_CONFIG.javascripts.loaders || [])

  if(env === 'development') {
    webpackConfig.devtool = TASK_CONFIG.javascripts.devtool || 'eval-cheap-module-source-map'
    webpackConfig.output.pathinfo = true
    // Create new entries object with webpack-hot-middleware added
    for (var key in TASK_CONFIG.javascripts.entries) {
      var entry = TASK_CONFIG.javascripts.entries[key]
      // TODO: To work in < node 6, prepend process.env.PWD + node_modules/
      TASK_CONFIG.javascripts.entries[key] = ['webpack-hot-middleware/client?&reload=true'].concat(entry)
    }

    webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin())
  }

  if(env !== 'test') {
    // Karma doesn't need entry points or output settings
    webpackConfig.entry = TASK_CONFIG.javascripts.entries

    webpackConfig.output.path = path.normalize(jsDest),
    webpackConfig.output.filename = filenamePattern,
    webpackConfig.output.publicPath = publicPath

    if(TASK_CONFIG.javascripts.extractSharedJs) {
      // Factor out common dependencies into a shared.js
      webpackConfig.plugins.push(
        new webpack.optimize.CommonsChunkPlugin({
          name: 'shared',
          filename: filenamePattern,
        })
      )
    }
  }

  if(env === 'production') {
    if(rev) {
      webpackConfig.plugins.push(new webpackManifest(PATH_CONFIG.assets.javascripts.dest, PATH_CONFIG.dest))
    }
    webpackConfig.plugins.push(
      new webpack.DefinePlugin({
        'process.env': {
          'NODE_ENV': JSON.stringify('production')
        }
      }),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.UglifyJsPlugin(),
      new webpack.NoErrorsPlugin()
    )
  }

  return webpackConfig
}
<|endoftext|>


<commit_before>module.exports = {
    "parser": "babel-eslint",
    "env": {
        "browser": true,
        "es6": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        // "plugin:import/errors",
        // "plugin:import/warnings"
    ],
    "parserOptions": {
        "ecmaVersion": 9,
        "ecmaFeatures": {
            "jsx": true
        },
        "sourceType": "module"
    },
    "plugins": [
        "react",
        // "import",
        "sort-imports-es6-autofix"
    ],
    "settings": {
        "react": {
            "version": "16.4"
        }
    },
    "rules": {
        "indent": [
            "error",
            4
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "never"
        ],
        "comma-spacing": [
            "error", {
                "before": false,
                "after": true
            }
        ],
        "no-multiple-empty-lines": [
            "error", {
                "max": 1,
                "maxBOF": 0,
                "maxEOF": 1
            }
        ],
        "no-trailing-spaces": [
            "error", {
                "skipBlankLines": true,
                "ignoreComments": false
            }
        ],
        "no-unused-vars": [
            "error", {
                "argsIgnorePattern": "^_"
            }
        ],
        "object-curly-spacing": [
            "error",
            "never"
        ],
        "eol-last": [
            "error",
            "always"
        ],
        "react/jsx-tag-spacing": [
            "error", {
                "closingSlash": "never",
                "beforeSelfClosing": "never",
                "afterOpening": "never",
                "beforeClosing": "allow"
            }
        ],
        "react/prop-types": 0,
        "react/sort-prop-types": [
            "error", {
                "ignoreCase": true,
                "callbacksLast": true,
                "requiredFirst": true,
                "sortShapeProp": true,
                "noSortAlphabetically": false
            }
        ],
        // "import/no-unresolved": 0,
        // "import/named": 0,
        // "import/namespace": 0,
        // "import/default": 0,
        // "import/export": 0,
        "sort-imports-es6-autofix/sort-imports-es6": ["error", {
            "ignoreCase": false,
            "ignoreMemberSort": false,
            "memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
        }]
    }
};
<commit_msg>Added eslint rule for allowing unused variables (_<variable name>).<commit_after>module.exports = {
    "parser": "babel-eslint",
    "env": {
        "browser": true,
        "es6": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        // "plugin:import/errors",
        // "plugin:import/warnings"
    ],
    "parserOptions": {
        "ecmaVersion": 9,
        "ecmaFeatures": {
            "jsx": true
        },
        "sourceType": "module"
    },
    "plugins": [
        "react",
        // "import",
        "sort-imports-es6-autofix"
    ],
    "settings": {
        "react": {
            "version": "16.4"
        }
    },
    "rules": {
        "indent": [
            "error",
            4
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "never"
        ],
        "comma-spacing": [
            "error", {
                "before": false,
                "after": true
            }
        ],
        "no-multiple-empty-lines": [
            "error", {
                "max": 1,
                "maxBOF": 0,
                "maxEOF": 1
            }
        ],
        "no-trailing-spaces": [
            "error", {
                "skipBlankLines": true,
                "ignoreComments": false
            }
        ],
        "no-unused-vars": [
            "error", {
                "argsIgnorePattern": "^_",
                "varsIgnorePattern": "^_"
            }
        ],
        "object-curly-spacing": [
            "error",
            "never"
        ],
        "eol-last": [
            "error",
            "always"
        ],
        "react/jsx-tag-spacing": [
            "error", {
                "closingSlash": "never",
                "beforeSelfClosing": "never",
                "afterOpening": "never",
                "beforeClosing": "allow"
            }
        ],
        "react/prop-types": 0,
        "react/sort-prop-types": [
            "error", {
                "ignoreCase": true,
                "callbacksLast": true,
                "requiredFirst": true,
                "sortShapeProp": true,
                "noSortAlphabetically": false
            }
        ],
        // "import/no-unresolved": 0,
        // "import/named": 0,
        // "import/namespace": 0,
        // "import/default": 0,
        // "import/export": 0,
        "sort-imports-es6-autofix/sort-imports-es6": ["error", {
            "ignoreCase": false,
            "ignoreMemberSort": false,
            "memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
        }]
    }
};
<|endoftext|>


<commit_before>var lastJump = {
    chargeLevel: 0,
    jumpCoefficient: 0,
    initalSpeed: 0,
};

var lastGeneratedObstacle = {
    generatedAt: null,
    lastMinimum: null,
    lastName: null
};

var onJumpDebug = function(chargeLevel, jumpCoefficient, initalSpeed) {
    lastJump = {
        chargeLevel: chargeLevel,
        jumpCoefficient: jumpCoefficient,
        initalSpeed: initalSpeed
    };
};

var onObstacleAddedDebug = function(newX, lastObstacle) {
    lastGeneratedObstacle = {
        generatedAt: newX,
        lastMinimum: lastObstacle ? lastObstacle.minimumSpaceBehind : 0,
        lastName: lastObstacle ? lastObstacle.name : null
    };
};

var setupDebugging = function() {
    objects.runner.onJump.add(onJumpDebug);
    obstacleGenerator.onObstacleAdded.add(onObstacleAddedDebug);
};

var drawDebugText = function(shouldDraw) {
    if (shouldDraw) {
        var row = 1;
        var rowHeight = 16;
        game.debug.text("world " + game.world.height + "h x " + game.world.width + "w", 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("player height: " + (constants.groundHeight - objects.runner.findLowestPoint()), 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("player vspeed: " + objects.runner.vspeed, 0, row++ * rowHeight, colorPalette.debugColor);
        row++;
        game.debug.text("last distance between: " + (lastGeneratedObstacle.generatedAt - game.world.width), 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("minimum distance behind: " + lastGeneratedObstacle.lastMinimum + "(" + lastGeneratedObstacle.lastName + ")", 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("distance from score: " + calculateDifficultyModifier(game.score), 0, row++ * rowHeight, colorPalette.debugColor);
        var obstacles = objects.obstacles ? objects.obstacles.length : 0;
        game.debug.text("obstacles in memory: " + obstacles, 0, row++ * rowHeight, colorPalette.debugColor);
        row++;
        game.debug.text("Last Jump ", 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("Charge Level " + lastJump.chargeLevel, 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("Charge Coefficient " + lastJump.jumpCoefficient, 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("JumpStrength " + lastJump.initalSpeed, 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.pointer(game.input.activePointer, false, 'rgba(0,255,0,0.5)', 'rgba(255,0,0,0.5)', colorPalette.debugColor);
    }
};
<commit_msg>tech - adding FPS to debug so I can look at performance stuff<commit_after>var lastJump = {
    chargeLevel: 0,
    jumpCoefficient: 0,
    initalSpeed: 0,
};

var lastGeneratedObstacle = {
    generatedAt: null,
    lastMinimum: null,
    lastName: null
};

var onJumpDebug = function(chargeLevel, jumpCoefficient, initalSpeed) {
    lastJump = {
        chargeLevel: chargeLevel,
        jumpCoefficient: jumpCoefficient,
        initalSpeed: initalSpeed
    };
};

var onObstacleAddedDebug = function(newX, lastObstacle) {
    lastGeneratedObstacle = {
        generatedAt: newX,
        lastMinimum: lastObstacle ? lastObstacle.minimumSpaceBehind : 0,
        lastName: lastObstacle ? lastObstacle.name : null
    };
};

var setupDebugging = function() {
    objects.runner.onJump.add(onJumpDebug);
    obstacleGenerator.onObstacleAdded.add(onObstacleAddedDebug);
};

var drawDebugText = function(shouldDraw) {
    if (shouldDraw) {
        game.time.advancedTiming = true;
        var row = 1;
        var rowHeight = 16;
        game.debug.text("FPS " + game.time.fps + " (" + game.time.fpsMax + ")", 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("world " + game.world.height + "h x " + game.world.width + "w", 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("player height: " + (constants.groundHeight - objects.runner.findLowestPoint()), 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("player vspeed: " + objects.runner.vspeed, 0, row++ * rowHeight, colorPalette.debugColor);
        row++;
        game.debug.text("last distance between: " + (lastGeneratedObstacle.generatedAt - game.world.width), 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("minimum distance behind: " + lastGeneratedObstacle.lastMinimum + "(" + lastGeneratedObstacle.lastName + ")", 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("distance from score: " + calculateDifficultyModifier(game.score), 0, row++ * rowHeight, colorPalette.debugColor);
        var obstacles = objects.obstacles ? objects.obstacles.length : 0;
        game.debug.text("obstacles in memory: " + obstacles, 0, row++ * rowHeight, colorPalette.debugColor);
        row++;
        game.debug.text("Last Jump ", 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("Charge Level " + lastJump.chargeLevel, 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("Charge Coefficient " + lastJump.jumpCoefficient, 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.text("JumpStrength " + lastJump.initalSpeed, 0, row++ * rowHeight, colorPalette.debugColor);
        game.debug.pointer(game.input.activePointer, false, 'rgba(0,255,0,0.5)', 'rgba(255,0,0,0.5)', colorPalette.debugColor);
    } else {
      game.time.advancedTiming = false;
    }
};
<|endoftext|>


<commit_before>exports.up = function(knex, Promise) {
  return knex.schema.createTableIfNotExists('games_users', function(table){
    table.increments('id').primary();
    table.integer('user_id').references('users.user_id');
    table.string('game_hash').references('games.game_hash');
    table.boolean('favorites').defaultTo(false);
  })
  .then(function(){
    return knex.schema.createTableIfNotExists('games_users', function(table){
        table.increments('id').primary();
        table.integer('user_id').references('users.user_id');
        table.string('game_hash').references('games.game_hash');
        table.boolean('favorites').defaultTo(false);;
    })
  });
};

exports.down = function(knex, Promise) {
  return knex.schema.dropTable('games_users');
};<commit_msg>Migrations 5<commit_after>exports.up = function(knex, Promise) {
  return knex.schema.createTableIfNotExists('games_users', function(table){
    table.increments('id').primary();
    table.integer('user_id').references('users.user_id');
    table.string('game_hash').references('games.game_hash');
    table.boolean('favorites').defaultTo(false);
  })
  .then(function(){
    return;
  });
};

exports.down = function(knex, Promise) {
  return knex.schema.dropTable('games_users');
};<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var TrackingLink = function (_Component) {
  _inherits(TrackingLink, _Component);

  /* istanbul ignore next */
  function TrackingLink(props) {
    _classCallCheck(this, TrackingLink);

    var _this = _possibleConstructorReturn(this, (TrackingLink.__proto__ || Object.getPrototypeOf(TrackingLink)).call(this, props));

    _this.linkEl = null;
    _this.longTouchTimer = 0;

    _this.state = {
      preventTouchTap: false
    };

    _this.addEvents = _this.addEvents.bind(_this);
    _this.removeEvents = _this.removeEvents.bind(_this);
    _this.onContextMenu = _this.onContextMenu.bind(_this);
    _this.onTouchStart = _this.onTouchStart.bind(_this);
    _this.onTouchEnd = _this.onTouchEnd.bind(_this);
    _this.onLongTouch = _this.onLongTouch.bind(_this);
    _this.onTouchTap = _this.onTouchTap.bind(_this);
    _this.navigateToUrl = _this.navigateToUrl.bind(_this);
    _this.preventDefault = _this.preventDefault.bind(_this);
    _this.resolveByTimeout = _this.resolveByTimeout.bind(_this);
    return _this;
  }

  _createClass(TrackingLink, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      this.addEvents();
    }
  }, {
    key: 'componentWillUnmount',
    value: function componentWillUnmount() {
      this.removeEvents();
    }

    /**
     * In mobile Chrome and desktop Firefox opening context menu upon a link also triggers touchTap
     * That's why we must prevent touchTap for some small period of time
     */

  }, {
    key: 'onContextMenu',
    value: function onContextMenu() {
      var _this2 = this;

      this.setState({ preventTouchTap: true });

      global.setTimeout(function () {
        _this2.setState({ preventTouchTap: false });
      }, this.props.contextMenuTimeout);
    }
  }, {
    key: 'onLongTouch',
    value: function onLongTouch() {
      this.setState({ preventTouchTap: true });
    }
  }, {
    key: 'onTouchStart',
    value: function onTouchStart() {
      this.longTouchTimer = global.setTimeout(this.onLongTouch, 1000);
    }
  }, {
    key: 'onTouchEnd',
    value: function onTouchEnd() {
      var _this3 = this;

      global.window.clearTimeout(this.longTouchTimer);

      if (this.state.preventTouchTap) {
        global.setTimeout(function () {
          _this3.setState({ preventTouchTap: false });
        }, this.props.contextMenuTimeout);
      }
    }
  }, {
    key: 'onTouchTap',
    value: function onTouchTap(ev) {
      var event = ev.nativeEvent;

      if (this.state.preventTouchTap) {
        return false;
      }

      var _props = this.props,
          trackingFunction = _props.onTouchTap,
          trackingTimeout = _props.trackingTimeout;

      // try to track the click but with the timeout
      // in case of tracking-blocking browser extensions or failure to load analytics scripts

      return Promise.race([trackingFunction(), this.resolveByTimeout(trackingTimeout)]).then(this.navigateToUrl(event));
    }
  }, {
    key: 'addEvents',
    value: function addEvents() {
      global.window.addEventListener('contextmenu', this.onContextMenu);
      this.linkEl.addEventListener('touchstart', this.onTouchStart);
      this.linkEl.addEventListener('touchend', this.onTouchEnd);
    }
  }, {
    key: 'removeEvents',
    value: function removeEvents() {
      global.window.removeEventListener('contextmenu', this.onContextMenu);
      this.linkEl.removeEventListener('touchstart', this.onTouchStart);
      this.linkEl.removeEventListener('touchend', this.onTouchEnd);
    }
  }, {
    key: 'navigateToUrl',
    value: function navigateToUrl(event) {
      var _this4 = this;

      return function () {
        var _props2 = _this4.props,
            href = _props2.href,
            targetBlank = _props2.targetBlank,
            preventDefault = _props2.preventDefault;

        var ctrlKeyPressed = event.metaKey || event.ctrlKey;

        if (href && !preventDefault) {
          if (targetBlank || ctrlKeyPressed) {
            global.window.open(href, '_blank');
          } else {
            global.location.href = href;
          }
        }
      };
    }
  }, {
    key: 'preventDefault',
    value: function preventDefault(event) {
      event.preventDefault();
    }
  }, {
    key: 'resolveByTimeout',
    value: function resolveByTimeout(timeout) {
      return new Promise(function (resolve) {
        global.setTimeout(resolve, timeout);
      });
    }
  }, {
    key: 'render',
    value: function render() {
      var _this5 = this;

      var _props3 = this.props,
          children = _props3.children,
          href = _props3.href,
          addtionalClassName = _props3.className,
          trackingFunction = _props3.onTouchTap;

      var className = (0, _classnames2.default)('TrackingLink', _defineProperty({}, addtionalClassName, !!addtionalClassName));
      var onTouchTap = trackingFunction ? this.onTouchTap : undefined;

      return _react2.default.createElement(
        'a',
        {
          className: className,
          href: href,
          onTouchTap: onTouchTap,
          onClick: this.preventDefault,
          ref: function ref(linkEl) {
            _this5.linkEl = linkEl;
          }
        },
        children
      );
    }
  }]);

  return TrackingLink;
}(_react.Component);

TrackingLink.propTypes = {
  children: _propTypes2.default.node.isRequired,
  href: _propTypes2.default.string.isRequired,
  className: _propTypes2.default.string,
  onTouchTap: _propTypes2.default.func,
  targetBlank: _propTypes2.default.bool,
  preventDefault: _propTypes2.default.bool,
  trackingTimeout: _propTypes2.default.number,
  contextMenuTimeout: _propTypes2.default.number
};
TrackingLink.defaultProps = {
  trackingTimeout: 500, // ms
  contextMenuTimeout: 300 // ms
};
exports.default = TrackingLink;<commit_msg>Build files for version 2.1.0;<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.MOUSE_RIGHT_BUTTON = undefined;

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var MOUSE_RIGHT_BUTTON = exports.MOUSE_RIGHT_BUTTON = 2;

var TrackingLink = function (_Component) {
  _inherits(TrackingLink, _Component);

  /* istanbul ignore next */
  function TrackingLink(props) {
    _classCallCheck(this, TrackingLink);

    var _this = _possibleConstructorReturn(this, (TrackingLink.__proto__ || Object.getPrototypeOf(TrackingLink)).call(this, props));

    _this.linkEl = null;
    _this.longTouchTimer = 0;

    _this.state = {
      preventTouchTap: false
    };

    _this.addEvents = _this.addEvents.bind(_this);
    _this.removeEvents = _this.removeEvents.bind(_this);
    _this.onContextMenu = _this.onContextMenu.bind(_this);
    _this.onTouchStart = _this.onTouchStart.bind(_this);
    _this.onTouchEnd = _this.onTouchEnd.bind(_this);
    _this.onLongTouch = _this.onLongTouch.bind(_this);
    _this.onTouchTap = _this.onTouchTap.bind(_this);
    _this.navigateToUrl = _this.navigateToUrl.bind(_this);
    _this.preventDefault = _this.preventDefault.bind(_this);
    _this.resolveByTimeout = _this.resolveByTimeout.bind(_this);
    return _this;
  }

  _createClass(TrackingLink, [{
    key: 'componentDidMount',
    value: function componentDidMount() {
      this.addEvents();
    }
  }, {
    key: 'componentWillUnmount',
    value: function componentWillUnmount() {
      this.removeEvents();
    }

    /**
     * In mobile Chrome and desktop Firefox opening context menu upon a link also triggers touchTap
     * That's why we must prevent touchTap for some small period of time
     */

  }, {
    key: 'onContextMenu',
    value: function onContextMenu() {
      var _this2 = this;

      this.setState({ preventTouchTap: true });

      global.setTimeout(function () {
        _this2.setState({ preventTouchTap: false });
      }, this.props.contextMenuTimeout);
    }
  }, {
    key: 'onLongTouch',
    value: function onLongTouch() {
      this.setState({ preventTouchTap: true });
    }
  }, {
    key: 'onTouchStart',
    value: function onTouchStart() {
      this.longTouchTimer = global.setTimeout(this.onLongTouch, 1000);
    }
  }, {
    key: 'onTouchEnd',
    value: function onTouchEnd() {
      var _this3 = this;

      global.window.clearTimeout(this.longTouchTimer);

      if (this.state.preventTouchTap) {
        global.setTimeout(function () {
          _this3.setState({ preventTouchTap: false });
        }, this.props.contextMenuTimeout);
      }
    }
  }, {
    key: 'onTouchTap',
    value: function onTouchTap(ev) {
      var event = ev.nativeEvent;

      if (this.state.preventTouchTap) {
        return false;
      }

      // on Windows right click triggers touchTap event (react-tap-event-plugin bug)
      if (event.button === MOUSE_RIGHT_BUTTON) {
        return false;
      }

      var _props = this.props,
          trackingFunction = _props.onTouchTap,
          trackingTimeout = _props.trackingTimeout;

      // try to track the click but with the timeout
      // in case of tracking-blocking browser extensions or failure to load analytics scripts

      return Promise.race([trackingFunction(), this.resolveByTimeout(trackingTimeout)]).then(this.navigateToUrl(event));
    }
  }, {
    key: 'addEvents',
    value: function addEvents() {
      global.window.addEventListener('contextmenu', this.onContextMenu);
      this.linkEl.addEventListener('touchstart', this.onTouchStart);
      this.linkEl.addEventListener('touchend', this.onTouchEnd);
    }
  }, {
    key: 'removeEvents',
    value: function removeEvents() {
      global.window.removeEventListener('contextmenu', this.onContextMenu);
      this.linkEl.removeEventListener('touchstart', this.onTouchStart);
      this.linkEl.removeEventListener('touchend', this.onTouchEnd);
    }
  }, {
    key: 'navigateToUrl',
    value: function navigateToUrl(event) {
      var _this4 = this;

      return function () {
        var _props2 = _this4.props,
            href = _props2.href,
            targetBlank = _props2.targetBlank,
            preventDefault = _props2.preventDefault;

        var ctrlKeyPressed = event.metaKey || event.ctrlKey;

        if (href && !preventDefault) {
          if (targetBlank || ctrlKeyPressed) {
            global.window.open(href, '_blank');
          } else {
            global.location.href = href;
          }
        }
      };
    }
  }, {
    key: 'preventDefault',
    value: function preventDefault(event) {
      event.preventDefault();
    }
  }, {
    key: 'resolveByTimeout',
    value: function resolveByTimeout(timeout) {
      return new Promise(function (resolve) {
        global.setTimeout(resolve, timeout);
      });
    }
  }, {
    key: 'render',
    value: function render() {
      var _this5 = this;

      var _props3 = this.props,
          children = _props3.children,
          href = _props3.href,
          addtionalClassName = _props3.className,
          trackingFunction = _props3.onTouchTap;

      var className = (0, _classnames2.default)('TrackingLink', _defineProperty({}, addtionalClassName, !!addtionalClassName));
      var onTouchTap = trackingFunction ? this.onTouchTap : undefined;

      return _react2.default.createElement(
        'a',
        {
          className: className,
          href: href,
          onTouchTap: onTouchTap,
          onClick: this.preventDefault,
          ref: function ref(linkEl) {
            _this5.linkEl = linkEl;
          }
        },
        children
      );
    }
  }]);

  return TrackingLink;
}(_react.Component);

TrackingLink.propTypes = {
  children: _propTypes2.default.node.isRequired,
  href: _propTypes2.default.string.isRequired,
  className: _propTypes2.default.string,
  onTouchTap: _propTypes2.default.func,
  targetBlank: _propTypes2.default.bool,
  preventDefault: _propTypes2.default.bool,
  trackingTimeout: _propTypes2.default.number,
  contextMenuTimeout: _propTypes2.default.number
};
TrackingLink.defaultProps = {
  trackingTimeout: 500, // ms
  contextMenuTimeout: 300 // ms
};
exports.default = TrackingLink;<|endoftext|>


<commit_before>let gulp = require('gulp')
let path = require('path')
let tap = require('gulp-tap')
let fs = require('fs')
let jsx2wxml = require('./jsx2wxml')

function buildComponent(code) {
  return `
class WeElement {
  render () {
    return ${code}
  }
}
`
}

const baseOptions = {
  isRoot: false,
  isApp: false,
  sourcePath: __dirname,
  outputPath: __dirname,
  code: '',
  isTyped: false
}

gulp.task('watch', () => {
  gulp.watch('src-mp/**/*', () => {
    gulp.start('copyThen')
  })
})

//加 cache？同样的字符串返回同样的结果
gulp.task('cp', () => {
  return gulp
    .src('../**/*.jsx')
    .pipe(
      tap(file => {

        let dir = path.dirname(file.path)

        let template = jsx2wxml.default({
          ...baseOptions,
          code: buildComponent(file.contents.toString())
        }).template

        file.contents = new Buffer(template)
        console.log(file.contents.toString())
      })
    )
    .pipe(gulp.dest('build'))
})

gulp.task('default', ['cp'])

gulp.start('default')
<commit_msg>update gulp task<commit_after>let gulp = require('gulp')
let path = require('path')
let tap = require('gulp-tap')
let fs = require('fs')
let jsx2wxml = require('./jsx2wxml')

function buildComponent(code) {
  return `
class WeElement {
  render () {
    return ${code}
  }
}
`
}

const baseOptions = {
  isRoot: false,
  isApp: false,
  sourcePath: __dirname,
  outputPath: __dirname,
  code: '',
  isTyped: false
}

gulp.task('watch', () => {
  gulp.watch('src-mp/**/*', () => {
    gulp.start('copyThen')
  })
})

//加 cache？同样的字符串返回同样的结果
gulp.task('cp', () => {
  return gulp
    .src('../**/*.jsx')
    .pipe(
      tap(file => {

        let dir = path.dirname(file.path)
        let arr = dir.split(/\\|\//)
        let name = arr[arr.length - 1]
        let template = jsx2wxml.default({
          ...baseOptions,
          code: buildComponent(file.contents.toString())
        }).template

        file.contents = new Buffer(template)
        console.log('编译' + file.path)

        fs.writeFileSync(dir + '/' + name + '.wxml', file.contents.toString())
      })
    )

})

gulp.task('default', ['cp'])

gulp.start('default')
<|endoftext|>


<commit_before>var ut4waApp = angular.module('ut4waApp', [])
  .controller('GameInfoController', function($scope, $http) {

	var url = "/gameinfo";
	url = "/js/gameinfo-test.json";

	$scope.toMinutesSec = function(seconds){
		return new Date(seconds * 1000).toISOString().substr(14, 5);
	};

	$http.get(url).then(function(response) {
		console.log(response);
        $scope.lobbyInfo = response.data.LobbyInfo;
		$scope.hasMatches = ($scope.lobbyInfo.NumMatches > 0);
    }, function(response) {
        //Second function handles error
        $scope.content = "Something went wrong";
    });
  });

 /*
ut4waApp.directive('GameInstance', function () {
    return {
        restrict : 'E',
        replace : true,
        scope : {
			instance : '@instance'
		},
        template : '
Some instance
'
    }
});*/<commit_msg>commented json url test<commit_after>var ut4waApp = angular.module('ut4waApp', [])
  .controller('GameInfoController', function($scope, $http) {

	var url = "/gameinfo";
	//url = "/js/gameinfo-test.json";

	$scope.toMinutesSec = function(seconds){
		return new Date(seconds * 1000).toISOString().substr(14, 5);
	};

	$http.get(url).then(function(response) {
		console.log(response);
        $scope.lobbyInfo = response.data.LobbyInfo;
		$scope.hasMatches = ($scope.lobbyInfo.NumMatches > 0);
    }, function(response) {
        //Second function handles error
        $scope.content = "Something went wrong";
    });
  });

 /*
ut4waApp.directive('GameInstance', function () {
    return {
        restrict : 'E',
        replace : true,
        scope : {
			instance : '@instance'
		},
        template : '
Some instance
'
    }
});*/<|endoftext|>