<commit_before>var net = require('net');
var sprintf = require('sprintf').sprintf;
var fs = require('fs');
var crypto = require('crypto');

var args = process.argv.slice(2);

var client = new net.Socket();
var first = true;
var name = args[0] || "minion";
var registrationStr = sprintf("robot|%s", name);

// Pull in the private key for the specific robot
var privateKeyFile = "./" + name + "_private.pem";
var privateKeyData = null;
fs.readFile(privateKeyFile, 'ascii', function(err, data) {
    if (err) {
      return console.log(err);
    }
    privateKeyData = data;
});

// Pull in the public key for the telep server
var publicKeyFile = "./telep_public.pem";
var publicKeyData = null;
fs.readFile(publicKeyFile, 'ascii', function(err, data) {
    if (err) {
      return console.log(err);
    }
    publicKeyData = data;
});

function verifyServerMessage(data) {
  var cmps = data.split('|');
  var message = cmps[0];
  var signature = cmps[1];
  var verifier = crypto.createVerify('RSA-SHA256');
  verifier.update(message);
  if (verifier.verify(publicKeyData, signature, 'base64')) {
    return message;
  } else {
    return null;
  }
}

function signMessage(message) {
  var signer = crypto.createSign('RSA-SHA256');
  signer.update(message);
  var signature = signer.sign(privateKeyData, 'base64');
  return signature + "|" + message;
}

client.connect(5555, 'daneel', function() {
    console.log('Connected');
});

client.on('data', function(data) {
    var message = verifyServerMessage(data);
    if (message) {
      console.log('Data: ' + message);
      if (first) {
        client.write(signMessage(registrationStr));
        // client.write(sprintf("%c%s", registrationStr.length, registrationStr));
        first = false;
      }
    } else {
      console.log("Invalid message from server: " + data);
    }
    // client.destroy();
});

client.on('close', function(data) {
    console.log('Connection closed');
});
<commit_msg>Tweaked the client for the signature stuff.<commit_after>var net = require('net');
var sprintf = require('sprintf').sprintf;
var fs = require('fs');
var crypto = require('crypto');

var args = process.argv.slice(2);

var client = new net.Socket();
var first = true;
var name = args[0] || "minion";
var registrationStr = sprintf("robot|%s", name);

// Pull in the private key for the specific robot
var privateKeyFile = "./" + name + "_private.pem";
var privateKeyData = null;
fs.readFile(privateKeyFile, 'ascii', function(err, data) {
    if (err) {
      return console.log(err);
    }
    privateKeyData = data;
});

// Pull in the public key for the telep server
var publicKeyFile = "./telep_public.pem";
var publicKeyData = null;
fs.readFile(publicKeyFile, 'ascii', function(err, data) {
    if (err) {
      return console.log(err);
    }
    publicKeyData = data;
});

function verifyServerMessage(data) {
  var msg = data.toString();
  console.log(msg);
  var cmps = msg.split('|');
  var message = cmps[0];
  var signature = cmps[1];
  var verifier = crypto.createVerify('RSA-SHA256');
  verifier.update(message);
  if (verifier.verify(publicKeyData, signature, 'base64')) {
    return message;
  } else {
    return null;
  }
}

function signMessage(message) {
  var signer = crypto.createSign('RSA-SHA256');
  signer.update(message);
  var signature = signer.sign(privateKeyData, 'base64');
  var signedMessage = message + "|" + signature;
  console.log(signedMessage);
  return signedMessage;
}

client.connect(5555, 'daneel', function() {
    console.log('Connected');
});

client.on('data', function(data) {
    var message = verifyServerMessage(data);
    if (message) {
      console.log('Data: ' + message);
      if (first) {
        client.write(signMessage(registrationStr));
        // client.write(sprintf("%c%s", registrationStr.length, registrationStr));
        first = false;
      }
    } else {
      console.log("Invalid message from server: " + data);
    }
    // client.destroy();
});

client.on('close', function(data) {
    console.log('Connection closed');
});
<|endoftext|>


<commit_before>/* global THREE, CANNON */
module.exports = ( function () {
    "use strict";

    const DEADZONE = 0.145;

    var gamepads;
    var buttonsPresseds = [];
    var gamepadCommands = [];
    var xboxGamepads = [];
    var vrGamepads = [];
    var viveMeshA = new THREE.Mesh(new THREE.BoxBufferGeometry(0.06, 0.06, 0.13), new THREE.MeshLambertMaterial({color: 0xff2222}));
    var viveMeshB = new THREE.Mesh(new THREE.BoxBufferGeometry(0.06, 0.06, 0.13), new THREE.MeshLambertMaterial({color: 0x22ff22}));
    viveMeshA.matrixAutoUpdate = false;
    viveMeshB.matrixAutoUpdate = false;
    var vrGamepadMeshes = [viveMeshA, viveMeshB];

    const DEFAULT_OPTIONS = {
        toolLength: 0.15,
        toolRadius: 0.0034,
        tipLength: 0.15,
        tipRadius: 0.0034,
        toolMass: 0.04,
        toolColor: 0xeebb99,
        tipColor: 0x99bbee,
        tipMaterial: new CANNON.Material(),
        useShadowMesh: true,
        shadowMaterial: new THREE.MeshBasicMaterial({color: 0x212121}),
        shadowLightPosition: new THREE.Vector4(0, 8, 3, 0.1),
        shadowPlane: 0.002
    };
    function makeTool(vrGamepad, options) {
        var _options = {};
        options = options || _options;
        for (var kwarg in options) {
            _options[kwarg] = options[kwarg];
        }
        for (kwarg in DEFAULT_OPTIONS) {
            if (_options[kwarg] === undefined) _options[kwarg] = DEFAULT_OPTIONS[kwarg];
        }
        options = _options;
        console.log('OpenVR tool options, gamepad %d:', vrGamepad.index);
        console.log(options);

        var toolGeom = new THREE.CylinderGeometry(options.toolRadius, options.toolRadius, options.toolLength, 10, 1, false);
        toolGeom.translate(0, -0.5 * options.toolLength, 0);
        toolGeom.rotateX(-0.5 * Math.PI);
        var bufferGeom = new THREE.BufferGeometry();
        bufferGeom.fromGeometry(toolGeom);
        toolGeom.dispose();
        toolGeom = bufferGeom;
        var toolMaterial = new THREE.MeshLambertMaterial({color: options.toolColor, transparent: true});
        var toolMesh = new THREE.Mesh(toolGeom, toolMaterial);

        var toolShadowMesh;
        if (options.useShadowMesh) {
            toolShadowMesh = new THREE.ShadowMesh(toolMesh, options.shadowMaterial);
            var shadowPlane = new THREE.Plane(THREE.Object3D.DefaultUp, options.shadowPlane);
            toolShadowMesh.updateShadowMatrix(shadowPlane, options.shadowLightPosition);
        } else {
            toolMesh.castShadow = true;
        }

        var toolBody = new CANNON.Body({mass: options.toolMass, type: CANNON.Body.KINEMATIC});
        toolBody.material = options.tipMaterial;
        toolBody.addShape(new CANNON.Cylinder(options.tipRadius, options.tipRadius, options.tipLength, 8),
            new CANNON.Vec3(0, 0, 0.5 * options.tipLength));

        var position = new THREE.Vector3();
        var velocity = new THREE.Vector3();
        var quaternion = new THREE.Quaternion();
        var worldPosition = new THREE.Vector3();
        var worldQuaternion = new THREE.Quaternion();
        var worldScale = new THREE.Vector3();

        function update(dt) {
            if (vrGamepad && vrGamepad.pose) {
                toolMesh.position.fromArray(vrGamepad.pose.position);
                toolMesh.quaternion.fromArray(vrGamepad.pose.orientation);
                position.copy(toolMesh.position);
                velocity.copy(toolBody.interpolatedPosition);
                var parent = toolMesh.parent;
                if (parent) {
                    parent.updateMatrix();
                    parent.updateMatrixWorld();
                    parent.matrixWorld.decompose(worldPosition, worldQuaternion, worldScale);
                    position.applyMatrix4(parent.matrixWorld);
                    quaternion.multiplyQuaternions(worldQuaternion, toolMesh.quaternion);
                    toolBody.position.copy(position);
                    toolBody.quaternion.copy(quaternion);
                    velocity.sub(position);
                    velocity.multiplyScalar(-1 / dt);
                    toolBody.velocity.copy(velocity);
                }
            } else {
                toolBody.sleep();
            }
            toolMesh.updateMatrix();
            if (toolShadowMesh) toolShadowMesh.updateMatrix();
            toolMesh.updateMatrixWorld();
        }
        return {
            body: toolBody,
            mesh: toolMesh,
            update: update
        };
    }

    function pollGamepads() {
        gamepads = navigator.getGamepads();
        for (var i = 0; i < gamepads.length; i++) {
            var gamepad = gamepads[i];
            if (!gamepad) continue;
            if (buttonsPresseds[i] === undefined) {
                console.log('new gamepad: %s', gamepad.id);
                if (/openvr/i.test(gamepad.id)) {
                    vrGamepads.push(gamepad);
                } else if (/xbox/i.test(gamepad.id) || /xinput/i.test(gamepad.id)) {
                    xboxGamepads.push(gamepad);
                }
                buttonsPresseds[i] = [];
                for (var j = 0; j < gamepad.buttons.length; j++) {
                    buttonsPresseds[i].push(false);
                }
                onGamepadConnected({gamepad: gamepad});
            }
        }
    }

    function setGamepadCommands(index, commands) {
        gamepadCommands[index] = commands;
    }

    var _onGamepadConnected = null;

    function setOnGamepadConnected(onGamepadConnected) {
        _onGamepadConnected = onGamepadConnected;
    }

    function onGamepadConnected(e) {
        console.log("Gamepad connected at index %d: %s - %d buttons, %d axes", e.gamepad.index, e.gamepad.id, e.gamepad.buttons.length, e.gamepad.axes.length);
        if (_onGamepadConnected) {
            _onGamepadConnected(e);
        }
    }
    window.addEventListener("gamepadconnected", onGamepadConnected);

    function onGamepadDisconnected(e) {
        console.log("Gamepad disconnected from index %d: %s", e.gamepad.index, e.gamepad.id);
        var i = e.gamepad.index;
        for (var j = 0; j < buttonsPresseds[i].length; j++) {
            buttonsPresseds[i][j] = false;
        }
    }
    window.addEventListener("gamepaddisconnected", onGamepadDisconnected);

    function update() {
        var values = [];
        pollGamepads();
        for (var i = 0; i < gamepads.length; ++i) {
            var gamepad = gamepads[i];
            if (!gamepad) continue;
            var buttonsPressed = buttonsPresseds[i];
            var commands = gamepadCommands[i] || {};
            // get all button/axes values:
            var axesValues = {};
            for (var name in commands) {
                axesValues[name] = 0;
                var command = commands[name];
                if (command.axes) {
                    for (var j = 0; j < gamepad.axes.length; j++) {
                        var axis = gamepad.axes[j];
                        if (Math.abs(axis) > DEADZONE) {
                            if (command.axes.indexOf(j) !== -1) {
                                axesValues[name] = gamepad.axes[j];
                                if (command.flipAxes) {
                                    axesValues[name] *= -1;
                                }
                                break;
                            }
                        }
                    }
                } else if (command.buttons) {
                    for (j = 0; j < command.buttons.length; j++) {
                        if (gamepad.buttons[command.buttons[j]] && gamepad.buttons[command.buttons[j]].pressed) {
                            axesValues[name] = 1;
                            break;
                        }
                    }
                }
            }
            values.push(axesValues);
            for (j = 0; j < gamepad.buttons.length; j++) {
                if (gamepad.buttons[j]) {
                    if (gamepad.buttons[j].pressed && !buttonsPressed[j]) {
                        buttonsPressed[j] = true;
                        for (name in commands) {
                            command = commands[name];
                            if (command.commandDown && command.buttons && command.buttons.indexOf(j) !== -1) {
                                command.commandDown(j, gamepad.axes);
                            }
                        }
                    } else if (!gamepad.buttons[j].pressed && buttonsPressed[j]) {
                        buttonsPressed[j] = false;
                        for (name in commands) {
                            command = commands[name];
                            if (command.commandUp && command.buttons && command.buttons.indexOf(j) !== -1) {
                                command.commandUp(j, gamepad.axes);
                            }
                        }
                    }
                }
            }
        }
        return values;
    }

    pollGamepads();

    return {
        BUTTONS: {
            A: 0,
            B: 1,
            X: 2,
            Y: 3,
            leftBumper: 4,
            rightBumper: 5,
            leftTrigger: 6,
            rightTrigger: 7,
            back: 8,
            start: 9,
            leftStick: 10,
            rightStick: 11,
            up: 12,
            down: 13,
            left: 14,
            right: 15
        },
        AXES: {
            LSX: 0,
            LSY: 1,
            RSX: 2,
            RSY: 3
        },
        viveMeshA: viveMeshA,
        viveMeshB: viveMeshB,
        vrGamepadMeshes: vrGamepadMeshes,
        setGamepadCommands: setGamepadCommands,
        setOnGamepadConnected: setOnGamepadConnected,
        update: update,
        makeTool: makeTool,
        vrGamepads: vrGamepads,
        xboxGamepads: xboxGamepads
    };

} )();
<commit_msg>openvr tool shadow mesh<commit_after>/* global THREE, CANNON */
module.exports = ( function () {
    "use strict";

    const DEADZONE = 0.145;

    var gamepads;
    var buttonsPresseds = [];
    var gamepadCommands = [];
    var xboxGamepads = [];
    var vrGamepads = [];
    var viveMeshA = new THREE.Mesh(new THREE.BoxBufferGeometry(0.06, 0.06, 0.13), new THREE.MeshLambertMaterial({color: 0xff2222}));
    var viveMeshB = new THREE.Mesh(new THREE.BoxBufferGeometry(0.06, 0.06, 0.13), new THREE.MeshLambertMaterial({color: 0x22ff22}));
    viveMeshA.matrixAutoUpdate = false;
    viveMeshB.matrixAutoUpdate = false;
    var vrGamepadMeshes = [viveMeshA, viveMeshB];

    const DEFAULT_OPTIONS = {
        toolLength: 0.15,
        toolRadius: 0.0034,
        tipLength: 0.15,
        tipRadius: 0.0034,
        toolMass: 0.04,
        toolColor: 0xeebb99,
        tipColor: 0x99bbee,
        tipMaterial: new CANNON.Material(),
        useShadowMesh: true,
        shadowMaterial: new THREE.MeshBasicMaterial({color: 0x212121}),
        shadowLightPosition: new THREE.Vector4(0, 8, 3, 0.1),
        shadowPlane: 0.002
    };
    function makeTool(vrGamepad, options) {
        var _options = {};
        options = options || _options;
        for (var kwarg in options) {
            _options[kwarg] = options[kwarg];
        }
        for (kwarg in DEFAULT_OPTIONS) {
            if (_options[kwarg] === undefined) _options[kwarg] = DEFAULT_OPTIONS[kwarg];
        }
        options = _options;
        console.log('OpenVR tool options, gamepad %d:', vrGamepad.index);
        console.log(options);

        var toolGeom = new THREE.CylinderGeometry(options.toolRadius, options.toolRadius, options.toolLength, 10, 1, false);
        toolGeom.translate(0, -0.5 * options.toolLength, 0);
        toolGeom.rotateX(-0.5 * Math.PI);
        var bufferGeom = new THREE.BufferGeometry();
        bufferGeom.fromGeometry(toolGeom);
        toolGeom.dispose();
        toolGeom = bufferGeom;
        var toolMaterial = new THREE.MeshLambertMaterial({color: options.toolColor, transparent: true});
        var toolMesh = new THREE.Mesh(toolGeom, toolMaterial);

        var toolShadowMesh;
        if (options.useShadowMesh) {
            toolShadowMesh = new THREE.ShadowMesh(toolMesh, options.shadowMaterial);
            var shadowPlane = new THREE.Plane(THREE.Object3D.DefaultUp, options.shadowPlane);
            toolShadowMesh.updateShadowMatrix(shadowPlane, options.shadowLightPosition);
        } else {
            toolMesh.castShadow = true;
        }

        var toolBody = new CANNON.Body({mass: options.toolMass, type: CANNON.Body.KINEMATIC});
        toolBody.material = options.tipMaterial;
        toolBody.addShape(new CANNON.Cylinder(options.tipRadius, options.tipRadius, options.tipLength, 8),
            new CANNON.Vec3(0, 0, 0.5 * options.tipLength));

        var position = new THREE.Vector3();
        var velocity = new THREE.Vector3();
        var quaternion = new THREE.Quaternion();
        var worldPosition = new THREE.Vector3();
        var worldQuaternion = new THREE.Quaternion();
        var worldScale = new THREE.Vector3();

        function update(dt) {
            if (vrGamepad && vrGamepad.pose) {
                toolMesh.position.fromArray(vrGamepad.pose.position);
                toolMesh.quaternion.fromArray(vrGamepad.pose.orientation);
                position.copy(toolMesh.position);
                velocity.copy(toolBody.interpolatedPosition);
                var parent = toolMesh.parent;
                if (parent) {
                    parent.updateMatrix();
                    parent.updateMatrixWorld();
                    parent.matrixWorld.decompose(worldPosition, worldQuaternion, worldScale);
                    position.applyMatrix4(parent.matrixWorld);
                    quaternion.multiplyQuaternions(worldQuaternion, toolMesh.quaternion);
                    toolBody.position.copy(position);
                    toolBody.quaternion.copy(quaternion);
                    velocity.sub(position);
                    velocity.multiplyScalar(-1 / dt);
                    toolBody.velocity.copy(velocity);
                }
            } else {
                toolBody.sleep();
            }
            toolMesh.updateMatrix();
            if (toolShadowMesh) toolShadowMesh.updateMatrix();
            toolMesh.updateMatrixWorld();
        }
        return {
            body: toolBody,
            mesh: toolMesh,
            shadowMesh: toolShadowMesh,
            update: update
        };
    }

    function pollGamepads() {
        gamepads = navigator.getGamepads();
        for (var i = 0; i < gamepads.length; i++) {
            var gamepad = gamepads[i];
            if (!gamepad) continue;
            if (buttonsPresseds[i] === undefined) {
                console.log('new gamepad: %s', gamepad.id);
                if (/openvr/i.test(gamepad.id)) {
                    vrGamepads.push(gamepad);
                } else if (/xbox/i.test(gamepad.id) || /xinput/i.test(gamepad.id)) {
                    xboxGamepads.push(gamepad);
                }
                buttonsPresseds[i] = [];
                for (var j = 0; j < gamepad.buttons.length; j++) {
                    buttonsPresseds[i].push(false);
                }
                onGamepadConnected({gamepad: gamepad});
            }
        }
    }

    function setGamepadCommands(index, commands) {
        gamepadCommands[index] = commands;
    }

    var _onGamepadConnected = null;

    function setOnGamepadConnected(onGamepadConnected) {
        _onGamepadConnected = onGamepadConnected;
    }

    function onGamepadConnected(e) {
        console.log("Gamepad connected at index %d: %s - %d buttons, %d axes", e.gamepad.index, e.gamepad.id, e.gamepad.buttons.length, e.gamepad.axes.length);
        if (_onGamepadConnected) {
            _onGamepadConnected(e);
        }
    }
    window.addEventListener("gamepadconnected", onGamepadConnected);

    function onGamepadDisconnected(e) {
        console.log("Gamepad disconnected from index %d: %s", e.gamepad.index, e.gamepad.id);
        var i = e.gamepad.index;
        for (var j = 0; j < buttonsPresseds[i].length; j++) {
            buttonsPresseds[i][j] = false;
        }
    }
    window.addEventListener("gamepaddisconnected", onGamepadDisconnected);

    function update() {
        var values = [];
        pollGamepads();
        for (var i = 0; i < gamepads.length; ++i) {
            var gamepad = gamepads[i];
            if (!gamepad) continue;
            var buttonsPressed = buttonsPresseds[i];
            var commands = gamepadCommands[i] || {};
            // get all button/axes values:
            var axesValues = {};
            for (var name in commands) {
                axesValues[name] = 0;
                var command = commands[name];
                if (command.axes) {
                    for (var j = 0; j < gamepad.axes.length; j++) {
                        var axis = gamepad.axes[j];
                        if (Math.abs(axis) > DEADZONE) {
                            if (command.axes.indexOf(j) !== -1) {
                                axesValues[name] = gamepad.axes[j];
                                if (command.flipAxes) {
                                    axesValues[name] *= -1;
                                }
                                break;
                            }
                        }
                    }
                } else if (command.buttons) {
                    for (j = 0; j < command.buttons.length; j++) {
                        if (gamepad.buttons[command.buttons[j]] && gamepad.buttons[command.buttons[j]].pressed) {
                            axesValues[name] = 1;
                            break;
                        }
                    }
                }
            }
            values.push(axesValues);
            for (j = 0; j < gamepad.buttons.length; j++) {
                if (gamepad.buttons[j]) {
                    if (gamepad.buttons[j].pressed && !buttonsPressed[j]) {
                        buttonsPressed[j] = true;
                        for (name in commands) {
                            command = commands[name];
                            if (command.commandDown && command.buttons && command.buttons.indexOf(j) !== -1) {
                                command.commandDown(j, gamepad.axes);
                            }
                        }
                    } else if (!gamepad.buttons[j].pressed && buttonsPressed[j]) {
                        buttonsPressed[j] = false;
                        for (name in commands) {
                            command = commands[name];
                            if (command.commandUp && command.buttons && command.buttons.indexOf(j) !== -1) {
                                command.commandUp(j, gamepad.axes);
                            }
                        }
                    }
                }
            }
        }
        return values;
    }

    pollGamepads();

    return {
        BUTTONS: {
            A: 0,
            B: 1,
            X: 2,
            Y: 3,
            leftBumper: 4,
            rightBumper: 5,
            leftTrigger: 6,
            rightTrigger: 7,
            back: 8,
            start: 9,
            leftStick: 10,
            rightStick: 11,
            up: 12,
            down: 13,
            left: 14,
            right: 15
        },
        AXES: {
            LSX: 0,
            LSY: 1,
            RSX: 2,
            RSY: 3
        },
        viveMeshA: viveMeshA,
        viveMeshB: viveMeshB,
        vrGamepadMeshes: vrGamepadMeshes,
        setGamepadCommands: setGamepadCommands,
        setOnGamepadConnected: setOnGamepadConnected,
        update: update,
        makeTool: makeTool,
        vrGamepads: vrGamepads,
        xboxGamepads: xboxGamepads
    };

} )();
<|endoftext|>


<commit_before>var NN = NN || {};

NN.GameState = NN.GameState || {};

NN.GameState.init = function(currentLevel, hadInstructions) {

    // game constants
    this.game.stage.backgroundColor = '#000';

    // level data
    this.currentLevel = currentLevel ? currentLevel : 1;

    if (this.currentLevel < 4 && !hadInstructions) {
        this.state.start('InstructionsState', true, false, this.currentLevel);
    }

    this.GAMEX = this.game.world.width;
    this.GAMEY = this.game.world.height;

    this.keyboard = this.game.input.keyboard.createCursorKeys();
    this.keyboard.space = this.game.input.keyboard.addKey(Phaser.KeyCode.SPACEBAR);

    this.facing = {
        "down":  0,
        "left":  2,
        "up":    3,
        "right": 1
    };
};

NN.GameState.create = function() {
    this.loadLevel();
    this.createBackground(this.levelData.columns, this.levelData.rows);
    // this.createBackground(5, 7);

    this.player = this.createCharacter('player', 0, 0, 'right');
    this.game.physics.arcade.enable(this.player);
    this.player.body.setSize(60, 60, 0, 0);
    this.nabbedText = this.add.group();
    this.generateNumbers(this.currentLevel);
    this.generateNabbedText();
    this.texts = this.add.group();
    this.createBoard(this.levelData.columns, this.levelData.rows);
    if (this.levelData.baddies) {
        this.generateBaddies();
    }

    var eventDuration;
    var startPoint = {};
    var endPoint = {};
    var direction;
    // this is the number of pixels they have to move their finger
    //  before it consideres it as a swipe rather than a tap.
    var swipeVsTap = 9;

    this.game.input.onDown.add(function(pointer) {
        startPoint.x = pointer.clientX;
        startPoint.y = pointer.clientY;
    }, this);

    // Enable SWIPING for Player Movement
    // TODO get this functionality into the library
    this.game.input.onUp.add(function(pointer) {
        direction = false;

        endPoint.x = pointer.clientX;
        endPoint.y = pointer.clientY;

        var deltaX = endPoint.x - startPoint.x;
        var deltaY = endPoint.y - startPoint.y;

        if(Math.abs(deltaX) >= Math.abs(deltaY)) {
            if (Math.abs(deltaX) < swipeVsTap) {
                this.nab();
            }
            else if (deltaX < 0) {
                direction = 'left';
            }
            else {
                direction = 'right';
            }
        }
        else {
            if (Math.abs(deltaY) < swipeVsTap) {
                this.nab();
            }
            else if (deltaY < 0) {
                direction = 'up';
            }
            else {
                direction = 'down';
            }
        }
        if (direction) {
            this.moveTo(this.player, direction);
        }
    }, this);
};

NN.GameState.update = function() {
    if (this.timeCheck && this.time.now - this.timeCheck > 1500) {
        this.pushEmOut();
        if (this.time.now - this.timeCheck > 2000) {
            this.nabbing = false;
            this.timeCheck = false;
        }
    }

    this.updatePlayer();

    this.game.physics.arcade.overlap(this.player, this.baddies, this.baddieAttack, null, this);
};

NN.GameState.loadLevel = function() {
    var levels = JSON.parse(this.game.cache.getText('levels'));
    if (!this.game.numLevels) {
        var i = 1;
        while (levels['level' + i])
            this.game.numLevels = i++;
    }
    this.levelData = levels['level' + this.currentLevel];
};

NN.GameState.createBackground = function(columns, rows) {
    this.tileSize = Math.floor(this.GAMEX / columns);
    var remainder = (this.GAMEX % columns);
    this.skew = Math.floor(remainder / 2);
    this.boardSizeX = this.tileSize * columns;
    this.boardSizeY = this.tileSize * rows;

    this.tiles = this.add.tileSprite(this.skew, this.GAMEY - this.boardSizeY, this.boardSizeX, this.boardSizeY, 'tile', 0);
    var scale = this.tileSize / this.tiles.texture.width;
    this.tiles.tileScale.x = scale;
    this.tiles.tileScale.y = scale;
};

NN.GameState.generateNabbedText = function(){
    this.levelText = this.add.text(0, 0);
    this.levelText.style.font = 'bold 70pt Arial';
    this.levelText.style.fill = '#0f0';
    this.levelText.text = this.currentLevel;
    var coords = [];
    for ( var i = 0; i < 12; i++ ) {
        coords = this.nabbedCoordsOfIndex(i);
        var nabbed = this.add.text(coords[0], coords[1]);
        nabbed.style.font = 'bold 25pt Arial';
        nabbed.style.fill = '#fff';
        nabbed.anchor.setTo(0.5);
        this.nabbedText.add(nabbed);
    }
    this.updateNabbedText();
};

NN.GameState.generateNumbers = function(level) {
    var numbers = library.range(1, 12 * level + 1);
    this.answers = {};
    this.nabbed = [];
    this.nabbed[11] = null;
    this.choices = [];
    this.pool = [];
    var index = 1;
    numbers.forEach(function(n) {
        var self = this;
        if (n % level == 0) {
            self.choices.push(n);
            self.answers[n] = index;
            index++;
        }
        else {
            self.pool.push(n);
        }
    }, this)

    var boardSize = this.levelData.rows * this.levelData.columns;

    for (var i = 12; i < boardSize; i++) {
        var idx = Math.floor(Math.random() * (this.pool.length));
        this.choices.push((this.pool.splice(idx, 1))[0]);
    }

    library.shuffle(this.choices);

};

NN.GameState.createBoard = function(columns, rows) {
    this.board = [];
    index = 0;
    var pixel_x;
    var pixel_y;
    for (var x = 0; x < columns; x++) {
        this.board[x] = [];
        for (var y = 0; y < rows; y++) {
            pixel_x = (x + 0.5) * this.tileSize + this.skew;
            pixel_y = (this.GAMEY - this.boardSizeY) + (y + 0.5) * this.tileSize;
            text = this.texts.getFirstExists(false);

            if (!text) {
                text = this.add.text(pixel_x, pixel_y);
                this.texts.add(text);
                text.anchor.setTo(0.5);
            }
            text.customParams = {};
            text.customParams.x = x;
            text.customParams.y = y;
            text.text = this.choices[index];
            text.style.font = 'bold 25pt Arial';
            text.style.fill = '#fff';

            this.board[x][y] = text;
            index++;
        }
    }
};

NN.GameState.newNumber = function(posX, posY) {
    var index = Math.floor(Math.random() * this.pool.length);
    var newnum = this.pool.splice(index, 1)[0];
    var number = this.board[posX][posY];
    number.x = this.GAMEX / 2;
    number.y = this.GAMEY - this.boardSizeY / 2;
    number.text = newnum;
    number.style.font = 'bold 25pt Arial';
    number.style.fill = '#fff';
    number.anchor.setTo(0.5);
    var moveText = this.game.add.tween(number);
    var coords = this.coordsFromPos(posX, posY);
    moveText.to({x: coords[0], y: coords[1]}, 500);
    moveText.onComplete.add(function() {
        // this.board[posX][posY] = number;
    }, this);
    moveText.start();
};

NN.GameState.coordsFromPos = function(X, Y) {
    var coords = [];
    coords[0] = this.skew + this.tileSize / 2 + X * this.tileSize;
    coords[1] = this.GAMEY - this.boardSizeY + this.tileSize / 2 + Y * this.tileSize;
    return (coords);
};

NN.GameState.updateNabbedText = function() {
    for (var i = 0; i < this.nabbed.length; i++) {
        var number = this.nabbed[i];
        if (number) {
            this.nabbedText.children[i].text = number;
        }
        else {
            this.nabbedText.children[i].text = '__';
        }
    }
};

NN.GameState.mixEmUp = function() {
    this.timeCheck = this.time.now;
    this.nabbing = true;
    library.shuffleDeeply(this.board);
    this.pullEmIn();
};

NN.GameState.removeNabbed = function() {
    // Make sure there is a nabbed number to remove first
    var nabbedNums = this.nabbed.filter(function(a){return a;});
    if (nabbedNums.length == 0) {
        return;
    }

    // choose a random wrong answer from the board
    var tempArray = library.flatten(this.board);
    var wrongAnswers = tempArray.filter(function(a){
        return (parseInt(a.text, 10) % this.currentLevel);
    }, this);
    var chosen = library.choose(wrongAnswers);

    // choose a random right answer from the nabbed list
    var choice = library.choose(nabbedNums);
    var index = this.nabbed.indexOf(choice);

    // change the wrong number from the board to the right number from the nabbed list
    var wrongText = chosen.text;
    chosen.text = choice;

    // then put the wrong number back in the pool
    this.pool.push(wrongText);

    this.nabbed[index] = false;
    var nabbedLocation = this.nabbedCoordsOfIndex(index);
    chosen.position = {x: nabbedLocation[0], y: nabbedLocation[1]};
    this.updateNabbedText();
};

NN.GameState.pullEmIn = function() {
    var cols = this.levelData.columns;
    var rows = this.levelData.rows;
    for (var x = 0; x < cols; x++) {
        for (var y = 0; y < rows; y++) {
            var moveText = this.game.add.tween(this.board[x][y]);
            var target = this.coordsFromPos( (cols-1) / 2, (rows-1) / 2);
            moveText.to({x: target[0], y: target[1]}, 500);
            moveText.start();
        }
    }
};

NN.GameState.nabbedCoordsOfIndex = function(index) {
    var pixel_x = 120;
    var pixel_y = 40;
    var x = index % 4;
    var y = Math.floor(index / 4);

    var coords = [pixel_x + x*60, pixel_y + y*40];
    return coords;
};

NN.GameState.pushEmOut = function() {
    if (this.pushing) {
        return;
    }
    this.pushing = true;
    var cols = this.levelData.columns;
    var rows = this.levelData.rows;
    var target = [];
    for (var x = 0; x < cols; x++) {
        for (var y = 0; y < rows; y++) {
            var moveTextBack = this.game.add.tween(this.board[x][y]);
            // moveTextBack.to({x: this.board[x][y].position.x, y: this.board[x][y].position.y}, 500);
            target = this.coordsFromPos(x, y);
            moveTextBack.to({x: target[0], y: target[1]}, 500);
            moveTextBack.onComplete.add(function() {
                this.pushing = false;
            }, this);
            moveTextBack.start();
        }
    }
};

NN.GameState.checkWin = function() {
    for (var i = 0; i < 12; i++) {
        if (!this.nabbed[i])
            return; // Not won yet
    }
    var nextLevel = this.currentLevel + 1;
    if (nextLevel > this.game.numLevels) {
        console.log("You win!");
    }
    else {
        this.game.state.restart(true, false, nextLevel);
    }
};
<commit_msg>added a timer and local data storage of fastest time<commit_after>var NN = NN || {};

NN.GameState = NN.GameState || {};

NN.GameState.init = function(currentLevel, hadInstructions) {

    // game constants
    this.game.stage.backgroundColor = '#000';

    // level data
    this.currentLevel = currentLevel ? currentLevel : 1;

    if (this.currentLevel < 4 && !hadInstructions) {
        this.state.start('InstructionsState', true, false, this.currentLevel);
    }

    this.GAMEX = this.game.world.width;
    this.GAMEY = this.game.world.height;

    this.keyboard = this.game.input.keyboard.createCursorKeys();
    this.keyboard.space = this.game.input.keyboard.addKey(Phaser.KeyCode.SPACEBAR);

    this.facing = {
        "down":  0,
        "left":  2,
        "up":    3,
        "right": 1
    };
};

NN.GameState.create = function() {
    this.loadLevel();
    this.createBackground(this.levelData.columns, this.levelData.rows);
    // this.createBackground(5, 7);

    this.player = this.createCharacter('player', 0, 0, 'right');
    this.game.physics.arcade.enable(this.player);
    this.player.body.setSize(60, 60, 0, 0);
    this.nabbedText = this.add.group();
    this.generateNumbers(this.currentLevel);
    this.generateNabbedText();
    this.texts = this.add.group();
    this.createBoard(this.levelData.columns, this.levelData.rows);
    if (this.levelData.baddies) {
        this.generateBaddies();
    }

    // Enable SWIPING for Player Movement
    var click_position = {};
    var click_release = {};
    var swipeVsTap = 9;
    // this is the number of pixels they have to move their finger
    //  before it consideres it as a swipe rather than a tap.

	this.game.input.onDown.add(function(pointer) {
        click_position = library.click(pointer);
    }, this);
    this.game.input.onUp.add(function(pointer) {
        click_release = library.release_click(pointer, click_position, swipeVsTap);
        if (click_release.direction == 'tap') {
            this.nab();
        }
        else if (click_release.direction) {
            this.moveTo(this.player, click_release.direction);
        }
    }, this);

    this.startTime = new Date();
    this.timeElapsed = 0;
    this.createTimer();
    this.gameTimer = this.game.time.events.loop(100, function(){
        this.updateTimer();
    }, this);
};

NN.GameState.update = function() {
    if (this.timeCheck && this.time.now - this.timeCheck > 1500) {
        this.pushEmOut();
        if (this.time.now - this.timeCheck > 2000) {
            this.nabbing = false;
            this.timeCheck = false;
        }
    }

    this.updatePlayer();

    this.game.physics.arcade.overlap(this.player, this.baddies, this.baddieAttack, null, this);
};

NN.GameState.loadLevel = function() {
    var levels = JSON.parse(this.game.cache.getText('levels'));
    if (!this.game.numLevels) {
        var i = 1;
        while (levels['level' + i])
            this.game.numLevels = i++;
    }
    this.levelData = levels['level' + this.currentLevel];
};

NN.GameState.createBackground = function(columns, rows) {
    this.tileSize = Math.floor(this.GAMEX / columns);
    var remainder = (this.GAMEX % columns);
    this.skew = Math.floor(remainder / 2);
    this.boardSizeX = this.tileSize * columns;
    this.boardSizeY = this.tileSize * rows;

    this.tiles = this.add.tileSprite(this.skew, this.GAMEY - this.boardSizeY, this.boardSizeX, this.boardSizeY, 'tile', 0);
    var scale = this.tileSize / this.tiles.texture.width;
    this.tiles.tileScale.x = scale;
    this.tiles.tileScale.y = scale;
};

NN.GameState.generateNabbedText = function(){
    this.levelText = this.add.text(0, 0);
    this.levelText.style.font = 'bold 70pt Arial';
    this.levelText.style.fill = '#0f0';
    this.levelText.text = this.currentLevel;
    var coords = [];
    for ( var i = 0; i < 12; i++ ) {
        coords = this.nabbedCoordsOfIndex(i);
        var nabbed = this.add.text(coords[0], coords[1]);
        nabbed.style.font = 'bold 25pt Arial';
        nabbed.style.fill = '#fff';
        nabbed.anchor.setTo(0.5);
        this.nabbedText.add(nabbed);
    }
    this.updateNabbedText();
};

NN.GameState.generateNumbers = function(level) {
    var numbers = library.range(1, 12 * level + 1);
    this.answers = {};
    this.nabbed = [];
    this.nabbed[11] = null;
    this.choices = [];
    this.pool = [];
    var index = 1;
    numbers.forEach(function(n) {
        var self = this;
        if (n % level == 0) {
            self.choices.push(n);
            self.answers[n] = index;
            index++;
        }
        else {
            self.pool.push(n);
        }
    }, this)

    var boardSize = this.levelData.rows * this.levelData.columns;

    for (var i = 12; i < boardSize; i++) {
        var idx = Math.floor(Math.random() * (this.pool.length));
        this.choices.push((this.pool.splice(idx, 1))[0]);
    }

    library.shuffle(this.choices);

};

NN.GameState.createBoard = function(columns, rows) {
    this.board = [];
    index = 0;
    var pixel_x;
    var pixel_y;
    for (var x = 0; x < columns; x++) {
        this.board[x] = [];
        for (var y = 0; y < rows; y++) {
            pixel_x = (x + 0.5) * this.tileSize + this.skew;
            pixel_y = (this.GAMEY - this.boardSizeY) + (y + 0.5) * this.tileSize;
            text = this.texts.getFirstExists(false);

            if (!text) {
                text = this.add.text(pixel_x, pixel_y);
                this.texts.add(text);
                text.anchor.setTo(0.5);
            }
            text.customParams = {};
            text.customParams.x = x;
            text.customParams.y = y;
            text.text = this.choices[index];
            text.style.font = 'bold 25pt Arial';
            text.style.fill = '#fff';

            this.board[x][y] = text;
            index++;
        }
    }
};

NN.GameState.newNumber = function(posX, posY) {
    var index = Math.floor(Math.random() * this.pool.length);
    var newnum = this.pool.splice(index, 1)[0];
    var number = this.board[posX][posY];
    number.x = this.GAMEX / 2;
    number.y = this.GAMEY - this.boardSizeY / 2;
    number.text = newnum;
    number.style.font = 'bold 25pt Arial';
    number.style.fill = '#fff';
    number.anchor.setTo(0.5);
    var moveText = this.game.add.tween(number);
    var coords = this.coordsFromPos(posX, posY);
    moveText.to({x: coords[0], y: coords[1]}, 500);
    moveText.onComplete.add(function() {
        // this.board[posX][posY] = number;
    }, this);
    moveText.start();
};

NN.GameState.coordsFromPos = function(X, Y) {
    var coords = [];
    coords[0] = this.skew + this.tileSize / 2 + X * this.tileSize;
    coords[1] = this.GAMEY - this.boardSizeY + this.tileSize / 2 + Y * this.tileSize;
    return (coords);
};

NN.GameState.updateNabbedText = function() {
    for (var i = 0; i < this.nabbed.length; i++) {
        var number = this.nabbed[i];
        if (number) {
            this.nabbedText.children[i].text = number;
        }
        else {
            this.nabbedText.children[i].text = '__';
        }
    }
};

NN.GameState.mixEmUp = function() {
    this.timeCheck = this.time.now;
    this.nabbing = true;
    library.shuffleDeeply(this.board);
    this.pullEmIn();
};

NN.GameState.removeNabbed = function() {
    // Make sure there is a nabbed number to remove first
    var nabbedNums = this.nabbed.filter(function(a){return a;});
    if (nabbedNums.length == 0) {
        return;
    }

    // choose a random wrong answer from the board
    var tempArray = library.flatten(this.board);
    var wrongAnswers = tempArray.filter(function(a){
        return (parseInt(a.text, 10) % this.currentLevel);
    }, this);
    var chosen = library.choose(wrongAnswers);

    // choose a random right answer from the nabbed list
    var choice = library.choose(nabbedNums);
    var index = this.nabbed.indexOf(choice);

    // change the wrong number from the board to the right number from the nabbed list
    var wrongText = chosen.text;
    chosen.text = choice;

    // then put the wrong number back in the pool
    this.pool.push(wrongText);

    this.nabbed[index] = false;
    var nabbedLocation = this.nabbedCoordsOfIndex(index);
    chosen.position = {x: nabbedLocation[0], y: nabbedLocation[1]};
    this.updateNabbedText();
};

NN.GameState.pullEmIn = function() {
    var cols = this.levelData.columns;
    var rows = this.levelData.rows;
    for (var x = 0; x < cols; x++) {
        for (var y = 0; y < rows; y++) {
            var moveText = this.game.add.tween(this.board[x][y]);
            var target = this.coordsFromPos( (cols-1) / 2, (rows-1) / 2);
            moveText.to({x: target[0], y: target[1]}, 500);
            moveText.start();
        }
    }
};

NN.GameState.nabbedCoordsOfIndex = function(index) {
    var pixel_x = 120;
    var pixel_y = 40;
    var x = index % 4;
    var y = Math.floor(index / 4);

    var coords = [pixel_x + x*60, pixel_y + y*40];
    return coords;
};

NN.GameState.pushEmOut = function() {
    if (this.pushing) {
        return;
    }
    this.pushing = true;
    var cols = this.levelData.columns;
    var rows = this.levelData.rows;
    var target = [];
    for (var x = 0; x < cols; x++) {
        for (var y = 0; y < rows; y++) {
            var moveTextBack = this.game.add.tween(this.board[x][y]);
            // moveTextBack.to({x: this.board[x][y].position.x, y: this.board[x][y].position.y}, 500);
            target = this.coordsFromPos(x, y);
            moveTextBack.to({x: target[0], y: target[1]}, 500);
            moveTextBack.onComplete.add(function() {
                this.pushing = false;
            }, this);
            moveTextBack.start();
        }
    }
};

NN.GameState.createTimer = function() {
    this.timeLabel = this.game.add.text(7, 100, "00:00");
    this.timeLabel.style.font = '25pt Arial';
    this.timeLabel.style.fill = '#fff';
};

NN.GameState.updateTimer = function() {
	var currentTime = new Date();
	var timeDifference = currentTime.getTime() - this.startTime.getTime();
    this.timeElapsed = timeDifference / 1000;

    var prettyTime = this.stringifyTime(this.timeElapsed);
    this.timeLabel.text = prettyTime;
};

NN.GameState.stringifyTime = function(totalSeconds) {
    var minutes = Math.floor(totalSeconds / 60);
    var seconds = Math.floor(totalSeconds) - (60 * minutes);

    var result = (minutes < 10) ? "0" + minutes : minutes;
    result += (seconds < 10) ? ":0" + seconds : ":" + seconds;
    return result;
};

NN.GameState.checkWin = function() {
    for (var i = 0; i < 12; i++) {
        if (!this.nabbed[i])
            return; // Not won yet
    }
    this.updateBestTime();
    var nextLevel = this.currentLevel + 1;

    if (nextLevel > this.game.numLevels) {
        console.log("You win!");
    }
    else {
        this.game.state.restart(true, false, nextLevel);
    }
};

NN.GameState.updateBestTime = function() {
    this.bestTime = +localStorage.getItem('bestTime' + this.currentLevel);
    if (!this.bestTime || this.bestTime > this.timeElapsed) {
        this.bestTime = this.timeElapsed;
        localStorage.setItem('bestTime' + this.currentLevel, this.bestTime);
        console.log("New Record!!!");
    }
};
<|endoftext|>


<commit_before>var StaticMap;
var ZoomableMap;

!function() {
    StaticMap = function(parameters) {
        "use strict";

        var settings = jQuery.extend({
                strokeWidth: 1.5,
                height: 200,
                width: $(parameters.element).innerWidth(),
                zoomScaleFactor: 0.9
            }, parameters)
          , features = topojson.feature(settings.topojson,
                                        settings.topojson.objects[parameters.name])

        if (parameters.projection) {
            var dataPath = d3.geo.path().projection(projection = parameters.projection)
        } else {
            var b = d3.geo.bounds(features)
              , projection = d3.geo.mercator()
                                   .scale(1)
                                   .center([(b[1][0] + b[0][0]) / 2,
                                            (b[1][1] + b[0][1]) / 2])
              , dataPath = d3.geo.path().projection(projection)
              , bounds = dataPath.bounds(features)
              , dx = bounds[1][0] - bounds[0][0]
              , dy = bounds[1][1] - bounds[0][1]
              , scale = 0.9 * (settings.width / dx)

            settings.height = dy * settings.width / dx

            projection.scale(scale)
                      .translate([settings.width / 2, settings.height / 2/* + topMargin*/])
        }

        $(this).height(settings.height) //FIXME: Introduce topMargin again

        function init() {
            var svg = d3.select(settings.element).append("svg")
                        .attr("width", settings.width)
                        .attr("height", settings.height/* + topMargin*/)

            svg.append("rect")
                    .attr("class", "map-background")
                    .attr("width", settings.width)
                    .attr("height", settings.height)

            var g = svg.append("g")
                       .attr("class", "map-polygonGroup")
                       .style("stroke-width", settings.strokeWidth + "px")
                       .selectAll("path")
                       .data(features.features)
                       .enter().append("path")
                       .attr("class", "map-polygon")
                       .attr("d", dataPath)
                       .style("fill", settings.fillCallback)

            //Prevent another call to the init method
            this.init = function() {}
        }

        this.init = init
        this.features = function() { return features }
        this.path = function()  { return dataPath }
        this.parameters = function() { return settings }
    }

    ZoomableMap = function(parameters) {
        var staticMap = new StaticMap(parameters)
          , settings = $.extend({
                selectCallback: function(d) {}
            }, staticMap.parameters())
          , selected
          , group

        function init() {
            staticMap.init()

            var svg = d3.select(parameters.element + " svg")

            svg.select(".map-background")
               .on("click", zoomOut);

            svg.selectAll(".map-polygon")
               .on("click", zoomIn)
               .on("mouseover", function(d, i) {
                   //TODO: Set stroke color dynamically here, not in css
                   d3.select(this).classed("map-polygon--active", true);
                })
               .on("mouseout", function(d, i) {
                    d3.select(this).classed("map-polygon--active", false);
               });

            group = svg.select(".map-polygonGroup");

            //$(parentSelector + ".map-clearButton").on("click", zoomHome);
        }

        function zoomOut() {
            selected = undefined

            group.transition()
                .duration(500)
                .style("stroke-width", settings.strokeWidth + "px")
                .attr("transform", "")

            settings.selectCallback(undefined)
        }

        function zoomIn(d) {
            if (selected == d || d == undefined) {
                zoomOut()
                return
            }
            selected = d

            var bounds = staticMap.path().bounds(d),
                dx = bounds[1][0] - bounds[0][0],
                dy = bounds[1][1] - bounds[0][1],
                x = (bounds[0][0] + bounds[1][0]) / 2,
                y = (bounds[0][1] + bounds[1][1]) / 2,
                scale = settings.zoomScaleFactor /
                        Math.max(dx / settings.width, dy / settings.height),
                translate = [settings.width / 2 - scale * x,
                             settings.height / 2 - scale * y/* + topMargin*/],
                strokeWidthScaled = Math.max(0.01, settings.strokeWidth / scale)

            group.transition()
                 .duration(500)
                 .attr("transform", "translate(" + translate + ")scale(" + scale + ")")
                 .style("stroke-width", strokeWidthScaled + "px")

            settings.selectCallback(selected)
        }

        this.init = init
        this.settings = function() { return settings }
    }
}()
<commit_msg>Active stroke when hover<commit_after>var StaticMap;
var ZoomableMap;

!function() {
    "use strict";
    StaticMap = function(parameters) {
        var settings = jQuery.extend({
                strokeWidth: 1.5,
                height: 200,
                width: $(parameters.element).innerWidth(),
                zoomScaleFactor: 0.9
            }, parameters)
          , features = topojson.feature(settings.topojson,
                                        settings.topojson.objects[parameters.name])

        if (parameters.projection) {
            var dataPath = d3.geo.path().projection(projection = parameters.projection)
        } else {
            var b = d3.geo.bounds(features)
              , projection = d3.geo.mercator()
                                   .scale(1)
                                   .center([(b[1][0] + b[0][0]) / 2,
                                            (b[1][1] + b[0][1]) / 2])
              , dataPath = d3.geo.path().projection(projection)
              , bounds = dataPath.bounds(features)
              , dx = bounds[1][0] - bounds[0][0]
              , dy = bounds[1][1] - bounds[0][1]
              , scale = 0.9 * (settings.width / dx)

            settings.height = dy * settings.width / dx

            projection.scale(scale)
                      .translate([settings.width / 2, settings.height / 2/* + topMargin*/])
        }

        $(this).height(settings.height) //FIXME: Introduce topMargin again

        function init() {
            var svg = d3.select(settings.element).append("svg")
                        .attr("width", settings.width)
                        .attr("height", settings.height/* + topMargin*/)

            svg.append("rect")
                    .attr("class", "map-background")
                    .attr("width", settings.width)
                    .attr("height", settings.height)

            var g = svg.append("g")
                       .attr("class", "map-polygonGroup")
                       .style("stroke-width", settings.strokeWidth + "px")
                       .selectAll("path")
                       .data(features.features)
                       .enter().append("path")
                       .attr("class", "map-polygon")
                       .attr("d", dataPath)
                       .style("fill", settings.fillCallback)

            //Prevent another call to the init method
            this.init = function() {}
        }

        this.init = init
        this.features = function() { return features }
        this.path = function()  { return dataPath }
        this.parameters = function() { return settings }
    }

    ZoomableMap = function(parameters) {
        var staticMap = new StaticMap(parameters)
          , settings = $.extend({
                selectCallback: function(d) {}
            }, staticMap.parameters())
          , selected
          , group

        function init() {
            staticMap.init()

            var svg = d3.select(parameters.element + " svg")

            svg.select(".map-background")
               .on("click", zoomOut);

            svg.selectAll(".map-polygon")
               .on("click", zoomIn)
               .on("mouseover", function(d, i) {
                   d3.select(this).style("stroke", "black")
                })
               .on("mouseout", function(d, i) {
                    d3.select(this).style("stroke", "unset")
               });

            group = svg.select(".map-polygonGroup");

            //$(parentSelector + ".map-clearButton").on("click", zoomHome);
        }

        function zoomOut() {
            selected = undefined

            group.transition()
                .duration(500)
                .style("stroke-width", settings.strokeWidth + "px")
                .attr("transform", "")

            settings.selectCallback(undefined)
        }

        function zoomIn(d) {
            if (selected == d || d == undefined) {
                zoomOut()
                return
            }
            selected = d

            var bounds = staticMap.path().bounds(d),
                dx = bounds[1][0] - bounds[0][0],
                dy = bounds[1][1] - bounds[0][1],
                x = (bounds[0][0] + bounds[1][0]) / 2,
                y = (bounds[0][1] + bounds[1][1]) / 2,
                scale = settings.zoomScaleFactor /
                        Math.max(dx / settings.width, dy / settings.height),
                translate = [settings.width / 2 - scale * x,
                             settings.height / 2 - scale * y/* + topMargin*/],
                strokeWidthScaled = Math.max(0.01, settings.strokeWidth / scale)

            group.transition()
                 .duration(500)
                 .attr("transform", "translate(" + translate + ")scale(" + scale + ")")
                 .style("stroke-width", strokeWidthScaled + "px")

            settings.selectCallback(selected)
        }

        this.init = init
        this.settings = function() { return settings }
    }
}()
<|endoftext|>


<commit_before>game.PlayScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {

        // load a level
		me.levelDirector.loadLevel("area01");

		// reset the score
		game.data.score = 0;

		// add our HUD to the game world
		this.HUD = new game.HUD.Container();
		me.game.world.addChild(this.HUD);
	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		// remove the HUD from the game world
		me.game.world.removeChild(this.HUD);
	}
});
<commit_msg>Update play.js<commit_after>game.PlayScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {

		// load a level
		me.levelDirector.loadLevel("area01");

		// reset the score
		game.data.score = 0;

		// add our HUD to the game world
		this.HUD = new game.HUD.Container();
		me.game.world.addChild(this.HUD);

	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		// remove the HUD from the game world
		me.game.world.removeChild(this.HUD);
	}
});
<|endoftext|>


<commit_before>function Javabuzz() {
	Javabuzz.prototype.isDivisibleByThree = function(number) {
		return (number % 3 === 0);
	};

	Javabuzz.prototype.isDivisibleByFive = function(number) {
		return (number % 5 === 0);
	};

	Javabuzz.prototype.isDivisibleByFifteen = function(number) {
		return (number % 15 === 0);
	};
};<commit_msg>Refactoring<commit_after>function Javabuzz() {

	Javabuzz.prototype._isDivisbleBy = function(number, divisor) {
		return(number % divisor === 0);
	};

	Javabuzz.prototype.isDivisibleByThree = function(number) {
		return this._isDivisbleBy(number, 3);
	};

	Javabuzz.prototype.isDivisibleByFive = function(number) {
		return this._isDivisbleBy(number, 5);
	};

	Javabuzz.prototype.isDivisibleByFifteen = function(number) {
		return this._isDivisbleBy(number, 15);
	};
};<|endoftext|>


<commit_before>game.PlayScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		// reset the score
		game.data.score = 0;

		me.levelDirector.loadLevel("level01");
		//loads the level/map when the game is opened and melonJS is run

		var player = me.pool.pull("player", 0, 420, {});
		me.game.world.addChild(player, 5);
		//pull instance of the player

		me.input.bindKey(me.input.KEY.RIGHT, "right");
		me.input.bindKey(me.input.KEY.LEFT, "left");
		//binds a key for movement

		// add our HUD to the game world
		this.HUD = new game.HUD.Container();
		me.game.world.addChild(this.HUD);
	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		// remove the HUD from the game world
		me.game.world.removeChild(this.HUD);
	}
});
<commit_msg>Video 9 completed<commit_after>game.PlayScreen = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		// reset the score
		game.data.score = 0;

		me.levelDirector.loadLevel("level01");
		//loads the level/map when the game is opened and melonJS is run

		var player = me.pool.pull("player", 0, 420, {});
		me.game.world.addChild(player, 5);
		//pull instance of the player

		me.input.bindKey(me.input.KEY.RIGHT, "right");
		me.input.bindKey(me.input.KEY.LEFT, "left");
		//binds a key for movement

		// add our HUD to the game world
		this.HUD = new game.HUD.Container();
		me.game.world.addChild(this.HUD);
	},

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
		// remove the HUD from the game world
		me.game.world.removeChild(this.HUD);
	}
});<|endoftext|>


<commit_before>/*!
 * vIndexNav v1.0
 *
 * Contact: https://github.com/xiaolin3303
 * 2016-07-20
 *
 * Designed and built with all the love of Web
 */

function vIndexNav (opts) {
	opts = opts || {};
	this.opts = $.extend({
		onNav: function () {}
	}, opts);

	if (!opts.target) {
		throw new Error ('target param is required!');
	}

	this.targetWrapper = opts.target;
	this.lock = false;
	this.indexList = [];
	this.tipTimer = null;
	this.prevIndex = null;

	this.init();
}

vIndexNav.prototype.init = function () {
	this.render();
	var list = this.collectIndex();
	this.renderIndexList(list);
	this.getIndexDetail();
	this.bind();
}

vIndexNav.prototype.render = function () {
	var navTpl = '

';
	this.navWrapper = $(navTpl);
	this.navWrapper.addClass('v-index-nav');
	$('body').append(this.navWrapper);

	var tipTpl = '

';
	this.tipWrapper = $(tipTpl);
	this.tipWrapper.addClass('v-nav-index-tip');
	$('body').append(this.tipWrapper);
}

vIndexNav.prototype.collectIndex = function () {
	var list = []
	var targets = this.targetWrapper.find('[v-nav-index]');
	targets.each(function () {
		list.push($(this).attr('v-nav-index'));
	});

	return list;
}

vIndexNav.prototype.getIndexDetail = function () {
	var me = this;
	$('ul > li', this.navWrapper).each(function () {
		var item = {}
		item.index = $(this).text();
		item.position = $(this).offset().top - window.scrollY;
		item.height = $(this).height();

		me.indexList.push(item);
	});
}

vIndexNav.prototype.renderIndexList = function (list) {
	var tpl = [];
	list.forEach(function (item) {
		tpl.push('
' + item + '
');
	});

	$('ul', this.navWrapper).html(tpl.join(''));
}

vIndexNav.prototype.findIndex = function (pos) {
	var target = null;
	for(var i = 0, len = this.indexList.length; i < len; i++) {
		var item = this.indexList[i];
		var start = item.position;
		var end = start + item.height;
		if (pos >= start && pos <= end) {
			target = item;
			break;
		}
	}

	return target;
}

vIndexNav.prototype.showIndexTip = function (index) {
	if (this.tipTimer) {
		clearTimeout(this.tipTimer);
	}

	$('.v-nav-index-tip').text(index).show();
	this.tipTimer = setTimeout(function () {
		$('.v-nav-index-tip').hide();
	}, 1000);
}

vIndexNav.prototype.moveTo = function (index) {
	var target = $('[v-nav-index]', this.targetWrapper).filter(function () {
		return $(this).attr('v-nav-index') === index;
	});

	if (target) {
		var top = target.offset().top;
		window.scrollTo(0, top);
	}
}

vIndexNav.prototype.nav = function (pos) {
	pos = pos - window.scrollY;
	var indexItem = this.findIndex(pos);
	if (indexItem && indexItem.index !== this.prevIndex) {
		this.prevIndex = indexItem.index;
		this.showIndexTip(indexItem.index);
		this.moveTo(indexItem.index);

		this.opts.onNav(indexItem.index);
	}
}

vIndexNav.prototype.bind = function () {
	var me = this;
	this.navWrapper.on('touchmove', function (e) {
		this.lock && e.preventDefault();
		me.nav(e.touches[0].pageY);
	});
	this.navWrapper.on('touchstart', function (e) {
		this.lock = true;
		me.nav(e.touches[0].pageY);
	});
	this.navWrapper.on('touchend', function (e) {
		this.lock = false;
	});
}<commit_msg>update<commit_after>/*!
 * vIndexNav v1.0
 *
 * Contact: https://github.com/xiaolin3303
 * 2016-07-20
 *
 * Designed and built with all the love of Web
 */

function vIndexNav (opts) {
	opts = opts || {};
	this.opts = $.extend({
		offset: 0,
		onNav: function () {}
	}, opts);

	if (!opts.target) {
		throw new Error ('target param is required!');
	}

	this.targetWrapper = opts.target;
	this.lock = false;
	this.indexList = [];
	this.tipTimer = null;
	this.prevIndex = null;

	this.init();
}

vIndexNav.prototype.init = function () {
	this.render();
	var list = this.collectIndex();
	this.renderIndexList(list);
	this.getIndexDetail();
	this.bind();
}

vIndexNav.prototype.render = function () {
	var navTpl = '

';
	this.navWrapper = $(navTpl);
	this.navWrapper.addClass('v-index-nav');
	this.opts.target.append(this.navWrapper);

	var tipTpl = '

';
	this.tipEle = $(tipTpl);
	this.tipEle.addClass('v-nav-index-tip');
	this.opts.target.append(this.tipEle);
}

vIndexNav.prototype.collectIndex = function () {
	var list = []
	var targets = this.targetWrapper.find('[v-nav-index]');
	targets.each(function () {
		list.push($(this).attr('v-nav-index'));
	});

	return list;
}

vIndexNav.prototype.getIndexDetail = function () {
	var me = this;
	$('ul > li', this.navWrapper).each(function () {
		var item = {}
		item.index = $(this).text();
		item.position = $(this).offset().top - window.scrollY;
		item.height = $(this).height();

		me.indexList.push(item);
	});
}

vIndexNav.prototype.renderIndexList = function (list) {
	var tpl = [];
	list.forEach(function (item) {
		tpl.push('
' + item + '
');
	});

	$('ul', this.navWrapper).html(tpl.join(''));
}

vIndexNav.prototype.findIndex = function (pos) {
	var target = null;
	for(var i = 0, len = this.indexList.length; i < len; i++) {
		var item = this.indexList[i];
		var start = item.position;
		var end = start + item.height;
		if (pos >= start && pos <= end) {
			target = item;
			break;
		}
	}

	return target;
}

vIndexNav.prototype.showIndexTip = function (index) {
	if (this.tipTimer) {
		clearTimeout(this.tipTimer);
	}

	var me = this;

	this.tipEle.text(index).show();
	this.tipTimer = setTimeout(function () {
		me.tipEle.hide();
	}, 1000);
}

vIndexNav.prototype.moveTo = function (index) {
	var target = $('[v-nav-index]', this.targetWrapper).filter(function () {
		return $(this).attr('v-nav-index') === index;
	});

	if (target) {
		var top = target.offset().top;
		top += this.opts.offset;
		window.scrollTo(0, top);
	}
}

vIndexNav.prototype.nav = function (pos) {
	pos = pos - window.scrollY;
	var indexItem = this.findIndex(pos);
	if (indexItem && indexItem.index !== this.prevIndex) {
		this.prevIndex = indexItem.index;
		this.showIndexTip(indexItem.index);
		this.moveTo(indexItem.index);

		this.opts.onNav(indexItem.index);
	}
}

vIndexNav.prototype.bind = function () {
	var me = this;
	this.navWrapper.on('touchmove', function (e) {
		this.lock && e.preventDefault();
		me.nav(e.touches[0].pageY);
	});
	this.navWrapper.on('touchstart', function (e) {
		this.lock = true;
		me.nav(e.touches[0].pageY);
	});
	this.navWrapper.on('touchend', function (e) {
		this.lock = false;
	});
}<|endoftext|>


<commit_before>function MyCtrl($scope, $filter) {
  $scope.activeOptions = ['Yes', 'No'];

  $scope.items = [
    {id: 1, name: {first: "Marcin", last: "Warpechowski"}, address: "Schellingstr. 58, Muenchen", isActive: 'Yes', "Product": {
      "Description": "Big Mac",
      "Options": [
        {"Description": "Big Mac", "Image": "bigmac.png", Pick$: null},
        {"Description": "Big Mac & Co", "Image": "bigmacco.png", Pick$: null}
      ]}},
    {id: 2, name: {first: "John", last: "Irving"}, address: "Chengdu Road, Wanhua, Taipei 108", isActive: 'Yes', "Product": {
      "Description": "Fried Potatoes",
      "Options": [
        {"Description": "Fried Potatoes", "Image": "", Pick$: null},
        {"Description": "Fried Onions", "Image": "", Pick$: null}
      ]}},
    {id: 3, name: {first: "Jeremy", last: "Springsteen"}, address: "4 New York Plaza, New York, NY 10004", isActive: 'Yes', "Product": {
      "Description": "McRoyal",
      "Options": [
        {"Description": "McRoyal", "Image": "", Pick$: null},
        {"Description": "McRoyal with Cheese", "Image": "", Pick$: null}
      ]}}
  ];

  $scope.dumpItems = function () {
    console.log("dump items", $scope.items);
  }

  $scope.getOptions = function (options) {
    var out = []
    if (options !== null && typeof options === 'object' && options.length) {
      for (var i = 0, ilen = options.length; i < ilen; i++) {
        out.push(options[i].Description);
      }
    }
    return out;
  }

  /**
   * Filter
   */

  $scope.$watch('query', function (newVal, oldVal) {
    $scope.filteredItems = $filter('filter')($scope.items, $scope.query);
    $scope.dataChange = !$scope.dataChange;
  });

  /**
   * Selection
   */

  $scope.currentSelection = "None";

  $scope.$on('datagridSelection', function (scope, $container, r, p, r2, p2) {
    var ht = $container.data('handsontable');
    var str = "row '" + r + "' col '" + ht.propToCol(p) + "' (prop '" + p + "')";
    if (r !== r2 && p !== p2) {
      str = "From " + str + " to row '" + r2 + "' col '" + ht.propToCol(p2) + "' (prop '" + p2 + "')";
    }
    $scope.$apply(function () {
      $scope.currentSelection = str;
    });
  });
}<commit_msg>bugfix: filteredItems was undefined at page load<commit_after>function MyCtrl($scope, $filter) {
  $scope.activeOptions = ['Yes', 'No'];

  $scope.items = [
    {id: 1, name: {first: "Marcin", last: "Warpechowski"}, address: "Schellingstr. 58, Muenchen", isActive: 'Yes', "Product": {
      "Description": "Big Mac",
      "Options": [
        {"Description": "Big Mac", "Image": "bigmac.png", Pick$: null},
        {"Description": "Big Mac & Co", "Image": "bigmacco.png", Pick$: null}
      ]}},
    {id: 2, name: {first: "John", last: "Irving"}, address: "Chengdu Road, Wanhua, Taipei 108", isActive: 'Yes', "Product": {
      "Description": "Fried Potatoes",
      "Options": [
        {"Description": "Fried Potatoes", "Image": "", Pick$: null},
        {"Description": "Fried Onions", "Image": "", Pick$: null}
      ]}},
    {id: 3, name: {first: "Jeremy", last: "Springsteen"}, address: "4 New York Plaza, New York, NY 10004", isActive: 'Yes', "Product": {
      "Description": "McRoyal",
      "Options": [
        {"Description": "McRoyal", "Image": "", Pick$: null},
        {"Description": "McRoyal with Cheese", "Image": "", Pick$: null}
      ]}}
  ];

  $scope.dumpItems = function () {
    console.log("dump items", $scope.items);
  };

  $scope.getOptions = function (options) {
    var out = [];
    if (options !== null && typeof options === 'object' && options.length) {
      for (var i = 0, ilen = options.length; i < ilen; i++) {
        out.push(options[i].Description);
      }
    }
    return out;
  };

  /**
   * Filter
   */

  $scope.$watch('query', function (newVal, oldVal) {
    $scope.filteredItems = $filter('filter')($scope.items, $scope.query);
    $scope.dataChange = !$scope.dataChange;
  });
  $scope.filteredItems = $scope.items;

  /**
   * Selection
   */

  $scope.currentSelection = "None";

  $scope.$on('datagridSelection', function (scope, $container, r, p, r2, p2) {
    var ht = $container.data('handsontable');
    var str = "row '" + r + "' col '" + ht.propToCol(p) + "' (prop '" + p + "')";
    if (r !== r2 && p !== p2) {
      str = "From " + str + " to row '" + r2 + "' col '" + ht.propToCol(p2) + "' (prop '" + p2 + "')";
    }
    $scope.$apply(function () {
      $scope.currentSelection = str;
    });
  });
}<|endoftext|>


<commit_before>/*jslint nomen: true */
/*globals define: true */

define([
  'jquery',
  'lib/lodash',
  'backbone',

  // LocalData
  'settings',
  'api',

  // Views
  'views/design',
  'views/builder',
  'views/preview'
],

function($, _, Backbone, settings, api, DesignViews, BuilderViews, PreviewView) {
  'use strict';

  var FormViews = {};

  FormViews.FormView = Backbone.View.extend({

    el: '#form-view-container',

    initialize: function(options) {
      _.bindAll(this, 'render', 'showDesigner', 'showBuilder');
      console.log('Initializing forms view');
      this.el = options.el || '#form-view-container';

      this.survey = options.survey;
      this.forms = options.forms;
    },

    showDesigner: function() {
      $('#survey-design-container').empty();

      // If there isn't a form yet, let's show the survey creation view
      if (settings.formData === undefined) {

        $('#survey-form-tools-container').hide();

        $('.button').hide();

        var designView = new DesignViews.DesignView({
          el: '#survey-design-container',
          survey: this.survey
        });
        designView.render();

        designView.on('formAdded', this.render, this);

      }else {
        $('#survey-form-tools-container').show(); // hacky!

        // Preview the form if there already is one.
        this.previewView = new PreviewView({
          el: '#preview-view-container',
          forms: [settings.formData]
        });

      }
    },

    showBuilder: function() {
      // Hide the toolbar when in editing mode.
      // Maybe we'll want to animate this?
      $('#survey-form-tools-container').hide();

      this.builderView = new BuilderViews.BuilderView({
        forms: this.forms
      });
      this.builderView.render();

      this.builderView.on('formUpdated', function() {
        console.log('Builder: Telling preview to update...');
        console.log(this.previewView);
        this.previewView.render();
      }, this);

      this.listenTo(this.builderView, 'done', function () {
        $(this.builderView.el).html('');
        $('#survey-form-tools-container').show();
        this.builderView.stopListening();
        this.builderView = null;
      });
    },

    render: function() {
      var surveyJSON = this.survey.toJSON();
      var context = {
        survey: surveyJSON,
        forms: this.forms.toJSON(),
        mobile: 'http://' + window.location.host + '/mobile/#' + surveyJSON.slug
      };
      this.$el.html(_.template($('#form-view').html(), context));

      // old: Make sure we have up-to-date form data before showing the design view
      //api.getForm(this.showDesigner);

      // Show the editor
      $('.edit-form-button').click(this.showBuilder);
    }
  });

  return FormViews;
});
<commit_msg>No, we do want to show the form editor<commit_after>/*jslint nomen: true */
/*globals define: true */

define([
  'jquery',
  'lib/lodash',
  'backbone',

  // LocalData
  'settings',
  'api',

  // Views
  'views/design',
  'views/builder',
  'views/preview'
],

function($, _, Backbone, settings, api, DesignViews, BuilderViews, PreviewView) {
  'use strict';

  var FormViews = {};

  FormViews.FormView = Backbone.View.extend({

    el: '#form-view-container',

    initialize: function(options) {
      _.bindAll(this, 'render', 'showDesigner', 'showBuilder');
      console.log('Initializing forms view');
      this.el = options.el || '#form-view-container';

      this.survey = options.survey;
      this.forms = options.forms;
    },

    showDesigner: function() {
      $('#survey-design-container').empty();

      // If there isn't a form yet, let's show the survey creation view
      if (settings.formData === undefined) {

        $('#survey-form-tools-container').hide();

        $('.button').hide();

        var designView = new DesignViews.DesignView({
          el: '#survey-design-container',
          survey: this.survey
        });
        designView.render();

        designView.on('formAdded', this.render, this);

      }else {
        $('#survey-form-tools-container').show(); // hacky!

        // Preview the form if there already is one.
        this.previewView = new PreviewView({
          el: '#preview-view-container',
          forms: [settings.formData]
        });

      }
    },

    showBuilder: function() {
      // Hide the toolbar when in editing mode.
      // Maybe we'll want to animate this?
      $('#survey-form-tools-container').hide();

      this.builderView = new BuilderViews.BuilderView({
        forms: this.forms
      });
      this.builderView.render();

      this.builderView.on('formUpdated', function() {
        console.log('Builder: Telling preview to update...');
        console.log(this.previewView);
        this.previewView.render();
      }, this);

      this.listenTo(this.builderView, 'done', function () {
        $(this.builderView.el).html('');
        $('#survey-form-tools-container').show();
        this.builderView.stopListening();
        this.builderView = null;
      });
    },

    render: function() {
      var surveyJSON = this.survey.toJSON();
      var context = {
        survey: surveyJSON,
        forms: this.forms.toJSON(),
        mobile: 'http://' + window.location.host + '/mobile/#' + surveyJSON.slug
      };
      this.$el.html(_.template($('#form-view').html(), context));

      // old: Make sure we have up-to-date form data before showing the design view
      api.getForm(this.showDesigner);

      // Show the editor
      $('.edit-form-button').click(this.showBuilder);
    }
  });

  return FormViews;
});
<|endoftext|>


<commit_before>//the default theme used by all class if not expressly defined
Dbmng.defaults.theme=new Dbmng.AbstractTheme();

//the default theme used by all class if not expressly defined
Dbmng.defaults.aParam = {
  ui: {
    btn_edit: {label:'Edit'},
    btn_edit_inline: {label:'Edit inline'},
    btn_delete: {label:'Delete'},
    btn_insert: {label:'Insert'},
    btn_save: {label:'Save'},
    btn_cancel: {label:'Cancel'}
  },
  user_function: {
    inline:0, upd:1, del:1, ins:1
  }
};

// console.log(Dbmng.defaults.aParam );
<commit_msg>update<commit_after>//the default theme used by all class if not expressly defined
Dbmng.defaults.theme=new Dbmng.AbstractTheme();

//the default theme used by all class if not expressly defined
Dbmng.defaults.aParam = {
  ui: {
    btn_edit: {label:'Edit'},
    btn_edit_inline: {label:'Edit inline'},
    btn_delete: {label:'Delete'},
    btn_insert: {label:'Insert'},
    btn_save: {label:'Save'},
    btn_cancel: {label:'Cancel'}
  },
  user_function: {
    inline:0, upd:1, del:1, ins:1
  }
};
<|endoftext|>


<commit_before>World = {
	tileWidth		: 40,

	canvasCoord		: HTMLCanvasElement,
	canvasPeople	: HTMLCanvasElement,
	canvasSight		: HTMLCanvasElement,
	canvasObstacles	: HTMLCanvasElement,
	canvasWidth		: 0,
	canvasHeight	: 0,
	ctxCoord		: CanvasRenderingContext2D,
	ctxPeople		: CanvasRenderingContext2D,
	ctxSight		: CanvasRenderingContext2D,
	ctxObstacles	: CanvasRenderingContext2D,
	/** @type {Person} selectedMerc */
	selectedMerc	: Merc,

	_drawCoord		: true,
	_drawObstacles	: true,
	/** @type {Boolean} _drawSight */
	_drawSight		: null,

	init: function() {
		this.canvasCoord 		= document.getElementById('world-coord');
		this.ctxCoord 			= this.canvasCoord.getContext('2d');

		this.canvasPeople 		= document.getElementById('world-people');
		this.ctxPeople 			= this.canvasPeople.getContext('2d');

		this.canvasSight 		= document.getElementById('world-sight');
		this.ctxSight 			= this.canvasSight.getContext('2d');

		this.canvasObstacles 	= document.getElementById('world-obstacles');
		this.ctxObstacles		= this.canvasObstacles.getContext('2d');

		this.canvasWidth 	= this.canvasCoord.width;
		this.canvasHeight 	= this.canvasCoord.height;

		// keyboard
		window.addEventListener("keydown", function(e) {
			if(e.keyCode == 83 && ! this._drawSight) {
				// show sight
				this._drawSight = true;
				this.draw();
			}
		}.bind(this));

		window.addEventListener("keyup", function(e) {
			if(e.keyCode == 83) {
				// hide sight
				this._drawSight = false;
				this.draw();
			}
		}.bind(this));

		// obstacles
		var ob1 = new Obstacle(new Point(7, 7), 0.33);
		var ob2 = new Obstacle(new Point(7, 6), 0.66);
		var ob3 = new Obstacle(new Point(2, 3), 0.66);
		var ob4 = new Obstacle(new Point(9, 5), 0.66);
		var ob5 = new Obstacle(new Point(8, 3), 0.66);
		var ob6 = new Obstacle(new Point(8, 4), 0.66);
		var ob7 = new Obstacle(new Point(4, 2), 0.66);
		var ob8 = new Obstacle(new Point(2, 6), 0.66);
		var ob9 = new Obstacle(new Point(5, 8), 0.66);
		var ob10 = new Obstacle(new Point(5, 6), 0.66);
		var ob11 = new Obstacle(new Point(7, 2), 0.66);
		var ob12 = new Obstacle(new Point(6, 2), 0.66);
		var ob13 = new Obstacle(new Point(2, 7), 0.66);
		var ob14 = new Obstacle(new Point(3, 2), 0.66);

		World.OBSTACLES.push(ob1, ob2, ob3, ob4, ob5, ob6, ob7, ob8, ob9, ob10, ob11, ob12, ob13, ob14);

		this.draw();
	},

	addPeople: function() {
		for (var person in arguments) {
			if(arguments.hasOwnProperty(person)) {
				World.PEOPLE.push(arguments[person]);
			}

		}
	},

	/**
	 *
	 * @param {String} team
	 * @param {Person} person
	 */
	joinTeam: function(team, person) {
		World.TEAMS[team].push(person);
	},

	/**
	 *
	 * @param {Point|String} coordOrNickname coord or nickname
	 * @return {Person|null}
	 */
	getPerson: function(coordOrNickname) {
		var person;
		for(var i=0; i < this.PEOPLE.length; i++) {
			person = this.PEOPLE[i];
			if(person.isDead) break;

			if(coordOrNickname instanceof Point) {
				if(person.coord.x == coordOrNickname.x && person.coord.y == coordOrNickname.y)
					return person;
			} else {
				if(person.nickname.toLowerCase() == coordOrNickname.toLowerCase()) return person;
			}
		}

		return null;
	},

	/**
	 *
	 * @param {Point} coord
	 * @return {Obstacle|null}
	 */
	getObstacle: function(coord) {
		var obstacle;
		for(var i=0; i < this.OBSTACLES.length; i++) {
			obstacle = this.OBSTACLES[i];
			if(obstacle.x == coord.x && obstacle.y == coord.y)
				return obstacle;
		}

		return null;
	},

	draw: function() {
		this.ctxPeople.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
		this.ctxSight.clearRect(0, 0, this.canvasWidth, this.canvasHeight);

		if(this._drawObstacles) {
			this.ctxObstacles.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
		}

		// draw coordinates
		var maxX = this.canvasWidth / this.tileWidth;
		var maxY = this.canvasHeight / this.tileWidth;

		for(var y = 0; y < maxY; y++) {
			for(var x = 0; x < maxX; x++) {
				this._drawTile(new Point(x+1, y+1));
			}
		}

		this._drawObstacles = false;

		if(this._drawSight) {
			var sight = this.selectedMerc.calculateSight(), p;
			for(var i=0; i < sight.length; i++) {
				/** @param {Point} p */
				p = sight[i];
				x = (p.x - 1) * this.tileWidth;
				y = (p.y - 1) * this.tileWidth;

				if(p.obstacle) {
					function getAlpha(a, b) {
						var c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));

						// calculate alpha degree in triangle
						var alpha = Math.round(Math.asin(a/c) * (180 / Math.PI));
						if(alpha <= -90 || alpha >= 90) alpha = 0;

						return alpha;
					}

					var p1 = new Point(),
						p2 = new Point(),
						p3 = new Point(),
						a = 0, b = 0;

					switch(this.selectedMerc.direction) {
						case Person.EAST:
							a = p.y - this.selectedMerc.coord.y;
							b = p.x - this.selectedMerc.coord.x;

							p1 = new Point(p.x+1, p.y+1);
							p2 = new Point(p.x+1, p.y-1);
							p3 = new Point(p.x+1, p.y);
							break;
						case Person.WEST:
							a = p.y - this.selectedMerc.coord.y;
							b = p.x - this.selectedMerc.coord.x;

							p1 = new Point(p.x-1, p.y+1);
							p2 = new Point(p.x-1, p.y-1);
							p3 = new Point(p.x-1, p.y);
							break;
						case Person.NORTH:
							a = this.selectedMerc.coord.x - p.x;
							b = p.y - this.selectedMerc.coord.y;

							p1 = new Point(p.x-1, p.y-1);
							p2 = new Point(p.x+1, p.y-1);
							p3 = new Point(p.x, p.y-1);
							break;
						case Person.SOUTH:
							a = p.x - this.selectedMerc.coord.x;
							b = p.y - this.selectedMerc.coord.y;

							p1 = new Point(p.x+1, p.y+1);
							p2 = new Point(p.x-1, p.y+1);
							p3 = new Point(p.x, p.y+1);
							break;
					}

					var alpha = getAlpha(a, b);
					//if(this.selectedMerc.coord.x > p.x) alpha *= -1;

					console.log(p, alpha);

					if(alpha >= 34) {
						this._getPoint(sight, p1).color = '#CC0000';
					} else if(alpha <= -34) {
						this._getPoint(sight, p2).color = '#CC0000';
					} else {
						this._getPoint(sight, p3).color = '#CC0000';
					}
				}

				this.ctxSight.fillStyle = p.color;

				this.ctxSight.fillRect(x, y, this.tileWidth, this.tileWidth);
				this.ctxSight.fill();
			}
		}

		this._drawCoord = false;
	},

	/**
	 *
	 * @param {Array} list
	 * @param {Point} point
	 * @returns {Point|null}
	 * @private
	 */
	_getPoint: function(list, point) {
		for(var i=0; i < list.length; i++) {
			if(list[i].x == point.x && list[i].y == point.y) return list[i];
		}
		return new Point();
	},

	/**
	 *
	 * @param {Point} coord
	 * @private
	 */
	_drawTile: function(coord) {
		var xi = coord.x - 1, yi = coord.y - 1,
			x = xi * this.tileWidth, y = yi * this.tileWidth;

		// draw coordinate
		if(this._drawCoord) {
			this.ctxCoord.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
			this.ctxCoord.strokeStyle = "#EEE";
			this.ctxCoord.rect(x, y, this.tileWidth, this.tileWidth);
			this.ctxCoord.stroke();

			// draw field number
			//this.ctxCoord.font = "11px sans-serif";
			//this.ctxCoord.fillStyle = "#F1F1F1";
			//this.ctxCoord.fillText("("+ coord.x +"/"+ coord.y +")", x, y - 5);
		}

		// look for people
		var person = this.getPerson(coord);
		if(person) {
			this.ctxPeople.font = "11px sans-serif";
			var text = this.ctxPeople.measureText(person.nickname.substr(0, 1).toUpperCase());
			this.ctxPeople.fillText(person.nickname.substr(0, 1).toUpperCase(), x + ((this.tileWidth / 2) - (text.width / 2)), y + (this.tileWidth / 2) - 4, this.tileWidth);
			if(person.AP != Infinity) {
				this.ctxPeople.font = "9px sans-serif";
				text = this.ctxPeople.measureText("("+person.AP+")");
				this.ctxPeople.fillText("("+person.AP+")", x + ((this.tileWidth / 2) - (text.width / 2)), y + (this.tileWidth / 2) + 6, this.tileWidth);
			}
		}

		// obstacles
		if(this._drawObstacles) {
			this.ctxObstacles.font = "11px sans-serif";
			this.ctxObstacles.fillStyle = "#CCC";

			this.OBSTACLES.forEach(
				/** @param {Obstacle} obstacle */
				function(obstacle) {
					if(obstacle.x == coord.x && obstacle.y == coord.y) {
						var text = this.ctxObstacles.measureText("O");
						this.ctxObstacles.fillText("O", x + this.tileWidth - 12, y + this.tileWidth - 4, this.tileWidth);
					}
				}.bind(this)
			);

			//this._drawObstacles = false;
		}
	}
};

World.NIGHT 	= 'night';
World.EVENING 	= 'evening';
World.DAY		= 'day';
World.MORNING 	= 'morning';

World.daytime = World.DAY;

World.OBSTACLES = [];
World.PEOPLE = [];
World.TEAMS = {
	A: [],
	B: []
};<commit_msg>extended sight by shadow length<commit_after>World = {
	tileWidth		: 40,

	canvasCoord		: HTMLCanvasElement,
	canvasPeople	: HTMLCanvasElement,
	canvasSight		: HTMLCanvasElement,
	canvasObstacles	: HTMLCanvasElement,
	canvasWidth		: 0,
	canvasHeight	: 0,
	ctxCoord		: CanvasRenderingContext2D,
	ctxPeople		: CanvasRenderingContext2D,
	ctxSight		: CanvasRenderingContext2D,
	ctxObstacles	: CanvasRenderingContext2D,
	/** @type {Person} selectedMerc */
	selectedMerc	: Merc,

	_drawCoord		: true,
	_drawObstacles	: true,
	/** @type {Boolean} _drawSight */
	_drawSight		: null,

	init: function() {
		this.canvasCoord 		= document.getElementById('world-coord');
		this.ctxCoord 			= this.canvasCoord.getContext('2d');

		this.canvasPeople 		= document.getElementById('world-people');
		this.ctxPeople 			= this.canvasPeople.getContext('2d');

		this.canvasSight 		= document.getElementById('world-sight');
		this.ctxSight 			= this.canvasSight.getContext('2d');

		this.canvasObstacles 	= document.getElementById('world-obstacles');
		this.ctxObstacles		= this.canvasObstacles.getContext('2d');

		this.canvasWidth 	= this.canvasCoord.width;
		this.canvasHeight 	= this.canvasCoord.height;

		// keyboard
		window.addEventListener("keydown", function(e) {
			if(e.keyCode == 83 && ! this._drawSight) {
				// show sight
				this._drawSight = true;
				this.draw();
			}
		}.bind(this));

		window.addEventListener("keyup", function(e) {
			if(e.keyCode == 83) {
				// hide sight
				this._drawSight = false;
				this.draw();
			}
		}.bind(this));

		// obstacles
		var ob1 = new Obstacle(new Point(7, 7), 0.33);
		var ob2 = new Obstacle(new Point(7, 6), 0.66);
		var ob3 = new Obstacle(new Point(2, 3), 0.66);
		var ob4 = new Obstacle(new Point(9, 5), 0.66);
		var ob5 = new Obstacle(new Point(8, 3), 0.66);
		var ob6 = new Obstacle(new Point(8, 4), 0.66);
		var ob7 = new Obstacle(new Point(4, 2), 0.66);
		var ob8 = new Obstacle(new Point(2, 6), 0.66);
		var ob9 = new Obstacle(new Point(5, 8), 0.66);
		var ob10 = new Obstacle(new Point(5, 6), 0.66);
		var ob11 = new Obstacle(new Point(7, 2), 0.66);
		var ob12 = new Obstacle(new Point(6, 2), 0.66);
		var ob13 = new Obstacle(new Point(2, 7), 0.66);
		var ob14 = new Obstacle(new Point(3, 2), 0.66);

		World.OBSTACLES.push(ob1, ob2, ob3, ob4, ob5, ob6, ob7, ob8, ob9, ob10, ob11, ob12, ob13, ob14);

		this.draw();
	},

	addPeople: function() {
		for (var person in arguments) {
			if(arguments.hasOwnProperty(person)) {
				World.PEOPLE.push(arguments[person]);
			}

		}
	},

	/**
	 *
	 * @param {String} team
	 * @param {Person} person
	 */
	joinTeam: function(team, person) {
		World.TEAMS[team].push(person);
	},

	/**
	 *
	 * @param {Point|String} coordOrNickname coord or nickname
	 * @return {Person|null}
	 */
	getPerson: function(coordOrNickname) {
		var person;
		for(var i=0; i < this.PEOPLE.length; i++) {
			person = this.PEOPLE[i];
			if(person.isDead) break;

			if(coordOrNickname instanceof Point) {
				if(person.coord.x == coordOrNickname.x && person.coord.y == coordOrNickname.y)
					return person;
			} else {
				if(person.nickname.toLowerCase() == coordOrNickname.toLowerCase()) return person;
			}
		}

		return null;
	},

	/**
	 *
	 * @param {Point} coord
	 * @return {Obstacle|null}
	 */
	getObstacle: function(coord) {
		var obstacle;
		for(var i=0; i < this.OBSTACLES.length; i++) {
			obstacle = this.OBSTACLES[i];
			if(obstacle.x == coord.x && obstacle.y == coord.y)
				return obstacle;
		}

		return null;
	},

	draw: function() {
		this.ctxPeople.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
		this.ctxSight.clearRect(0, 0, this.canvasWidth, this.canvasHeight);

		if(this._drawObstacles) {
			this.ctxObstacles.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
		}

		// draw coordinates
		var maxX = this.canvasWidth / this.tileWidth;
		var maxY = this.canvasHeight / this.tileWidth;

		for(var y = 0; y < maxY; y++) {
			for(var x = 0; x < maxX; x++) {
				this._drawTile(new Point(x+1, y+1));
			}
		}

		this._drawObstacles = false;

		if(this._drawSight) {
			/** @type {Array} sight **/
			var sight = this.selectedMerc.calculateSight();
			/** @param {Point} p */
			var p;
			/** @type {Obstacle} obstacle **/
			var obstacle;
			var shadowLength = 1;

			for(var i=0; i < sight.length; i++) {
				p = sight[i];
				x = (p.x - 1) * this.tileWidth;
				y = (p.y - 1) * this.tileWidth;
				obstacle = p.obstacle;

				if(obstacle) {
					shadowLength = obstacle.shadowLength;

					function getAlpha(a, b) {
						var c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));

						// calculate alpha degree in triangle
						var alpha = Math.round(Math.asin(a/c) * (180 / Math.PI));
						if(alpha <= -90 || alpha >= 90) alpha = 0;

						return alpha;
					}

					var p1 = [],
						p2 = [],
						p3 = [],
						a = 0, b = 0;

					switch(this.selectedMerc.direction) {
						case Person.EAST:
							a = p.y - this.selectedMerc.coord.y;
							b = p.x - this.selectedMerc.coord.x;

							p1 = this._getPointsAdditions(p, 1, 1, shadowLength); // new Point(p.x+1, p.y+1);
							p2 = this._getPointsAdditions(p, 1, -1, shadowLength); // new Point(p.x+1, p.y-1);
							p3 = this._getPointsAdditions(p, 1, 0, shadowLength); // new Point(p.x+1, p.y);
							break;
						case Person.WEST:
							a = p.y - this.selectedMerc.coord.y;
							b = p.x - this.selectedMerc.coord.x;

							p1 = this._getPointsAdditions(p, -1, 1, shadowLength); // new Point(p.x-1, p.y+1);
							p2 = this._getPointsAdditions(p, -1, -1, shadowLength); // new Point(p.x-1, p.y-1);
							p3 = this._getPointsAdditions(p, -1, 0, shadowLength); // new Point(p.x-1, p.y);
							break;
						case Person.NORTH:
							a = this.selectedMerc.coord.x - p.x;
							b = p.y - this.selectedMerc.coord.y;

							p1 = this._getPointsAdditions(p, -1, -1, shadowLength); // new Point(p.x-1, p.y-1);
							p2 = this._getPointsAdditions(p, 1, -1, shadowLength); // new Point(p.x+1, p.y-1);
							p3 = this._getPointsAdditions(p, 0, -1, shadowLength); // new Point(p.x, p.y-1);
							break;
						case Person.SOUTH:
							a = p.x - this.selectedMerc.coord.x;
							b = p.y - this.selectedMerc.coord.y;

							p1 = this._getPointsAdditions(p, 1, 1, shadowLength); // new Point(p.x+1, p.y+1);
							p2 = this._getPointsAdditions(p, -1, 1, shadowLength); // new Point(p.x-1, p.y+1);
							p3 = this._getPointsAdditions(p, 0, 1, shadowLength); // new Point(p.x, p.y+1);
							break;
					}

					var alpha = getAlpha(a, b);

					console.log(p, alpha);

					/** @type {Array} points **/
					var points;

					if(alpha >= 34) {
						points = this._getPoints(sight, p1);
					} else if(alpha <= -34) {
						points = this._getPoints(sight, p2);
					} else {
						points = this._getPoints(sight, p3);
					}

					console.log("points", points);

					/** @type {Point} point */
					var point;
					for(var j=0; j < points.length; j++) {
						point = points[j];
						point.color = '#CC0000';
					}
				}

				this.ctxSight.fillStyle = p.color;

				this.ctxSight.fillRect(x, y, this.tileWidth, this.tileWidth);
				this.ctxSight.fill();
			}
		}

		this._drawCoord = false;
	},

	/**
	 *
	 * @param {Array} list
	 * @param {Point} point
	 * @returns {Point|null}
	 * @private
	 */
	_getPoint: function(list, point) {
		for(var i=0; i < list.length; i++) {
			if(list[i].x == point.x && list[i].y == point.y) return list[i];
		}
		return null;
	},

	/**
	 *
	 * @param {Array} list
	 * @param {Array} points
	 * @returns {Array}
	 * @private
	 */
	_getPoints: function(list, points) {
		/** @type {Point} point **/
		var point;
		var newPoints = [];
		for(var i=0; i < points.length; i++) {
			point = this._getPoint(list, points[i]);
			if(point) newPoints.push(point);
		}

		return newPoints;
	},

	/**
	 *
	 * @param {Point} point
	 * @param {number} addX
	 * @param {number} addY
	 * @param {number} length
	 * @private
	 */
	_getPointsAdditions: function(point, addX, addY, length) {
		var points = [];
		for(var i=0; i < length; i++) {
			points.push( new Point(point.x + addX, point.y + addY) );

			addX += addX == 0 ? 0 : addX > 0 ? 1 : -1;
			addY += addY == 0 ? 0 : addY > 0 ? 1 : -1;
		}

		return points;
	},

	/**
	 *
	 * @param {Point} coord
	 * @private
	 */
	_drawTile: function(coord) {
		var xi = coord.x - 1, yi = coord.y - 1,
			x = xi * this.tileWidth, y = yi * this.tileWidth;

		// draw coordinate
		if(this._drawCoord) {
			this.ctxCoord.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
			this.ctxCoord.strokeStyle = "#EEE";
			this.ctxCoord.rect(x, y, this.tileWidth, this.tileWidth);
			this.ctxCoord.stroke();

			// draw field number
			//this.ctxCoord.font = "11px sans-serif";
			//this.ctxCoord.fillStyle = "#F1F1F1";
			//this.ctxCoord.fillText("("+ coord.x +"/"+ coord.y +")", x, y - 5);
		}

		// look for people
		var person = this.getPerson(coord);
		if(person) {
			this.ctxPeople.font = "11px sans-serif";
			var text = this.ctxPeople.measureText(person.nickname.substr(0, 1).toUpperCase());
			this.ctxPeople.fillText(person.nickname.substr(0, 1).toUpperCase(), x + ((this.tileWidth / 2) - (text.width / 2)), y + (this.tileWidth / 2) - 4, this.tileWidth);
			if(person.AP != Infinity) {
				this.ctxPeople.font = "9px sans-serif";
				text = this.ctxPeople.measureText("("+person.AP+")");
				this.ctxPeople.fillText("("+person.AP+")", x + ((this.tileWidth / 2) - (text.width / 2)), y + (this.tileWidth / 2) + 6, this.tileWidth);
			}
		}

		// obstacles
		if(this._drawObstacles) {
			this.ctxObstacles.font = "11px sans-serif";
			this.ctxObstacles.fillStyle = "#CCC";

			this.OBSTACLES.forEach(
				/** @param {Obstacle} obstacle */
				function(obstacle) {
					if(obstacle.x == coord.x && obstacle.y == coord.y) {
						var text = this.ctxObstacles.measureText("O");
						this.ctxObstacles.fillText("O", x + this.tileWidth - 12, y + this.tileWidth - 4, this.tileWidth);
					}
				}.bind(this)
			);

			//this._drawObstacles = false;
		}
	}
};

World.NIGHT 	= 'night';
World.EVENING 	= 'evening';
World.DAY		= 'day';
World.MORNING 	= 'morning';

World.daytime = World.DAY;

World.OBSTACLES = [];
World.PEOPLE = [];
World.TEAMS = {
	A: [],
	B: []
};<|endoftext|>