<commit_before>define([
        "./var/appMessenger"
],function(appMessenger) {

    /**
     * @constructor
     */
    function NumberPad() {
        this.$numpad = $(".numpad");
        var buff = [];
        var that = this;

        document.ontouchmove = function(e){e.preventDefault();};

        /**
         * @public
         * clear buffer
         */
        this.clear = function() {
            while (buff.length) buff.pop();
            return this;
        };

        /**
         * click event handler
         * @callback
         */
        function clickHandler(event) {
            var button = event.target;
            var content = button.innerHTML;
            // only capture number elements
            if (!$(button).hasClass("number")) { return null; }
            // If you clicked enter, then call onenter, clear the buffer, and return.
            if ($(button).hasClass("operator")) {
                _onenter(event);
                return null;
            }
            if ($(button).hasClass("clr")) {
                _onclear(event);
                return null;
            }
            else {
                buff.push(content);
                that.onclick(buff.join(""), buff);
            }
        }

        /**
         * onenter callback
         * @callback
         * @private
         */
        function _onenter(event) {
            that.onenter(buff.join(""), buff);
            that.hide();
            that.clear();
            return null;
        }

        /**
         * clear the buffer callback
         * @callback
         */
        function _onclear(event) {
            that.clear();
            that.onclear(buff.join(""), buff);
            return null;
        }

        /**
         * handle any dragging of the number pad
         * @callback
         */
        function dragHandler(event) {
            event.preventDefault();
            event.stopPropagation();
            var cx, cy, x0, y0, x, y;
            if ($(event.target).hasClass("number")) { return null; }
            switch (event.type) {
                case "touchstart":
                    cx = event.touches[0].clientX;
                    cy = event.touches[0].clientY;
                    x0 = that.$numpad.offset().left;
                    y0 = that.$numpad.offset().top;
                    document.addEventListener("touchmove", drag);
                    document.addEventListener("touchend", function() {
                        document.removeEventListener("touchmove", drag);
                        endDrag();
                    });
                    break;
                default:
                    cx = event.pageX;
                    cy = event.pageY;
                    x0 = that.$numpad.offset().left;
                    y0 = that.$numpad.offset().top;
                    document.addEventListener("mousemove", drag);
                    document.addEventListener("mouseup", function() {
                        document.removeEventListener("mousemove", drag);
                        endDrag();
                    });
            }
            that.$numpad.removeClass("transition-top");

            /** @callback */
            function endDrag(event) {
                that.$numpad.addClass("transition-top");
            }

            /** @callback */
            function drag(event) {
                event.preventDefault();
                event.stopPropagation();
                switch (event.type) {
                    case "touchmove":
                        x = event.touches[0].clientX-cx + x0;
                        y = event.touches[0].clientY-cy + y0;
                        break;
                    default:
                        x = event.pageX-cx + x0;
                        y = event.pageY-cy + y0;
                }
                that.$numpad.css({
                    "left": x,
                    "top": y
                });
            }
        }

        // I don't like unbinding previous handlers like this, but it works for now.
        this.$numpad.off();
        this.$numpad[0].addEventListener("mousedown", dragHandler);
        this.$numpad[0].addEventListener("touchstart", dragHandler);
        this.$numpad[0].addEventListener("click", clickHandler);
    }

    /**
     * Called when the enter button is clicked
     * @public
     * @method
     * @param str - string representing the buttons pressed that are in the current buffer
     * @param array - array representing the buttons that were pressed.
     */
    NumberPad.prototype.onenter = function(str, array) { };

    /**
     * called when a button other than enter is clicked
     * @public
     * @method
     * @param str - string representing the buttons pressed that are in the current buffer
     * @param array - array representing the buttons that were pressed.
     */
    NumberPad.prototype.onclick = function(str, array) { };

    NumberPad.prototype.onclear = function(str, array) { };

    NumberPad.prototype.hide = function() {
        this.$numpad.addClass("offscreen");
    };

    NumberPad.prototype.show = function() {
        this.$numpad.removeClass("offscreen");
    };

    NumberPad.prototype.removeClass = function() {
        this.$numpad.removeClass.apply(this.$numpad, arguments);
    };

    NumberPad.prototype.addClass = function() {
        this.$numpad.addClass.apply(this.$numpad, arguments);
    };

    NumberPad.prototype.destroy = function() {
        this.$numpad.off();
        this.onenter = function() { return null; };
        this.onclick = function() { return null; };
    };

    return NumberPad;
});
<commit_msg>allow propagation<commit_after>define([
        "./var/appMessenger"
],function(appMessenger) {

    /**
     * @constructor
     */
    function NumberPad() {
        this.$numpad = $(".numpad");
        var buff = [];
        var that = this;

        /**
         * @public
         * clear buffer
         */
        this.clear = function() {
            while (buff.length) buff.pop();
            return this;
        };

        /**
         * click event handler
         * @callback
         */
        function clickHandler(event) {
            var button = event.target;
            var content = button.innerHTML;
            // only capture number elements
            if (!$(button).hasClass("number")) { return null; }
            // If you clicked enter, then call onenter, clear the buffer, and return.
            if ($(button).hasClass("operator")) {
                _onenter(event);
                return null;
            }
            if ($(button).hasClass("clr")) {
                _onclear(event);
                return null;
            }
            else {
                buff.push(content);
                that.onclick(buff.join(""), buff);
            }
        }

        /**
         * onenter callback
         * @callback
         * @private
         */
        function _onenter(event) {
            that.onenter(buff.join(""), buff);
            that.hide();
            that.clear();
            return null;
        }

        /**
         * clear the buffer callback
         * @callback
         */
        function _onclear(event) {
            that.clear();
            that.onclear(buff.join(""), buff);
            return null;
        }

        /**
         * handle any dragging of the number pad
         * @callback
         */
        function dragHandler(event) {
            //event.preventDefault();
            var cx, cy, x0, y0, x, y;
            if ($(event.target).hasClass("number")) { return null; }
            switch (event.type) {
                case "touchstart":
                    cx = event.touches[0].clientX;
                    cy = event.touches[0].clientY;
                    x0 = that.$numpad.offset().left;
                    y0 = that.$numpad.offset().top;
                    document.addEventListener("touchmove", drag);
                    document.addEventListener("touchend", function() {
                        document.removeEventListener("touchmove", drag);
                        endDrag();
                    });
                    break;
                default:
                    cx = event.pageX;
                    cy = event.pageY;
                    x0 = that.$numpad.offset().left;
                    y0 = that.$numpad.offset().top;
                    document.addEventListener("mousemove", drag);
                    document.addEventListener("mouseup", function() {
                        document.removeEventListener("mousemove", drag);
                        endDrag();
                    });
            }
            that.$numpad.removeClass("transition-top");

            /** @callback */
            function endDrag(event) {
                that.$numpad.addClass("transition-top");
            }

            /** @callback */
            function drag(event) {
                //event.preventDefault();
                //event.stopPropagation();
                switch (event.type) {
                    case "touchmove":
                        x = event.touches[0].clientX-cx + x0;
                        y = event.touches[0].clientY-cy + y0;
                        break;
                    default:
                        x = event.pageX-cx + x0;
                        y = event.pageY-cy + y0;
                }
                that.$numpad.css({
                    "left": x,
                    "top": y
                });
            }
        }

        // I don't like unbinding previous handlers like this, but it works for now.
        this.$numpad.off();
        this.$numpad[0].addEventListener("mousedown", dragHandler);
        this.$numpad[0].addEventListener("touchstart", dragHandler);
        this.$numpad[0].addEventListener("click", clickHandler);
    }

    /**
     * Called when the enter button is clicked
     * @public
     * @method
     * @param str - string representing the buttons pressed that are in the current buffer
     * @param array - array representing the buttons that were pressed.
     */
    NumberPad.prototype.onenter = function(str, array) { };

    /**
     * called when a button other than enter is clicked
     * @public
     * @method
     * @param str - string representing the buttons pressed that are in the current buffer
     * @param array - array representing the buttons that were pressed.
     */
    NumberPad.prototype.onclick = function(str, array) { };

    NumberPad.prototype.onclear = function(str, array) { };

    NumberPad.prototype.hide = function() {
        this.$numpad.addClass("offscreen");
    };

    NumberPad.prototype.show = function() {
        this.$numpad.removeClass("offscreen");
    };

    NumberPad.prototype.removeClass = function() {
        this.$numpad.removeClass.apply(this.$numpad, arguments);
    };

    NumberPad.prototype.addClass = function() {
        this.$numpad.addClass.apply(this.$numpad, arguments);
    };

    NumberPad.prototype.destroy = function() {
        this.$numpad.off();
        this.onenter = function() { return null; };
        this.onclick = function() { return null; };
    };

    return NumberPad;
});
<|endoftext|>


<commit_before>/*
 * Game core for Robots Order BreakOut Trepidation!
 *
 * @canvas = reference to an HTML5 canvas element.
 */

'use strict';
import Actors from 'Actors.js';
import Collision from 'Collision.js';

export default class {
  constructor(canvas) {
    // Player settings.
    this._score = 0;
    this._lives = 3;

    // Game settings.
    this._running = false;

    this._canvas = canvas;
    this._ctx = this._canvas.getContext("2d");

    this._actors = new Actors(this._canvas.width, this._canvas.height);

    this._collision = new Collision();
  }

  _clearScene() {
    this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
    // TODO: Draw background.
  }

  _drawScene() {
    this.clearScene();
    // TODO: Draw scene.

    if (this._running) {
      requestAnimationFrame(()=> this.drawScene());
    }
  }

  _startGameLoop() {
    requestAnimationFrame(()=> this.drawScene());
  }

  // This is kinda out of place here, but haven't found a better
  // place for it yet.
  movePaddle(direction) {
    // TODO: Implement paddle movement.
  }

  start() {
    this._startGameLoop();
  }

  pause() {
    // TODO: Implement some kind of pause.
  }

  stop() {
    this._running = false;
  }
}
<commit_msg>Fix call to incorrect function name<commit_after>/*
 * Game core for Robots Order BreakOut Trepidation!
 *
 * @canvas = reference to an HTML5 canvas element.
 */

'use strict';
import Actors from 'Actors.js';
import Collision from 'Collision.js';

export default class {
  constructor(canvas) {
    // Player settings.
    this._score = 0;
    this._lives = 3;

    // Game settings.
    this._running = false;

    this._canvas = canvas;
    this._ctx = this._canvas.getContext("2d");

    this._actors = new Actors(this._canvas.width, this._canvas.height);

    this._collision = new Collision();
  }

  _clearScene() {
    this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
    // TODO: Draw background.
  }

  _drawScene() {
    this._clearScene();
    // TODO: Draw scene.

    if (this._running) {
      requestAnimationFrame(()=> this._drawScene());
    }
  }

  _startGameLoop() {
    requestAnimationFrame(()=> this._drawScene());
  }

  // This is kinda out of place here, but haven't found a better
  // place for it yet.
  movePaddle(direction) {
    // TODO: Implement paddle movement.
  }

  start() {
    this._startGameLoop();
  }

  pause() {
    // TODO: Implement some kind of pause.
  }

  stop() {
    this._running = false;
  }
}
<|endoftext|>


<commit_before>/*global Grid, Tile, TileLink, TileLinkDescriptor */
"use strict";

var AlcazarAI = function(level) {
    this.level = level;
};

AlcazarAI.prototype.solve = function() {
    while (true) {
        // apply "trivial" procedures until it is not efficient anymore
        var wallUnstable = true;
        var pathUnstable = true;
        var loopUnstable = true;
        var doorUnstable = true;
        while (wallUnstable || pathUnstable || loopUnstable || doorUnstable) {
            wallUnstable = this.fillObviousWalls();
            pathUnstable = this.fillObviousPaths();
            loopUnstable = this.preventObviousLoops();
            doorUnstable = this.openCloseObviousDoors();
        }

        break; // todo: add random walls (one level, then two, then ... )
    }
};

AlcazarAI.prototype.fillObviousWalls = function() {
    // Fill tiles with two paths => other two links are walls
    // return true if any link is changed
    var foundObviousWall = false;
    for (var i = this.level.grid.sizeX - 1; i >= 0; i--) {
        for (var j = this.level.grid.sizeY - 1; j >= 0; j--) {
            var tile = this.level.grid.getTile(i, j);
            var neighborPaths = tile.getNeighborPaths();
            if (neighborPaths.length > 2) {
                throw new Error(
                    "Tile " +
                        String(i) +
                        ", " +
                        String(j) +
                        " has more than 2 paths"
                );
            } else if (neighborPaths.length == 2) {
                // exactly two neighbor paths => any clear neighbor link can be a wall
                var neighborClears = tile.getNeighborClears();
                for (var c = neighborClears.length - 1; c >= 0; c--) {
                    var link = neighborClears[c];
                    link.state = TileLink.stateEnum.USER_WALL;
                    foundObviousWall = true;
                }
            }
        }
    }
    return foundObviousWall;
};

AlcazarAI.prototype.fillObviousPaths = function() {
    // Fill tiles with two walls => other two links are paths
    // return true if any link is changed
    var foundObviousPath = false;
    for (var i = this.level.grid.sizeX - 1; i >= 0; i--) {
        for (var j = this.level.grid.sizeY - 1; j >= 0; j--) {
            var tile = this.level.grid.getTile(i, j);
            var neighborWalls = tile.getNeighborWalls();
            // dirty trick for borders: count them as missing neighbor links
            var neighborLinks = tile.getNeighborLinks();
            var wallCount = neighborWalls.length + (4 - neighborLinks.length);
            if (wallCount > 2) {
                throw new Error(
                    "Tile " +
                        String(i) +
                        ", " +
                        String(j) +
                        " with more than 2 walls"
                );
            } else if (wallCount == 2) {
                // exactly two neighbor walls => any clear neighbor link can be a path
                var neighborClears = tile.getNeighborClears();
                for (var c = neighborClears.length - 1; c >= 0; c--) {
                    var link = neighborClears[c];
                    link.state = TileLink.stateEnum.IN_PATH;
                    foundObviousPath = true;
                }
            }
        }
    }
    return foundObviousPath;
};

AlcazarAI.prototype.preventObviousLoops = function() {
    // Prevent partial paths to form a loop, i.e:
    // if both ends are adjacent, add a wall between them
    // if both ends are one tile apart, prevent the separation tile to connect them (if possible)
    // return true if any link is changed
    var foundPreventableLoop = false;

    var i, j;

    // create marker array with the same size as the level
    // to mark already visited loop/tiles
    var marks = [];
    for (i = 0; i < this.level.grid.sizeX; i++) {
        marks.push([]);
        for (j = 0; j < this.level.grid.sizeY; j++) {
            marks[i].push(false);
        }
    }
    marks[-1] = [];
    marks[-1][-1] = false; // outerTile

    // look for partial paths endpoints (tile with exactly one path link)
    for (i = this.level.grid.sizeX - 1; i >= 0; i--) {
        for (j = this.level.grid.sizeY - 1; j >= 0; j--) {
            var firstTile = this.level.grid.getTile(i, j);
            var firstPaths = firstTile.getNeighborPaths();
            var firstPathCount = firstPaths.length;
            if (firstPathCount > 2) {
                throw new Error(
                    "Tile " +
                        String(i) +
                        ", " +
                        String(j) +
                        " has more than 2 paths"
                );
            }
            if (firstPathCount == 1 && marks[i][j] === false) {
                // find other endpoint
                var pathLength = 2;
                var currentLink = firstPaths[0];
                var currentTile = currentLink.other(firstTile);
                while (currentTile.getNeighborPaths().length == 2) {
                    if (currentTile === firstTile) {
                        throw new Error(
                            "Loop detected at tile " +
                                String(i) +
                                ", " +
                                String(j)
                        );
                    }
                    var paths = currentTile.getNeighborPaths();
                    pathLength = pathLength + 1;
                    currentLink =
                        paths[0] === currentLink ? paths[1] : paths[0];
                    currentTile = currentLink.other(currentTile);
                }
                var lastTile = currentTile;
                // mark both endpoints
                marks[firstTile.x][firstTile.y] = true;
                marks[lastTile.x][lastTile.y] = true;

                // skip trivial paths (only one link)
                if (pathLength == 2) {
                    continue;
                }

                // compare endpoints position
                var dx = lastTile.x - firstTile.x;
                var dy = lastTile.y - firstTile.y;

                // handle adjacent endpoints
                var separationLink = null;
                if (dy === 0) {
                    if (dx == 1) {
                        separationLink =
                            firstTile.neighborLinks[Tile.directions.RIGHT];
                    } else if (dx == -1) {
                        separationLink =
                            firstTile.neighborLinks[Tile.directions.LEFT];
                    }
                } else if (dx === 0) {
                    if (dy == 1) {
                        separationLink =
                            firstTile.neighborLinks[Tile.directions.DOWN];
                    } else if (dy == -1) {
                        separationLink =
                            firstTile.neighborLinks[Tile.directions.UP];
                    }
                }
                if (separationLink !== null) {
                    if (separationLink.state == TileLink.stateEnum.IN_PATH) {
                        throw new Error(
                            "Invalid State: loop separation link in path " +
                                String(i) +
                                ", " +
                                String(j)
                        );
                    }
                    if (separationLink.state == TileLink.stateEnum.CLEAR) {
                        foundPreventableLoop = true;
                        separationLink.state = TileLink.stateEnum.USER_WALL;
                    }
                }

                // handle bouncing (endpoints separated by one tile)
                // TODOOOO...

                // If one of the endpoint is the outerTile (i.e. the path contain a door),
                // and the other endpoint is next to a door --> close the door
                var notOuterEndTile = null;
                var outerTile = this.level.grid.outerTile;
                if (firstTile === outerTile || lastTile === outerTile) {
                    if (firstTile === outerTile) {
                        notOuterEndTile = lastTile;
                    }
                    if (lastTile === outerTile) {
                        notOuterEndTile = firstTile;
                    }

                    var doors = this.level.grid.getDoors();

                    // check if notouter adjacent to a door
                    for (var d = doors.length - 1; d >= 0; d--) {
                        var doorLink = this.level.grid.getLink(doors[d]);
                        var neighborLinks = notOuterEndTile.getNeighborLinks();
                        for (var l = 0; l < neighborLinks.length; l++) {
                            var link = neighborLinks[l];
                            if (link === doorLink) {
                                // make sure that we are not closing the last door
                                // in that case it will be in IN_PATH state after this
                                this.openCloseObviousDoors();

                                if (link.state === TileLink.stateEnum.CLEAR) {
                                    link.state = TileLink.stateEnum.USER_WALL;
                                    foundPreventableLoop = true;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return foundPreventableLoop;
};

AlcazarAI.prototype.bounce = function(x, y, direction) {
    // TODO
};

AlcazarAI.prototype.openCloseObviousDoors = function(first_argument) {
    // Only two doors must be used in the path
    // I.e. if two doors are left open, use them
    // and if two doors are already used, close the others
    // return true if any link is changed
    var changedDoorState = false;

    var doors = this.level.grid.getDoors();
    var openDoors = [];
    for (var i = doors.length - 1; i >= 0; i--) {
        var doorLink = this.level.grid.getLink(doors[i]);
        if (doorLink.state != TileLink.stateEnum.USER_WALL) {
            openDoors.push(doorLink);
        }
    }

    if (openDoors.length < 2) {
        throw new Error("Not enough open doors left");
    } else if (openDoors.length == 2) {
        var firstDoor = openDoors[0];
        var secondDoor = openDoors[1];
        if (firstDoor.state != TileLink.stateEnum.IN_PATH) {
            firstDoor.state = TileLink.stateEnum.IN_PATH;
            changedDoorState = true;
        }
        if (secondDoor.state != TileLink.stateEnum.IN_PATH) {
            secondDoor.state = TileLink.stateEnum.IN_PATH;
            changedDoorState = true;
        }
    } else {
        // more than two open doors
        // if two are in the path => close the others
        var doors_inpath = [];
        for (var j = openDoors.length - 1; j >= 0; j--) {
            var door = openDoors[j];
            if (door.state == TileLink.stateEnum.IN_PATH) {
                doors_inpath.push(door);
            }
        }

        if (doors_inpath.length == 2) {
            for (var k = openDoors.length - 1; k >= 0; k--) {
                if (openDoors[k].state == TileLink.stateEnum.CLEAR) {
                    openDoors[k].state = TileLink.stateEnum.USER_WALL;
                    changedDoorState = true;
                }
            }
        } else if (doors_inpath.length > 2) {
            throw new Error("More than two used doors");
        }
    }

    return changedDoorState;
};
<commit_msg>[PRETTIER]<commit_after>/*global Grid, Tile, TileLink, TileLinkDescriptor */
"use strict";

var AlcazarAI = function(level) {
  this.level = level;
};

AlcazarAI.prototype.solve = function() {
  while (true) {
    // apply "trivial" procedures until it is not efficient anymore
    var wallUnstable = true;
    var pathUnstable = true;
    var loopUnstable = true;
    var doorUnstable = true;
    while (wallUnstable || pathUnstable || loopUnstable || doorUnstable) {
      wallUnstable = this.fillObviousWalls();
      pathUnstable = this.fillObviousPaths();
      loopUnstable = this.preventObviousLoops();
      doorUnstable = this.openCloseObviousDoors();
    }

    break; // todo: add random walls (one level, then two, then ... )
  }
};

AlcazarAI.prototype.fillObviousWalls = function() {
  // Fill tiles with two paths => other two links are walls
  // return true if any link is changed
  var foundObviousWall = false;
  for (var i = this.level.grid.sizeX - 1; i >= 0; i--) {
    for (var j = this.level.grid.sizeY - 1; j >= 0; j--) {
      var tile = this.level.grid.getTile(i, j);
      var neighborPaths = tile.getNeighborPaths();
      if (neighborPaths.length > 2) {
        throw new Error(
          "Tile " + String(i) + ", " + String(j) + " has more than 2 paths"
        );
      } else if (neighborPaths.length == 2) {
        // exactly two neighbor paths => any clear neighbor link can be a wall
        var neighborClears = tile.getNeighborClears();
        for (var c = neighborClears.length - 1; c >= 0; c--) {
          var link = neighborClears[c];
          link.state = TileLink.stateEnum.USER_WALL;
          foundObviousWall = true;
        }
      }
    }
  }
  return foundObviousWall;
};

AlcazarAI.prototype.fillObviousPaths = function() {
  // Fill tiles with two walls => other two links are paths
  // return true if any link is changed
  var foundObviousPath = false;
  for (var i = this.level.grid.sizeX - 1; i >= 0; i--) {
    for (var j = this.level.grid.sizeY - 1; j >= 0; j--) {
      var tile = this.level.grid.getTile(i, j);
      var neighborWalls = tile.getNeighborWalls();
      // dirty trick for borders: count them as missing neighbor links
      var neighborLinks = tile.getNeighborLinks();
      var wallCount = neighborWalls.length + (4 - neighborLinks.length);
      if (wallCount > 2) {
        throw new Error(
          "Tile " + String(i) + ", " + String(j) + " with more than 2 walls"
        );
      } else if (wallCount == 2) {
        // exactly two neighbor walls => any clear neighbor link can be a path
        var neighborClears = tile.getNeighborClears();
        for (var c = neighborClears.length - 1; c >= 0; c--) {
          var link = neighborClears[c];
          link.state = TileLink.stateEnum.IN_PATH;
          foundObviousPath = true;
        }
      }
    }
  }
  return foundObviousPath;
};

AlcazarAI.prototype.preventObviousLoops = function() {
  // Prevent partial paths to form a loop, i.e:
  // if both ends are adjacent, add a wall between them
  // if both ends are one tile apart, prevent the separation tile to connect them (if possible)
  // return true if any link is changed
  var foundPreventableLoop = false;

  var i, j;

  // create marker array with the same size as the level
  // to mark already visited loop/tiles
  var marks = [];
  for (i = 0; i < this.level.grid.sizeX; i++) {
    marks.push([]);
    for (j = 0; j < this.level.grid.sizeY; j++) {
      marks[i].push(false);
    }
  }
  marks[-1] = [];
  marks[-1][-1] = false; // outerTile

  // look for partial paths endpoints (tile with exactly one path link)
  for (i = this.level.grid.sizeX - 1; i >= 0; i--) {
    for (j = this.level.grid.sizeY - 1; j >= 0; j--) {
      var firstTile = this.level.grid.getTile(i, j);
      var firstPaths = firstTile.getNeighborPaths();
      var firstPathCount = firstPaths.length;
      if (firstPathCount > 2) {
        throw new Error(
          "Tile " + String(i) + ", " + String(j) + " has more than 2 paths"
        );
      }
      if (firstPathCount == 1 && marks[i][j] === false) {
        // find other endpoint
        var pathLength = 2;
        var currentLink = firstPaths[0];
        var currentTile = currentLink.other(firstTile);
        while (currentTile.getNeighborPaths().length == 2) {
          if (currentTile === firstTile) {
            throw new Error(
              "Loop detected at tile " + String(i) + ", " + String(j)
            );
          }
          var paths = currentTile.getNeighborPaths();
          pathLength = pathLength + 1;
          currentLink = paths[0] === currentLink ? paths[1] : paths[0];
          currentTile = currentLink.other(currentTile);
        }
        var lastTile = currentTile;
        // mark both endpoints
        marks[firstTile.x][firstTile.y] = true;
        marks[lastTile.x][lastTile.y] = true;

        // skip trivial paths (only one link)
        if (pathLength == 2) {
          continue;
        }

        // compare endpoints position
        var dx = lastTile.x - firstTile.x;
        var dy = lastTile.y - firstTile.y;

        // handle adjacent endpoints
        var separationLink = null;
        if (dy === 0) {
          if (dx == 1) {
            separationLink = firstTile.neighborLinks[Tile.directions.RIGHT];
          } else if (dx == -1) {
            separationLink = firstTile.neighborLinks[Tile.directions.LEFT];
          }
        } else if (dx === 0) {
          if (dy == 1) {
            separationLink = firstTile.neighborLinks[Tile.directions.DOWN];
          } else if (dy == -1) {
            separationLink = firstTile.neighborLinks[Tile.directions.UP];
          }
        }
        if (separationLink !== null) {
          if (separationLink.state == TileLink.stateEnum.IN_PATH) {
            throw new Error(
              "Invalid State: loop separation link in path " +
                String(i) +
                ", " +
                String(j)
            );
          }
          if (separationLink.state == TileLink.stateEnum.CLEAR) {
            foundPreventableLoop = true;
            separationLink.state = TileLink.stateEnum.USER_WALL;
          }
        }

        // handle bouncing (endpoints separated by one tile)
        // TODOOOO...

        // If one of the endpoint is the outerTile (i.e. the path contain a door),
        // and the other endpoint is next to a door --> close the door
        var notOuterEndTile = null;
        var outerTile = this.level.grid.outerTile;
        if (firstTile === outerTile || lastTile === outerTile) {
          if (firstTile === outerTile) {
            notOuterEndTile = lastTile;
          }
          if (lastTile === outerTile) {
            notOuterEndTile = firstTile;
          }

          var doors = this.level.grid.getDoors();

          // check if notouter adjacent to a door
          for (var d = doors.length - 1; d >= 0; d--) {
            var doorLink = this.level.grid.getLink(doors[d]);
            var neighborLinks = notOuterEndTile.getNeighborLinks();
            for (var l = 0; l < neighborLinks.length; l++) {
              var link = neighborLinks[l];
              if (link === doorLink) {
                // make sure that we are not closing the last door
                // in that case it will be in IN_PATH state after this
                this.openCloseObviousDoors();

                if (link.state === TileLink.stateEnum.CLEAR) {
                  link.state = TileLink.stateEnum.USER_WALL;
                  foundPreventableLoop = true;
                }
              }
            }
          }
        }
      }
    }
  }

  return foundPreventableLoop;
};

AlcazarAI.prototype.bounce = function(x, y, direction) {
  // TODO
};

AlcazarAI.prototype.openCloseObviousDoors = function(first_argument) {
  // Only two doors must be used in the path
  // I.e. if two doors are left open, use them
  // and if two doors are already used, close the others
  // return true if any link is changed
  var changedDoorState = false;

  var doors = this.level.grid.getDoors();
  var openDoors = [];
  for (var i = doors.length - 1; i >= 0; i--) {
    var doorLink = this.level.grid.getLink(doors[i]);
    if (doorLink.state != TileLink.stateEnum.USER_WALL) {
      openDoors.push(doorLink);
    }
  }

  if (openDoors.length < 2) {
    throw new Error("Not enough open doors left");
  } else if (openDoors.length == 2) {
    var firstDoor = openDoors[0];
    var secondDoor = openDoors[1];
    if (firstDoor.state != TileLink.stateEnum.IN_PATH) {
      firstDoor.state = TileLink.stateEnum.IN_PATH;
      changedDoorState = true;
    }
    if (secondDoor.state != TileLink.stateEnum.IN_PATH) {
      secondDoor.state = TileLink.stateEnum.IN_PATH;
      changedDoorState = true;
    }
  } else {
    // more than two open doors
    // if two are in the path => close the others
    var doors_inpath = [];
    for (var j = openDoors.length - 1; j >= 0; j--) {
      var door = openDoors[j];
      if (door.state == TileLink.stateEnum.IN_PATH) {
        doors_inpath.push(door);
      }
    }

    if (doors_inpath.length == 2) {
      for (var k = openDoors.length - 1; k >= 0; k--) {
        if (openDoors[k].state == TileLink.stateEnum.CLEAR) {
          openDoors[k].state = TileLink.stateEnum.USER_WALL;
          changedDoorState = true;
        }
      }
    } else if (doors_inpath.length > 2) {
      throw new Error("More than two used doors");
    }
  }

  return changedDoorState;
};
<|endoftext|>


<commit_before>/**
 * Created by Derek Xiao on 6/3/2017.
 */

function visualize_scanning(sorted_vertex) {
    var x_values = sorted_vertex.map(function (v) {
        return v.x;
    });
    //var canvas = document.getElementById('animation');
    //var animation_ctx = canvas.getContext("2d");
    var width = canvas.width;// * 1.5;
    var height = canvas.height;

    var progress = 0, step = 0.003, highlight_radius = 30;

    var max_progress = (highlight_radius * 4) / width + 1;

    var node_color = "#7c7c7c";
    var scaling_radius = function (delta) {
        delta = Math.max(0, delta - 15);
        return highlight_radius * Math.exp(-delta / 10);
    };
    function frame() {
        var x_threshold = progress * width;
        var vertex = sorted_vertex.filter(function (v) {
            return v.x <= x_threshold + highlight_radius * 2;
        });

        animation_ctx.clearRect(0, 0, width, height);

        if (progress < 1) {
            animation_ctx.beginPath();
            animation_ctx.fillStyle = "rgba(128,128,128,0.2)";
            animation_ctx.fillRect(-1, -1, x_threshold + 1, height + 2);
        }

        animation_ctx.fillStyle = node_color;
        animation_ctx.fillRect(x_threshold - 1, -1, 4, height + 2);

        var size = 20;
        for (var i = 0; i < vertex.length; i ++) {
            var v = vertex[i];
            var delta = Math.abs(v.x - x_threshold);
            if (delta < highlight_radius * 5) {
                var r = scaling_radius(delta);
                animation_ctx.beginPath();
                animation_ctx.fillStyle = "orange";
                animation_ctx.fillRect(v.x - r, v.y - r,
                    r * 2, r * 2
                );
            }
            animation_ctx.fillStyle = node_color;
            animation_ctx.fillRect(v.x - size / 2, v.y - size / 2, size, size);

            // draw right neighbour relationship
            var rn = v.get_right_neighbour();
            if (rn == null) {
                continue;
            }
            animation_ctx.setLineDash([]);
            animation_ctx.lineWidth = 5;
            animation_ctx.beginPath();
            animation_ctx.moveTo(v.x, v.y);
            // var e = interpolate(v, rn, Math.min(1, delta / highlight_radius * 0.05));
            var e = interpolate2(v, rn, x_threshold);

            animation_ctx.lineTo(e.x, e.y);
            animation_ctx.stroke();
        }
        if (progress <= max_progress) {
            requestAnimationFrame(frame);
        }
        progress += step;
    }

    var animation_id = requestAnimationFrame(frame);
    console.log(animation_id);
}

function display_quadrilateral(quadrilaterals, history) {
    var context = animation_ctx;
    clearCanvas(context);
    if (quadrilaterals.length == 0) return;
    var progress = 0, step = 1 / quadrilaterals.length * 0.01;
    var first_stage = 0.1,
        second_stage = 0.5,
        third_stage = 0.1,
        last_stage = 0.3;
    var active_lineWidth = 10;
    var progress_per_q = 1 / quadrilaterals.length;
    function frame() {
        clearCanvas(context);
        var completed_count = Math.floor(progress * quadrilaterals.length);
        quadrilaterals.slice(0, completed_count).forEach(function (q) {
            q.drawPath_closed(context, "rgba(208,208,208,0.5)");
        });

        var animation_quadrilateral_id = completed_count;
        if (animation_quadrilateral_id >= quadrilaterals.length) {
            return;
        }
        var q = quadrilaterals[animation_quadrilateral_id];
        var residual = progress - completed_count * progress_per_q;
        var t = residual / progress_per_q;
        var u = history[animation_quadrilateral_id][0];
        var v = history[animation_quadrilateral_id][1];
        var r = history[animation_quadrilateral_id][2];
        var s = history[animation_quadrilateral_id][3];

        var mid_t;
        mid_t = interpolate(u, v, Math.min(t / first_stage, 1));
        context.save();
        context.lineWidth = active_lineWidth;
        context.strokeStyle = 'black';
        context.beginPath();
        context.moveTo(u.x, u.y);
        context.lineTo(mid_t.x, mid_t.y);
        context.stroke();
        context.restore();

        if (t > first_stage) {
            mid_t = interpolate(v, r, Math.min((t - first_stage) / second_stage, 1));
            context.save();
            context.setLineDash([10, 6]);
            context.lineWidth = active_lineWidth;
            context.strokeStyle = 'gray';
            context.beginPath();
            context.moveTo(v.x, v.y);
            context.lineTo(mid_t.x, mid_t.y);
            context.stroke();
            context.restore();
        }
        if (t > first_stage + second_stage) {
            mid_t = interpolate(r, s, Math.min((t - first_stage - second_stage) / third_stage, 1));
            context.save();
            context.lineWidth = active_lineWidth;
            context.strokeStyle = 'black';
            context.beginPath();
            context.moveTo(r.x, r.y);
            context.lineTo(mid_t.x, mid_t.y);
            context.stroke();
            context.restore();
        }
        if (t > first_stage + second_stage + third_stage) {
            var opacity = (t - first_stage - second_stage - third_stage) / last_stage;
            opacity = 0.5 + 0.5 / (1 + Math.exp((opacity * 12 - 6)));
            var color = "rgba(208,208,208," + opacity + ")";
            q.drawPath_closed(animation_ctx, color, active_lineWidth);
        }

        progress += step;
        if (progress <= 1 + first_stage) {
            requestAnimationFrame(frame);
        }
    }

    var animation_id = requestAnimationFrame(frame);
}
<commit_msg>:confetti_ball: 给右邻居连线加上渐变颜色<commit_after>/**
 * Created by Derek Xiao on 6/3/2017.
 */

function visualize_scanning(sorted_vertex) {
    var x_values = sorted_vertex.map(function (v) {
        return v.x;
    });
    //var canvas = document.getElementById('animation');
    //var animation_ctx = canvas.getContext("2d");
    var width = canvas.width;// * 1.5;
    var height = canvas.height;

    var progress = 0, step = 0.003, highlight_radius = 30;

    var max_progress = (highlight_radius * 4) / width + 1;

    var node_color = "#7c7c7c";
    var scaling_radius = function (delta) {
        delta = Math.max(0, delta - 15);
        return highlight_radius * Math.exp(-delta / 10);
    };
    function frame() {
        var x_threshold = progress * width;
        var vertex = sorted_vertex.filter(function (v) {
            return v.x <= x_threshold + highlight_radius * 2;
        });

        animation_ctx.clearRect(0, 0, width, height);

        if (progress < 1) {
            animation_ctx.beginPath();
            animation_ctx.fillStyle = "rgba(128,128,128,0.2)";
            animation_ctx.fillRect(-1, -1, x_threshold + 1, height + 2);
        }

        animation_ctx.fillStyle = node_color;
        animation_ctx.fillRect(x_threshold - 1, -1, 4, height + 2);

        var size = 20;
        for (var i = 0; i < vertex.length; i ++) {
            var v = vertex[i];
            var delta = Math.abs(v.x - x_threshold);
            if (delta < highlight_radius * 5) {
                var r = scaling_radius(delta);
                animation_ctx.beginPath();
                animation_ctx.fillStyle = "orange";
                animation_ctx.fillRect(v.x - r, v.y - r,
                    r * 2, r * 2
                );
            }
            animation_ctx.fillStyle = node_color;
            animation_ctx.fillRect(v.x - size / 2, v.y - size / 2, size, size);

            // draw right neighbour relationship
            var rn = v.get_right_neighbour();
            if (rn == null) {
                continue;
            }
            var gnt = animation_ctx.createLinearGradient(v.x, v.y, rn.x, rn.y);
            gnt.addColorStop(0, 'blue');
            gnt.addColorStop(1, 'yellow');
            animation_ctx.strokeStyle = gnt;
            animation_ctx.setLineDash([]);
            animation_ctx.lineWidth = 5;
            animation_ctx.beginPath();
            animation_ctx.moveTo(v.x, v.y);
            // var e = interpolate(v, rn, Math.min(1, delta / highlight_radius * 0.05));
            var e = interpolate2(v, rn, x_threshold);
            animation_ctx.lineTo(e.x, e.y);
            animation_ctx.stroke();
        }
        if (progress <= max_progress) {
            requestAnimationFrame(frame);
        }
        progress += step;
    }

    var animation_id = requestAnimationFrame(frame);
    console.log(animation_id);
}

function display_quadrilateral(quadrilaterals, history) {
    var context = animation_ctx;
    clearCanvas(context);
    if (quadrilaterals.length == 0) return;
    var progress = 0, step = 1 / quadrilaterals.length * 0.01;
    var first_stage = 0.1,
        second_stage = 0.5,
        third_stage = 0.1,
        last_stage = 0.3;
    var active_lineWidth = 10;
    var progress_per_q = 1 / quadrilaterals.length;
    function frame() {
        clearCanvas(context);
        var completed_count = Math.floor(progress * quadrilaterals.length);
        quadrilaterals.slice(0, completed_count).forEach(function (q) {
            q.drawPath_closed(context, "rgba(208,208,208,0.5)");
        });

        var animation_quadrilateral_id = completed_count;
        if (animation_quadrilateral_id >= quadrilaterals.length) {
            return;
        }
        var q = quadrilaterals[animation_quadrilateral_id];
        var residual = progress - completed_count * progress_per_q;
        var t = residual / progress_per_q;
        var u = history[animation_quadrilateral_id][0];
        var v = history[animation_quadrilateral_id][1];
        var r = history[animation_quadrilateral_id][2];
        var s = history[animation_quadrilateral_id][3];

        var mid_t;
        mid_t = interpolate(u, v, Math.min(t / first_stage, 1));
        context.save();
        context.lineWidth = active_lineWidth;
        context.strokeStyle = 'black';
        context.beginPath();
        context.moveTo(u.x, u.y);
        context.lineTo(mid_t.x, mid_t.y);
        context.stroke();
        context.restore();

        if (t > first_stage) {
            mid_t = interpolate(v, r, Math.min((t - first_stage) / second_stage, 1));
            context.save();
            context.setLineDash([10, 6]);
            context.lineWidth = active_lineWidth;
            context.strokeStyle = 'gray';
            context.beginPath();
            context.moveTo(v.x, v.y);
            context.lineTo(mid_t.x, mid_t.y);
            context.stroke();
            context.restore();
        }
        if (t > first_stage + second_stage) {
            mid_t = interpolate(r, s, Math.min((t - first_stage - second_stage) / third_stage, 1));
            context.save();
            context.lineWidth = active_lineWidth;
            context.strokeStyle = 'black';
            context.beginPath();
            context.moveTo(r.x, r.y);
            context.lineTo(mid_t.x, mid_t.y);
            context.stroke();
            context.restore();
        }
        if (t > first_stage + second_stage + third_stage) {
            var opacity = (t - first_stage - second_stage - third_stage) / last_stage;
            opacity = 0.5 + 0.5 / (1 + Math.exp((opacity * 12 - 6)));
            var color = "rgba(208,208,208," + opacity + ")";
            q.drawPath_closed(animation_ctx, color, active_lineWidth);
        }

        progress += step;
        if (progress <= 1 + first_stage) {
            requestAnimationFrame(frame);
        }
    }

    var animation_id = requestAnimationFrame(frame);
}
<|endoftext|>


<commit_before>class App extends Base {

	constructor() {

		super();

		this.factories = {};
		this.factories.settings = new Settings();
		this.factories.weather = new Weather();
		this.factories.links = new Links();
		this.factories.news = new News();

		this.updateTrads();

		this.updateClock();
		this.updateGreetings();
		this.updateBackground();

		this.setEvents();

	}

	updateClock() {
		var now = new Date(); // current date
		var time = ("0" + now.getHours()).slice(-2) + ' : ' + ("0" + now.getMinutes()).slice(-2) + ' : ' + ("0" + now.getSeconds()).slice(-2);
		$('#clock h1').html(time);
		//this.updateGreetings();
		setTimeout(this.updateClock.bind(this), 1000);
	}

	updateGreetings() {
		let self = this;
		var now = new Date();
		var hour = now.getHours();
		var message = '';
		if(hour >= 5 && hour < 12) {
			message = this.getTrad("greetingsMorning");
		} else if(hour >= 12 && hour < 21) {
			message = this.getTrad("greetingsAfternoon");
		} else if(hour >= 21 || hour < 5) {
			message = this.getTrad("greetingsEvening");
		}

		this.getFromStorage('username',function(data){
			if(self.isInStorage(data, 'username')) {
				$('#greetings').html(message+', '+data.username);
				$('input[name="name"]').val(data.username);
			} else {
				var input = $('<input />');
				input.on('keydown', function(e){
					self.factories.settings.changeName(e, this.value, self.updateGreetings.bind(self));
				});
				$('#greetings').html(message+', ');
				$('#greetings').append(input);
				$('input[name="name"]').val('');
			}
		});
	}

	updateBackground() {
		let self = this;
		this.getFromStorage('background', function(data){
			if(self.isInStorage(data, 'background')) {
				// Tengo fondo, se pone
				$('#background').css('background-image', 'url("'+data.background.img+'")').waitForImages(function() {
					$('#background').addClass('show');
					self.cacheBackground(false);
				}, $.noop, true);
			} else {
				self.cacheBackground(true);
			}
		});
	}

	cacheBackground(reload = false) {
		let self = this;
		var photo = new UnsplashPhoto();
		var url = photo.fromCategory('nature')/*.of(["trees", "water"])*/.size(1920,1080).fetch();

		var xhr = new XMLHttpRequest();
		xhr.onload = function() {
			var reader = new FileReader();
			reader.onloadend = function() {

				var now = new Date();
				self.setInStorage('background', {img: reader.result, timestamp: now.getTime()},function() {
					if(reload) {
						self.updateBackground();
					}
				});
			}
			reader.readAsDataURL(xhr.response);
		};
		xhr.open('GET', url);
		xhr.responseType = 'blob';
		xhr.send();
	}

	setEvents() {

		var self = this;

		$('input[name="name"]').on('keydown', function(e){
			console.log("PASO");
			self.factories.settings.changeName(e, this.value, self.updateGreetings.bind(self))
		});

		$(document).mouseup(function(e) {
			// if the target of the click isn't the container nor a descendant of the container
			if (!$("#weather").is(e.target) && $("#weather").has(e.target).length === 0 && $("#weather").is(':visible')) {
				$("#weather").click();
			} else if(!$("#settings").is(e.target) && $("#settings").has(e.target).length === 0 && parseInt($("#settings").css('left')) == 0) {
				$('#close-settings').click();
			}
		});

	}

}

$(document).ready(function(){
	top.app = new App();
	//app.deleteAllStorage();
});<commit_msg>change greetings on 5, 12, 21 hours, fixes #13<commit_after>class App extends Base {

	constructor() {

		super();

		this.factories = {};
		this.factories.settings = new Settings();
		this.factories.weather = new Weather();
		this.factories.links = new Links();
		this.factories.news = new News();

		this.updateTrads();

		this.updateClock();
		this.updateGreetings();
		this.updateBackground();

		this.setEvents();

	}

	updateClock() {
		var now = new Date(); // current date
		if((now.getHours() == 5 || now.getHours() == 12 || now.getHours() == 21) && now.getMinutes() == 0 && now.getSeconds() == 0) {
			this.updateGreetings();
		}
		var time = ("0" + now.getHours()).slice(-2) + ' : ' + ("0" + now.getMinutes()).slice(-2) + ' : ' + ("0" + now.getSeconds()).slice(-2);
		$('#clock h1').html(time);
		//this.updateGreetings();
		setTimeout(this.updateClock.bind(this), 1000);
	}

	updateGreetings() {
		let self = this;
		var now = new Date();
		var hour = now.getHours();
		var message = '';
		if(hour >= 5 && hour < 12) {
			message = this.getTrad("greetingsMorning");
		} else if(hour >= 12 && hour < 21) {
			message = this.getTrad("greetingsAfternoon");
		} else if(hour >= 21 || hour < 5) {
			message = this.getTrad("greetingsEvening");
		}

		this.getFromStorage('username',function(data){
			if(self.isInStorage(data, 'username')) {
				$('#greetings').html(message+', '+data.username);
				$('input[name="name"]').val(data.username);
			} else {
				var input = $('<input />');
				input.on('keydown', function(e){
					self.factories.settings.changeName(e, this.value, self.updateGreetings.bind(self));
				});
				$('#greetings').html(message+', ');
				$('#greetings').append(input);
				$('input[name="name"]').val('');
			}
		});
	}

	updateBackground() {
		let self = this;
		this.getFromStorage('background', function(data){
			if(self.isInStorage(data, 'background')) {
				// Tengo fondo, se pone
				$('#background').css('background-image', 'url("'+data.background.img+'")').waitForImages(function() {
					$('#background').addClass('show');
					self.cacheBackground(false);
				}, $.noop, true);
			} else {
				self.cacheBackground(true);
			}
		});
	}

	cacheBackground(reload = false) {
		let self = this;
		var photo = new UnsplashPhoto();
		var url = photo.fromCategory('nature')/*.of(["trees", "water"])*/.size(1920,1080).fetch();

		var xhr = new XMLHttpRequest();
		xhr.onload = function() {
			var reader = new FileReader();
			reader.onloadend = function() {

				var now = new Date();
				self.setInStorage('background', {img: reader.result, timestamp: now.getTime()},function() {
					if(reload) {
						self.updateBackground();
					}
				});
			}
			reader.readAsDataURL(xhr.response);
		};
		xhr.open('GET', url);
		xhr.responseType = 'blob';
		xhr.send();
	}

	setEvents() {

		var self = this;

		$('input[name="name"]').on('keydown', function(e){
			console.log("PASO");
			self.factories.settings.changeName(e, this.value, self.updateGreetings.bind(self))
		});

		$(document).mouseup(function(e) {
			// if the target of the click isn't the container nor a descendant of the container
			if (!$("#weather").is(e.target) && $("#weather").has(e.target).length === 0 && $("#weather").is(':visible')) {
				$("#weather").click();
			} else if(!$("#settings").is(e.target) && $("#settings").has(e.target).length === 0 && parseInt($("#settings").css('left')) == 0) {
				$('#close-settings').click();
			}
		});

	}

}

$(document).ready(function(){
	top.app = new App();
	//app.deleteAllStorage();
});<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const binance = require ('./binance.js');

//  ---------------------------------------------------------------------------

module.exports = class binanceje extends binance {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'binanceje',
            'name': 'Binance Jersey',
            'countries': [ 'JE' ], // Jersey
            'certified': false,
            'pro': true,
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/54874009-d526eb00-4df3-11e9-928c-ce6a2b914cd1.jpg',
                'api': {
                    'web': 'https://www.binance.je',
                    'wapi': 'https://api.binance.je/wapi/v3',
                    'public': 'https://api.binance.je/api/v1',
                    'private': 'https://api.binance.je/api/v3',
                    'v3': 'https://api.binance.je/api/v3',
                    'v1': 'https://api.binance.je/api/v1',
                },
                'www': 'https://www.binance.je',
                'referral': 'https://www.binance.je/?ref=35047921',
                'doc': 'https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md',
                'fees': 'https://www.binance.je/fees.html',
            },
            'fees': {
                'trading': {
                    'tierBased': false,
                    'percentage': true,
                    'taker': 0.0005,
                    'maker': 0.0005,
                },
                // should be deleted, these are outdated and inaccurate
                'funding': {
                    'tierBased': false,
                    'percentage': false,
                    'withdraw': {
                        'BTC': 0.0005,
                        'ETH': 0.01,
                    },
                    'deposit': {},
                },
            },
            'options': {
                'quoteOrderQty': false, // whether market orders support amounts in quote currency
            },
        });
    }
};

<commit_msg>binanceje shutdown<commit_after><|endoftext|>


<commit_before>'use strict';

// ---------------------------------------------------------------------------

const bittrex = require ('./bittrex.js');
const { AuthenticationError, InvalidOrder, InsufficientFunds, DDoSProtection } = require ('./base/errors');

// ---------------------------------------------------------------------------

module.exports = class bleutrade extends bittrex {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'bleutrade',
            'name': 'Bleutrade',
            'countries': 'BR', // Brazil
            'rateLimit': 1000,
            'version': 'v2',
            'has': {
                'CORS': true,
                'fetchTickers': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/30303000-b602dbe6-976d-11e7-956d-36c5049c01e7.jpg',
                'api': {
                    'public': 'https://bleutrade.com/api',
                    'account': 'https://bleutrade.com/api',
                    'market': 'https://bleutrade.com/api',
                },
                'www': 'https://bleutrade.com',
                'doc': 'https://bleutrade.com/help/API',
                'fees': 'https://bleutrade.com/help/fees_and_deadlines',
            },
            'fees': {
                'funding': {
                    'withdraw': {
                        'ADC': 0.1,
                        'BTA': 0.1,
                        'BITB': 0.1,
                        'BTC': 0.001,
                        'BCC': 0.001,
                        'BTCD': 0.001,
                        'BTG': 0.001,
                        'BLK': 0.1,
                        'CDN': 0.1,
                        'CLAM': 0.01,
                        'DASH': 0.001,
                        'DCR': 0.05,
                        'DGC': 0.1,
                        'DP': 0.1,
                        'DPC': 0.1,
                        'DOGE': 10.0,
                        'EFL': 0.1,
                        'ETH': 0.01,
                        'EXP': 0.1,
                        'FJC': 0.1,
                        'BSTY': 0.001,
                        'GB': 0.1,
                        'NLG': 0.1,
                        'HTML': 1.0,
                        'LTC': 0.001,
                        'MONA': 0.01,
                        'MOON': 1.0,
                        'NMC': 0.015,
                        'NEOS': 0.1,
                        'NVC': 0.05,
                        'OK': 0.1,
                        'PPC': 0.1,
                        'POT': 0.1,
                        'XPM': 0.001,
                        'QTUM': 0.1,
                        'RDD': 0.1,
                        'SLR': 0.1,
                        'START': 0.1,
                        'SLG': 0.1,
                        'TROLL': 0.1,
                        'UNO': 0.01,
                        'VRC': 0.1,
                        'VTC': 0.1,
                        'XVP': 0.1,
                        'WDC': 0.001,
                        'ZET': 0.1,
                    },
                },
            },
            'exceptions': {
                'Insufficient funds!': InsufficientFunds,
            },
        });
    }

    async fetchMarkets () {
        let markets = await this.publicGetMarkets ();
        let result = [];
        for (let p = 0; p < markets['result'].length; p++) {
            let market = markets['result'][p];
            let id = market['MarketName'];
            let base = market['MarketCurrency'];
            let quote = market['BaseCurrency'];
            base = this.commonCurrencyCode (base);
            quote = this.commonCurrencyCode (quote);
            let symbol = base + '/' + quote;
            let precision = {
                'amount': 8,
                'price': 8,
            };
            let active = market['IsActive'];
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'active': active,
                'info': market,
                'lot': Math.pow (10, -precision['amount']),
                'precision': precision,
                'limits': {
                    'amount': {
                        'min': market['MinTradeSize'],
                        'max': undefined,
                    },
                    'price': {
                        'min': undefined,
                        'max': undefined,
                    },
                    'cost': {
                        'min': 0,
                        'max': undefined,
                    },
                },
            });
        }
        return result;
    }

    getOrderIdField () {
        return 'orderid';
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let request = {
            'market': this.marketId (symbol),
            'type': 'ALL',
        };
        if (typeof limit !== 'undefined')
            request['depth'] = limit; // 50
        let response = await this.publicGetOrderbook (this.extend (request, params));
        let orderbook = response['result'];
        return this.parseOrderBook (orderbook, undefined, 'buy', 'sell', 'Rate', 'Quantity');
    }
};
<commit_msg>bleutrade: InvalidOrder, AuthenticationError<commit_after>'use strict';

// ---------------------------------------------------------------------------

const bittrex = require ('./bittrex.js');
const { AuthenticationError, InvalidOrder, InsufficientFunds } = require ('./base/errors');

// ---------------------------------------------------------------------------

module.exports = class bleutrade extends bittrex {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'bleutrade',
            'name': 'Bleutrade',
            'countries': 'BR', // Brazil
            'rateLimit': 1000,
            'version': 'v2',
            'has': {
                'CORS': true,
                'fetchTickers': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/30303000-b602dbe6-976d-11e7-956d-36c5049c01e7.jpg',
                'api': {
                    'public': 'https://bleutrade.com/api',
                    'account': 'https://bleutrade.com/api',
                    'market': 'https://bleutrade.com/api',
                },
                'www': 'https://bleutrade.com',
                'doc': 'https://bleutrade.com/help/API',
                'fees': 'https://bleutrade.com/help/fees_and_deadlines',
            },
            'fees': {
                'funding': {
                    'withdraw': {
                        'ADC': 0.1,
                        'BTA': 0.1,
                        'BITB': 0.1,
                        'BTC': 0.001,
                        'BCC': 0.001,
                        'BTCD': 0.001,
                        'BTG': 0.001,
                        'BLK': 0.1,
                        'CDN': 0.1,
                        'CLAM': 0.01,
                        'DASH': 0.001,
                        'DCR': 0.05,
                        'DGC': 0.1,
                        'DP': 0.1,
                        'DPC': 0.1,
                        'DOGE': 10.0,
                        'EFL': 0.1,
                        'ETH': 0.01,
                        'EXP': 0.1,
                        'FJC': 0.1,
                        'BSTY': 0.001,
                        'GB': 0.1,
                        'NLG': 0.1,
                        'HTML': 1.0,
                        'LTC': 0.001,
                        'MONA': 0.01,
                        'MOON': 1.0,
                        'NMC': 0.015,
                        'NEOS': 0.1,
                        'NVC': 0.05,
                        'OK': 0.1,
                        'PPC': 0.1,
                        'POT': 0.1,
                        'XPM': 0.001,
                        'QTUM': 0.1,
                        'RDD': 0.1,
                        'SLR': 0.1,
                        'START': 0.1,
                        'SLG': 0.1,
                        'TROLL': 0.1,
                        'UNO': 0.01,
                        'VRC': 0.1,
                        'VTC': 0.1,
                        'XVP': 0.1,
                        'WDC': 0.001,
                        'ZET': 0.1,
                    },
                },
            },
            'exceptions': {
                'Insufficient funds!': InsufficientFunds,
                'Invalid Order ID': InvalidOrder,
                'Invalid apikey or apisecret': AuthenticationError,
            },
        });
    }

    async fetchMarkets () {
        let markets = await this.publicGetMarkets ();
        let result = [];
        for (let p = 0; p < markets['result'].length; p++) {
            let market = markets['result'][p];
            let id = market['MarketName'];
            let base = market['MarketCurrency'];
            let quote = market['BaseCurrency'];
            base = this.commonCurrencyCode (base);
            quote = this.commonCurrencyCode (quote);
            let symbol = base + '/' + quote;
            let precision = {
                'amount': 8,
                'price': 8,
            };
            let active = market['IsActive'];
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'active': active,
                'info': market,
                'lot': Math.pow (10, -precision['amount']),
                'precision': precision,
                'limits': {
                    'amount': {
                        'min': market['MinTradeSize'],
                        'max': undefined,
                    },
                    'price': {
                        'min': undefined,
                        'max': undefined,
                    },
                    'cost': {
                        'min': 0,
                        'max': undefined,
                    },
                },
            });
        }
        return result;
    }

    getOrderIdField () {
        return 'orderid';
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let request = {
            'market': this.marketId (symbol),
            'type': 'ALL',
        };
        if (typeof limit !== 'undefined')
            request['depth'] = limit; // 50
        let response = await this.publicGetOrderbook (this.extend (request, params));
        let orderbook = response['result'];
        return this.parseOrderBook (orderbook, undefined, 'buy', 'sell', 'Rate', 'Quantity');
    }
};
<|endoftext|>


<commit_before>/*
 * cem.shell.js
 * Shell for Cemetery Project CMP343
*/

cem.shell = (function () {
  'use strict';
  //---------------- BEGIN MODULE SCOPE VARIABLES --------------
  var
    configMap = {
      anchor_schema_map : {
        chat  : { opened : true, closed : true }
      },
      resize_interval : 200,
      main_html : String()
        + '
'
          + '
'
            + '
CEM/SPA
'
            + '
The past is a gift to the future . .
'
          + '
'
          + '

'
        + '
'
        + '
'
	  // Display main menu; this needs to be done with code
          + '
'
	  + '
Temporary Menu:
'
	  + '
'
          +  'Cemetery Data Input
'
          + '
'
          +  'Geolocation Point Data
'
	  +  '
'
	  +  'Marker Details
'
	  + '
'
	  +  ' PWI Plugin
'
	  +  '
'
	  +  'Show PWI Data
'
          + '
'
          +  'Clear All

'
          + '

'
	  + '

'
	  + '

'
	  + '

'
        + '
'
        + '

'
        + '

'
    },
    stateMap = {
      $container  : undefined,
      anchor_map  : {},
      resize_idto : undefined
    },
    jqueryMap = {},

    copyAnchorMap,    setJqueryMap,   changeAnchorPart,
    onResize,         onHashchange,   onTapList,
    onTapAcct,        onLogin,        onLogout,
    setChatAnchor,    initModule,     $activeDiv,
    $divToHide,	      cemValid,	      geoValid,
    markerValid,      pwiValid,	      swapDivs;
  //----------------- END MODULE SCOPE VARIABLES ---------------

  //------------------- BEGIN UTILITY METHODS ------------------
  // Returns copy of stored anchor map; minimizes overhead
  copyAnchorMap = function () {
    return $.extend( true, {}, stateMap.anchor_map );
  };
  //-------------------- END UTILITY METHODS -------------------

  //--------------------- BEGIN DOM METHODS --------------------
  // Begin DOM method /setJqueryMap/
  setJqueryMap = function () {
    var $container = stateMap.$container;

    // I added several valures here for divs I need to manipulate
    jqueryMap = {
      $container : $container,
      $acct      : $container.find('.cem-shell-head-acct'),
      $nav       : $container.find('.cem-shell-main-nav'),
      $cem	 : $container.find('.cem-shell-cem-content'),
      $pwi	 : $container.find('.cem-shell-plugin-content'),
      $geo	 : $container.find('.cem-shell-geo-content'),
      $marker	 : $container.find('.cem-shell-marker-content'),
      $menu	 : $container.find('.cem-shell-list-menu'),
      $footer 	 : $container.find('.cem-shell-foot')
    };
  };
  // End DOM method /setJqueryMap/

  // swapDivs: convenience function when switching screens
  swapDivs = function($newDiv) {
          if ( $activeDiv == $newDiv ) return;
          $divToHide = $activeDiv;
          $activeDiv = $newDiv;
          if (typeof($divToHide) != 'undefined') $divToHide.hide();
          $newDiv.show();
          return;
          }

  //--------------------- END DOM METHODS ----------------------

  //------------------- BEGIN EVENT HANDLERS -------------------

  // Begin Event handler /onResize/
  onResize = function () {
    if ( stateMap.resize_idto ) { return true; }

    stateMap.resize_idto = setTimeout(
      function () { stateMap.resize_idto = undefined; },
      configMap.resize_interval
    );

    return true;
  };
  // End Event handler /onResize/

  onTapAcct = function ( event ) {
      // React to mouse click w/temporary message
      jqueryMap.$acct.text( '... coming soon ...' );
      setTimeout(function(){
  	jqueryMap.$acct.text( 'Click to sign in' );
      },3000);
      return false;
  };

  // Event handler /onTapList/
  onTapList = function ( event ) {
    // React to taps on menu in nav div
    var menu_item  = $(this).data("id");
    // console.log('Tapped on ' + menu_item);
    switch(menu_item) {

	case 'cemetery':
	  swapDivs(jqueryMap.$cem);
          if (  cemValid  == false ) {
            cemValid = true;
	    jqueryMap.$cem.append(cem_form());
	    }
	  break;

	case 'geopoint':
	  swapDivs(jqueryMap.$geo);
          if ( geoValid == false || pwiValid == true ) {
            geoValid = true;
	    jqueryMap.$geo.empty();
            jqueryMap.$geo.append(geo_form(pwi.returnDataMap,'Marker'));
            }
	  break;

	case 'marker':
	  swapDivs(jqueryMap.$marker);
          if ( ! markerValid ) {
            markerValid = true;
            jqueryMap.$marker.append(marker_form());
            }
          break;

	case 'pwi':
	  swapDivs(jqueryMap.$pwi);
          if ( ! pwiValid ) {
            pwiValid = true;
            jqueryMap.$geo.append(pwi_form());
            }
          break;

	case 'pwi-get':
	  jqueryMap.$footer.empty();
	  jqueryMap.$footer.append(JSON.stringify(pwi.returnDataMap));
	  // console.log(JSON.stringify(pwi.returnDataMap));
	  break;
	case 'clear':
	  // Set everything back to starting state . .
	  cemValid = geoValid = markerValid = pwiValid = false;
	  jqueryMap.$footer.empty();
	  jqueryMap.$cem.empty();
	  jqueryMap.$geo.empty();
	  jqueryMap.$pwi.empty();
	  jqueryMap.$marker.empty();
	  $activeDiv.hide();
	  // Unset any lingering coordinates, too
	  if ( typeof(returnDataMap) == 'object')
	    delete pwi.returnDataMap['coordinates'];
	  break;
	}
    return false;
    };

  //-------------------- END EVENT HANDLERS --------------------

  //------------------- BEGIN PUBLIC METHODS -------------------
  // Begin Public method /initModule/
  // Example   : cem.shell.initModule( $('#app_div_id') );
  // Purpose   :
  //   Directs the Shell to offer its capability to the user
  // Arguments :
  //   * $container (example: $('#app_div_id')).
  //     A jQuery collection that should represent
  //     a single DOM container
  // Action    :
  //   Populates $container with the shell of the UI
  //   and then configures and initializes feature modules.
  //   The Shell is also responsible for browser-wide issues
  //   such as URI anchor and cookie management
  // Returns   : none
  // Throws    : none
  initModule = function ( $container ) {
    // load HTML and map jQuery collections
    stateMap.$container = $container;
    $container.html( configMap.main_html );
    setJqueryMap();
    jqueryMap.$cem.hide();
    jqueryMap.$geo.hide();
    jqueryMap.$marker.hide();
    jqueryMap.$pwi.hide();
    cemValid = geoValid = markerValid = pwiValid = false;
    // $.gevent.subscribe( $container, 'spa-login',  onLogin  );
    // $.gevent.subscribe( $container, 'spa-logout', onLogout );

    // Set up for user login
    jqueryMap.$acct
      .text( 'Click to sign in')
      .bind( 'click', onTapAcct );

    jqueryMap.$menu.bind( 'click', onTapList   );
    // configure and initialize feature modules
    // This is where the action will soon be
    // spa.input.initModule( jqueryMap.$container );

  // End PUBLIC method /initModule/
  };
  return { initModule : initModule };

  //------------------- END PUBLIC METHODS ---------------------
}());
<commit_msg>Insert scaffolding for client-side routing<commit_after>/*
 * cem.shell.js
 * Shell for Cemetery Project CMP343
*/

cem.shell = (function () {
  'use strict';
  //---------------- BEGIN MODULE SCOPE VARIABLES --------------
  var
    configMap = {
      anchor_schema_map : {
        chat  : { opened : true, closed : true }
      },
      resize_interval : 200,
      main_html : String()
        + '
'
          + '
'
            + '
CEM/SPA
'
            + '
The past is a gift to the future . .
'
          + '
'
          + '

'
        + '
'
        + '
'
	  // Display main menu; this needs to be done with code
          + '
'
	  + '
Temporary Menu:
'
	  + 'Test Director Router'
	  + '
'
          +  'Cemetery Data Input
'
          + '
'
          +  'Geolocation Point Data
'
	  +  '
'
	  +  'Marker Details
'
	  + '
'
	  +  ' PWI Plugin
'
	  +  '
'
	  +  'Show PWI Data
'
          + '
'
          +  'Clear All

'
          + '

'
	  + '

'
	  + '

'
	  + '

'
        + '
'
        + '

'
        + '

'
    },
    stateMap = {
      $container  : undefined,
      anchor_map  : {},
      resize_idto : undefined
    },
    jqueryMap = {},

    copyAnchorMap,    setJqueryMap,   changeAnchorPart,
    onResize,         onHashchange,   onTapList,
    onTapAcct,        onLogin,        onLogout,
    setChatAnchor,    initModule,     $activeDiv,
    $divToHide,	      cemValid,	      geoValid,
    markerValid,      pwiValid,	      routes,
    test, 	      router, 	      swapDivs;
  //----------------- END MODULE SCOPE VARIABLES ---------------

  //------------------- BEGIN UTILITY METHODS ------------------
  // Returns copy of stored anchor map; minimizes overhead
  copyAnchorMap = function () {
    return $.extend( true, {}, stateMap.anchor_map );
  };
  //-------------------- END UTILITY METHODS -------------------

  //--------------------- BEGIN DOM METHODS --------------------
  // Begin DOM method /setJqueryMap/
  setJqueryMap = function () {
    var $container = stateMap.$container;

    // I added several valures here for divs I need to manipulate
    jqueryMap = {
      $container : $container,
      $acct      : $container.find('.cem-shell-head-acct'),
      $nav       : $container.find('.cem-shell-main-nav'),
      $cem	 : $container.find('.cem-shell-cem-content'),
      $pwi	 : $container.find('.cem-shell-plugin-content'),
      $geo	 : $container.find('.cem-shell-geo-content'),
      $marker	 : $container.find('.cem-shell-marker-content'),
      $menu	 : $container.find('.cem-shell-list-menu'),
      $footer 	 : $container.find('.cem-shell-foot')
    };
  };
  // End DOM method /setJqueryMap/

  // swapDivs: convenience function when switching screens
  swapDivs = function($newDiv) {
          if ( $activeDiv == $newDiv ) return;
          $divToHide = $activeDiv;
          $activeDiv = $newDiv;
          if (typeof($divToHide) != 'undefined') $divToHide.hide();
          $newDiv.show();
          return;
          }
  // route stuff
  test = function () {console.log('We are OK!'); };

  routes = {
	'test': test };

  //--------------------- END DOM METHODS ----------------------

  //------------------- BEGIN EVENT HANDLERS -------------------

  // Begin Event handler /onResize/
  onResize = function () {
    if ( stateMap.resize_idto ) { return true; }

    stateMap.resize_idto = setTimeout(
      function () { stateMap.resize_idto = undefined; },
      configMap.resize_interval
    );

    return true;
  };
  // End Event handler /onResize/

  onTapAcct = function ( event ) {
      // React to mouse click w/temporary message
      jqueryMap.$acct.text( '... coming soon ...' );
      setTimeout(function(){
  	jqueryMap.$acct.text( 'Click to sign in' );
      },3000);
      return false;
  };

  // Event handler /onTapList/
  onTapList = function ( event ) {
    // React to taps on menu in nav div
    var menu_item  = $(this).data("id");
    // console.log('Tapped on ' + menu_item);
    switch(menu_item) {

	case 'cemetery':
	  swapDivs(jqueryMap.$cem);
          if (  cemValid  == false ) {
            cemValid = true;
	    jqueryMap.$cem.append(cem_form());
	    }
	  break;

	case 'geopoint':
	  swapDivs(jqueryMap.$geo);
          if ( geoValid == false || pwiValid == true ) {
            geoValid = true;
	    jqueryMap.$geo.empty();
            jqueryMap.$geo.append(geo_form(pwi.returnDataMap,'Marker'));
            }
	  break;

	case 'marker':
	  swapDivs(jqueryMap.$marker);
          if ( ! markerValid ) {
            markerValid = true;
            jqueryMap.$marker.append(marker_form());
            }
          break;

	case 'pwi':
	  swapDivs(jqueryMap.$pwi);
          if ( ! pwiValid ) {
            pwiValid = true;
            jqueryMap.$geo.append(pwi_form());
            }
          break;

	case 'pwi-get':
	  jqueryMap.$footer.empty();
	  jqueryMap.$footer.append(JSON.stringify(pwi.returnDataMap));
	  // console.log(JSON.stringify(pwi.returnDataMap));
	  break;
	case 'clear':
	  // Set everything back to starting state . .
	  cemValid = geoValid = markerValid = pwiValid = false;
	  jqueryMap.$footer.empty();
	  jqueryMap.$cem.empty();
	  jqueryMap.$geo.empty();
	  jqueryMap.$pwi.empty();
	  jqueryMap.$marker.empty();
	  $activeDiv.hide();
	  // Unset any lingering coordinates, too
	  if ( typeof(returnDataMap) == 'object')
	    delete pwi.returnDataMap['coordinates'];
	  break;
	}
    return false;
    };

  //-------------------- END EVENT HANDLERS --------------------

  //------------------- BEGIN PUBLIC METHODS -------------------
  // Begin Public method /initModule/
  // Example   : cem.shell.initModule( $('#app_div_id') );
  // Purpose   :
  //   Directs the Shell to offer its capability to the user
  // Arguments :
  //   * $container (example: $('#app_div_id')).
  //     A jQuery collection that should represent
  //     a single DOM container
  // Action    :
  //   Populates $container with the shell of the UI
  //   and then configures and initializes feature modules.
  //   The Shell is also responsible for browser-wide issues
  //   such as URI anchor and cookie management
  // Returns   : none
  // Throws    : none
  initModule = function ( $container ) {
    // load HTML and map jQuery collections
    stateMap.$container = $container;
    $container.html( configMap.main_html );
    setJqueryMap();
    jqueryMap.$cem.hide();
    jqueryMap.$geo.hide();
    jqueryMap.$marker.hide();
    jqueryMap.$pwi.hide();
    cemValid = geoValid = markerValid = pwiValid = false;

    // Can we do the routing this easily?
    router = Router(routes);
    router.init();
    // $.gevent.subscribe( $container, 'spa-login',  onLogin  );
    // $.gevent.subscribe( $container, 'spa-logout', onLogout );

    // Set up for user login
    jqueryMap.$acct
      .text( 'Click to sign in')
      .bind( 'click', onTapAcct );

    jqueryMap.$menu.bind( 'click', onTapList   );
    // configure and initialize feature modules
    // This is where the action will soon be
    // spa.input.initModule( jqueryMap.$container );

  // End PUBLIC method /initModule/
  };
  return { initModule : initModule };

  //------------------- END PUBLIC METHODS ---------------------
}());
<|endoftext|>


<commit_before>var vid = document.getElementById('videoel');
var overlay = document.getElementById('overlay');
var overlayCC = overlay.getContext('2d');

var ctrack = new clm.tracker({useWebGL : true});
ctrack.init(pModel);

stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.getElementById('container').appendChild( stats.domElement );

function enablestart() {
	var startbutton = document.getElementById('startbutton');
	startbutton.value = "start";
	startbutton.disabled = null;
}

var insertAltVideo = function(video) {
	if (supports_video()) {
		if (supports_ogg_theora_video()) {
			video.src = "./media/cap12_edit.ogv";
		} else if (supports_h264_baseline_video()) {
			video.src = "./media/cap12_edit.mp4";
		} else {
			return false;
		}
		//video.play();
		return true;
	} else return false;
}
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL || window.msURL || window.mozURL;

// check for camerasupport
if (navigator.getUserMedia) {
	// set up stream

	var videoSelector = {video : true};
	if (window.navigator.appVersion.match(/Chrome\/(.*?) /)) {
		var chromeVersion = parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10);
		if (chromeVersion < 20) {
			videoSelector = "video";
		}
	};

	navigator.getUserMedia(videoSelector, function( stream ) {
		if (vid.mozCaptureStream) {
			vid.mozSrcObject = stream;
		} else {
			vid.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
		}
		vid.play();
	}, function() {
			 insertAltVideo(vid);
			 document.getElementById('gum').className = "hide";
			 document.getElementById('nogum').className = "nohide";
			 alert("There was some problem trying to fetch video from your webcam, using a fallback video instead.");
		 });
} else {
	insertAltVideo(vid);
	document.getElementById('gum').className = "hide";
	document.getElementById('nogum').className = "nohide";
	alert("Your browser does not seem to support getUserMedia, using a fallback video instead.");
}

vid.addEventListener('canplay', enablestart, false);

function startVideo() {
	// start video
	vid.play();
	// start tracking
	ctrack.start(vid);
	// start loop to draw face
	drawLoop();
}

var calibrateModeOn = false; //determine if calibrating or testing
var calibratedInstances = [];
var scale = 1;
var paths = []; //paths[frame number][point][x or y]
var closedTimer = 0;
var spokenTimer = 0;
var prevIsOpen = false;
var CLOSED_LIMIT = 25*1; //1 "second" worth of frames
var SPOKEN_LIMIT = 25*.6;
var MIN_PATHS_LENGTH = 25;
function drawLoop() {
  requestAnimFrame(drawLoop);
	overlayCC.clearRect(0, 0, 400, 300);
	// //psrElement.innerHTML = "score :" + ctrack.getScore().toFixed(4);
	// if (ctrack.getCurrentPosition()) {
	// 	ctrack.draw(overlay);
	// }
  var currPos = ctrack.getCurrentPosition()
	if (currPos) {
		drawLips(overlay, currPos);
		displayPoints(currPos);

		if(!calibrateModeOn)
		{
			//calculate a new scaling factor

		}

		if(paths.length < MIN_PATHS_LENGTH || spokenTimer > 0) //fill to 25 or currently speaking
			addPoints(paths, currPos);
		else //more than 25 frames
		{
			while(paths.length >= MIN_PATHS_LENGTH)
				paths.shift() //get rid of oldest by removing from front
			addPoints(paths, currPos); //insert newest frame
		}
		document.getElementById('message').innerHTML = paths.length;

		var isOpen = getMouthDistances(currPos);

		if(isOpen) //currently speaking, increment
		{
			spokenTimer++;
			if(prevIsOpen == false) //went from closed to open
				spokenTimer += closedTimer; //b/c closed interval counts as speaking

			closedTimer = 0;
		}
		if(prevIsOpen == true && isOpen == false) //goes from open to closed
		{
			//increment both timers
			spokenTimer++; //could possibly still be speaking, increment
			closedTimer++; //mouth is closed, so increment
		}
		else if(isOpen == false && closedTimer > 0) //mouth is closed and closedTimer has begun
		{
			if(closedTimer < CLOSED_LIMIT)
				closedTimer++;
			else //reached threshold of closedTimer, assume mouth is closed indefinitely now
			{
				//code executes when user finishes speaking!
				if(spokenTimer > SPOKEN_LIMIT)
				{
					var pathStr = document.getElementById('paths');
					pathStr.innerHTML = "";
					for(var i = 0; i < paths[0].length; i++) //first frame, 18 points
					{
						pathStr.innerHTML += "Point " + i + ": " + ptToString(paths[0][i][0], paths[0][i][1]);
					}

					//deep copy of paths
					var pathsCopy = [];
					while(paths.length > 0)
						pathsCopy.push(paths.shift());

					if(calibrateModeOn) //calibration mode
					{
						recordNoseLength(currPos);

						var inputWord = prompt("What word spoken?");
						askSaveCalibrationMatrix(inputWord, pathsCopy);
					}
					else //testing mode
					{
						getBestWord(pathsCopy);
					}
				}
				closedTimer = spokenTimer = 0;
			}

		}

		prevIsOpen = isOpen;
		document.getElementById('spokenTimer').innerHTML = spokenTimer + "
";
		document.getElementById('closedTimer').innerHTML = closedTimer + "
";
	}
}

// update stats on every iteration
document.addEventListener('clmtrackrIteration', function(event) {
	stats.update();
}, false);
<commit_msg>Changed startVideo() to load noseLength variable before starting loop. Less hacky than immediately retrieving from database as soon as page loaded. Also cleaned up some unused commented-out code.<commit_after>var vid = document.getElementById('videoel');
var overlay = document.getElementById('overlay');
var overlayCC = overlay.getContext('2d');

var ctrack = new clm.tracker({useWebGL : true});
ctrack.init(pModel);

stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.getElementById('container').appendChild( stats.domElement );

function enablestart() {
	var startbutton = document.getElementById('startbutton');
	startbutton.value = "start";
	startbutton.disabled = null;
}

var insertAltVideo = function(video) {
	if (supports_video()) {
		if (supports_ogg_theora_video()) {
			video.src = "./media/cap12_edit.ogv";
		} else if (supports_h264_baseline_video()) {
			video.src = "./media/cap12_edit.mp4";
		} else {
			return false;
		}
		//video.play();
		return true;
	} else return false;
}
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
window.URL = window.URL || window.webkitURL || window.msURL || window.mozURL;

// check for camerasupport
if (navigator.getUserMedia) {
	// set up stream

	var videoSelector = {video : true};
	if (window.navigator.appVersion.match(/Chrome\/(.*?) /)) {
		var chromeVersion = parseInt(window.navigator.appVersion.match(/Chrome\/(\d+)\./)[1], 10);
		if (chromeVersion < 20) {
			videoSelector = "video";
		}
	};

	navigator.getUserMedia(videoSelector, function( stream ) {
		if (vid.mozCaptureStream) {
			vid.mozSrcObject = stream;
		} else {
			vid.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
		}
		vid.play();
	}, function() {
			 insertAltVideo(vid);
			 document.getElementById('gum').className = "hide";
			 document.getElementById('nogum').className = "nohide";
			 alert("There was some problem trying to fetch video from your webcam, using a fallback video instead.");
		 });
} else {
	insertAltVideo(vid);
	document.getElementById('gum').className = "hide";
	document.getElementById('nogum').className = "nohide";
	alert("Your browser does not seem to support getUserMedia, using a fallback video instead.");
}

vid.addEventListener('canplay', enablestart, false);

var noseLength;
function startVideo() {
	//load nose length first
	firebase.child("noseLength").on("value", function(snapshot) {
	  	noseLength = snapshot.val();

		// start video
		vid.play();
		// start tracking
		ctrack.start(vid);
		// start loop to draw face
		drawLoop();
	});
}

var calibrateModeOn = false; //determine if calibrating or testing
var calibratedInstances = [];
var scale = 1;
var paths = []; //paths[frame number][point][x or y]
var closedTimer = 0;
var spokenTimer = 0;
var prevIsOpen = false;
var CLOSED_LIMIT = 25*1; //1 "second" worth of frames
var SPOKEN_LIMIT = 25*.6;
var MIN_PATHS_LENGTH = 25;
function drawLoop() {
  requestAnimFrame(drawLoop);
	overlayCC.clearRect(0, 0, 400, 300);

  var currPos = ctrack.getCurrentPosition()
	if (currPos) {
		drawLips(overlay, currPos);
		displayPoints(currPos);

		if(paths.length < MIN_PATHS_LENGTH || spokenTimer > 0) //fill to 25 or currently speaking
			addPoints(paths, currPos);
		else //more than 25 frames
		{
			while(paths.length >= MIN_PATHS_LENGTH)
				paths.shift() //get rid of oldest by removing from front
			addPoints(paths, currPos); //insert newest frame
		}
		document.getElementById('message').innerHTML = paths.length;

		var isOpen = getMouthDistances(currPos);

		if(isOpen) //currently speaking, increment
		{
			spokenTimer++;
			if(prevIsOpen == false) //went from closed to open
				spokenTimer += closedTimer; //b/c closed interval counts as speaking

			closedTimer = 0;
		}
		if(prevIsOpen == true && isOpen == false) //goes from open to closed
		{
			//increment both timers
			spokenTimer++; //could possibly still be speaking, increment
			closedTimer++; //mouth is closed, so increment
		}
		else if(isOpen == false && closedTimer > 0) //mouth is closed and closedTimer has begun
		{
			if(closedTimer < CLOSED_LIMIT)
				closedTimer++;
			else //reached threshold of closedTimer, assume mouth is closed indefinitely now
			{
				//code executes when user finishes speaking!
				if(spokenTimer > SPOKEN_LIMIT)
				{
					var pathStr = document.getElementById('paths');
					pathStr.innerHTML = "";
					for(var i = 0; i < paths[0].length; i++) //first frame, 18 points
					{
						pathStr.innerHTML += "Point " + i + ": " + ptToString(paths[0][i][0], paths[0][i][1]);
					}

					//deep copy of paths
					var pathsCopy = [];
					while(paths.length > 0)
						pathsCopy.push(paths.shift());

					if(calibrateModeOn) //calibration mode
					{
						var inputWord = prompt("What word spoken?");
						askSaveCalibrationMatrix(inputWord, pathsCopy);
					}
					else //testing mode
					{
						console.log("displaying");
						getBestWord(pathsCopy);
					}
				}
				closedTimer = spokenTimer = 0;
			}

		}

		prevIsOpen = isOpen;
		document.getElementById('spokenTimer').innerHTML = spokenTimer + "
";
		document.getElementById('closedTimer').innerHTML = closedTimer + "
";
	}
}

// update stats on every iteration
document.addEventListener('clmtrackrIteration', function(event) {
	stats.update();
}, false);
<|endoftext|>


<commit_before>var DEBUG = 0;

// AJAX setup
var AJAX_SETUP = {
	timeout: 9000,
	cache: false, // this little sentence killed a lot of little bugs that was actually one big bug
}

// Loops & intervals
var BACKGROUND_LOOP = 30000; // 30s
var BACKGROUND_LOOP_OFFLINE = 3000; // 3s, respond quickly when we get back online
var PAGE_LOOP = 10000; // 10s

// Update stuff at every X intervals
var UPDATE_OFFICE_INTERVAL = 1; // recommended: 1
var UPDATE_SERVANT_INTERVAL = 20; // recommended: 20
var UPDATE_MEETINGS_INTERVAL = 20; // recommended: 20
var UPDATE_COFFEE_INTERVAL = 1; // recommended: 1
var UPDATE_HOURS_INTERVAL = 60; // recommended: 60
var UPDATE_CANTINAS_INTERVAL = 60; // recommended: 60
var UPDATE_BUS_INTERVAL = 2; // recommended: 1
var UPDATE_NEWS_INTERVAL = 20; // recommended: 20

// Meme detection
var urlExists = function(url) {
	try {
	    var http = new XMLHttpRequest();
	    http.open('HEAD', url, false);
	    http.send();
	    return http.status!=404;
	}
	catch (e) {
		// do nothing
	}
	finally {
		return false;
	}
}
var MEME_AMOUNT = 0;
var __counter__ = 1;
while (urlExists('meme/'+__counter__+'.jpg')) {
	MEME_AMOUNT++;
	__counter__++;
}

// OS detection
var OPERATING_SYSTEM = "Unknown";
if (navigator.appVersion.indexOf("Win")!==-1) OPERATING_SYSTEM="Windows";
else if (navigator.appVersion.indexOf("Linux")!==-1) OPERATING_SYSTEM="Linux";
else if (navigator.appVersion.indexOf("X11")!==-1) OPERATING_SYSTEM="UNIX";
else if (navigator.appVersion.indexOf("Mac")!==-1) {
	OPERATING_SYSTEM = "Old Mac";
	if (navigator.appVersion.indexOf("10_7")!==-1||navigator.appVersion.indexOf("10_8")!==-1) {
		OPERATING_SYSTEM = "Mac";
	}
}
else {
	console.log('WARNING: Potentially unsupported operating system');
}

// Browser detection
var BROWSER = "Unknown";
if (navigator.userAgent.indexOf('Chrome') != -1 && navigator.userAgent.indexOf('OPR') == -1)
	BROWSER = "Chrome";
else if (navigator.userAgent.indexOf('OPR') != -1)
	BROWSER = "Opera";
else
	console.log('WARNING: Potentially unsupported browser');

// Production detection
if (BROWSER == 'Chrome')
	if (typeof chrome.i18n != 'undefined')
		if (chrome.i18n.getMessage('@@extension_id') === 'hfgffimlnajpbenfpaofmmffcdmgkllf')
			DEBUG = 0;
else if (BROWSER == 'Opera')
	if (typeof chrome.i18n != 'undefined')
		if (chrome.i18n.getMessage('@@extension_id') === 'npnpbddfcaibgnegafofkmffmbmflelj')
			DEBUG = 0;
<commit_msg>constants: turned debug back on<commit_after>var DEBUG = 1;

// AJAX setup
var AJAX_SETUP = {
	timeout: 9000,
	cache: false, // this little sentence killed a lot of little bugs that was actually one big bug
}

// Loops & intervals
var BACKGROUND_LOOP = 30000; // 30s
var BACKGROUND_LOOP_OFFLINE = 3000; // 3s, respond quickly when we get back online
var PAGE_LOOP = 10000; // 10s

// Update stuff at every X intervals
var UPDATE_OFFICE_INTERVAL = 1; // recommended: 1
var UPDATE_SERVANT_INTERVAL = 20; // recommended: 20
var UPDATE_MEETINGS_INTERVAL = 20; // recommended: 20
var UPDATE_COFFEE_INTERVAL = 1; // recommended: 1
var UPDATE_HOURS_INTERVAL = 60; // recommended: 60
var UPDATE_CANTINAS_INTERVAL = 60; // recommended: 60
var UPDATE_BUS_INTERVAL = 2; // recommended: 1
var UPDATE_NEWS_INTERVAL = 20; // recommended: 20

// Meme detection
var urlExists = function(url) {
	try {
	    var http = new XMLHttpRequest();
	    http.open('HEAD', url, false);
	    http.send();
	    return http.status!=404;
	}
	catch (e) {
		// do nothing
	}
	finally {
		return false;
	}
}
var MEME_AMOUNT = 0;
var __counter__ = 1;
while (urlExists('meme/'+__counter__+'.jpg')) {
	MEME_AMOUNT++;
	__counter__++;
}

// OS detection
var OPERATING_SYSTEM = "Unknown";
if (navigator.appVersion.indexOf("Win")!==-1) OPERATING_SYSTEM="Windows";
else if (navigator.appVersion.indexOf("Linux")!==-1) OPERATING_SYSTEM="Linux";
else if (navigator.appVersion.indexOf("X11")!==-1) OPERATING_SYSTEM="UNIX";
else if (navigator.appVersion.indexOf("Mac")!==-1) {
	OPERATING_SYSTEM = "Old Mac";
	if (navigator.appVersion.indexOf("10_7")!==-1||navigator.appVersion.indexOf("10_8")!==-1) {
		OPERATING_SYSTEM = "Mac";
	}
}
else {
	console.log('WARNING: Potentially unsupported operating system');
}

// Browser detection
var BROWSER = "Unknown";
if (navigator.userAgent.indexOf('Chrome') != -1 && navigator.userAgent.indexOf('OPR') == -1)
	BROWSER = "Chrome";
else if (navigator.userAgent.indexOf('OPR') != -1)
	BROWSER = "Opera";
else
	console.log('WARNING: Potentially unsupported browser');

// Production detection
if (BROWSER == 'Chrome')
	if (typeof chrome.i18n != 'undefined')
		if (chrome.i18n.getMessage('@@extension_id') === 'hfgffimlnajpbenfpaofmmffcdmgkllf')
			DEBUG = 0;
else if (BROWSER == 'Opera')
	if (typeof chrome.i18n != 'undefined')
		if (chrome.i18n.getMessage('@@extension_id') === 'npnpbddfcaibgnegafofkmffmbmflelj')
			DEBUG = 0;
<|endoftext|>


<commit_before><commit_msg>fix(converter): add missing conversion<commit_after><|endoftext|>