<commit_before>/**
 * Created by liang on 2015/8/6.
 */
var _ = require("lodash"),
    moment = require("moment"),
    Promise = require("bluebird"),
    request = Promise.promisify(require("request")),
    parseString = require("xml2js").parseString,
    fs = Promise.promisifyAll(require("fs")),
    cronJob = require("cron").CronJob,
    filePath = __dirname + "/cnblog.json";

var cnblog = (function(){
    var json;
    return {
        get:function(){
            if(!json){
                return fs.readFileAsync(filePath,"utf8")
                    .then(JSON.parse)
                    .done();
                //updateCnblog(errorHandler);
            }
            return json;
        },
        set:function(j){
            json = j;
        }
    }
})();

function updateCnblog (errorHandler){
    return request("http://www.cnblogs.com/zhiyishou/rss")
        .spread(function(res,body){
            if(res.statusCode == 200){
                return Promise.promisify(parseString)(body);
            }else{
                return Promise.reject("Http request fail!");
            }
        })
        .then(function(result){
            var tempPublished,
                    tempObject,
                newEntry = [];

            _.map(result.feed.entry,function(entry){
                var object = {
                    title: entry.title[0]["_"].match(/.*(?=\s-)/)[0],
                    url: entry.link[0]["$"].href
                };

                tempObject = _.last(newEntry);
                tempPublished = moment(new Date(entry.published)).format("MMMM YYYY");
                if(tempObject && tempObject.published == tempPublished){
                    tempObject.entries.push(object);
                }else{
                    newEntry.push({
                        published: tempPublished,
                        entries: [object]
                    });
                }
            });

            return newEntry;
        })
        .then(function(result) {
            cnblog.set(result);
            return fs.writeFileAsync(filePath, JSON.stringify(result), "utf8");
        })
        .catch(errorHandler);
}

function errorHandler(){
    console.log(e);
    console.log("Will refetch again!");
    new cronJob("0 0 0 * * *",doJob,null,true,"Asia/Shanghai")
}

function doJob(){
    updateCnblog(errorHandler);
}

function cronUpdate(){
    new cronJob("0 0 0 * * *",doJob,null,true,"Asia/Shanghai")
}

function init(){
    cronUpdate();
}

exports.getCnblog = cnblog.get;
exports.init = init;

console.log(cnblog.get());
<commit_msg>add complete cnblog.js<commit_after>/**
 * Created by liang on 2015/8/6.
 */
var _ = require("lodash"),
    moment = require("moment"),
    Promise = require("bluebird"),
    request = Promise.promisify(require("request")),
    parseString = require("xml2js").parseString,
    fs = Promise.promisifyAll(require("fs")),
    cronJob = require("cron").CronJob,
    filePath = __dirname + "/cnblog.json";

var cnblog = (function(){
    var json;
    return {
        get:function(){
            if(!json){
                updateCnblog(errorHandler);
                return fs.readFileAsync(filePath,"utf8")
                    .then(JSON.parse);
            }
            return Promise.resolve(json);
        },
        set:function(j){
            json = j;
        }
    }
})();

function updateCnblog (errorHandler){
    return request("http://www.cnblogs.com/zhiyishou/rss")
        .spread(function(res,body){
            if(res.statusCode == 200){
                return Promise.promisify(parseString)(body);
            }else{
                return Promise.reject("Http request fail!");
            }
        })
        .then(function(result){
            var tempPublished,
                    tempObject,
                newEntry = [];

            _.map(result.feed.entry,function(entry){
                var object = {
                    title: entry.title[0]["_"].match(/.*(?=\s-)/)[0],
                    url: entry.link[0]["$"].href
                };

                tempObject = _.last(newEntry);
                tempPublished = moment(new Date(entry.published)).format("MMMM YYYY");
                if(tempObject && tempObject.published == tempPublished){
                    tempObject.entries.push(object);
                }else{
                    newEntry.push({
                        published: tempPublished,
                        entries: [object]
                    });
                }
            });

            return newEntry;
        })
        .then(function(result) {
            cnblog.set(result);
            return fs.writeFileAsync(filePath, JSON.stringify(result), "utf8");
        })
        .catch(errorHandler);
}

function errorHandler(){
    console.log(e);
    console.log("Will refetch again!");
    new cronJob("0 0 0 * * *",doJob,null,true,"Asia/Shanghai")
}

function doJob(){
    updateCnblog(errorHandler);
}

function cronUpdate(){
    new cronJob("0 0 0 * * *",doJob,null,true,"Asia/Shanghai")
}

function init(){
    cronUpdate();
}

exports.getCnblog = cnblog.get;
exports.init = init;

console.log(cnblog.get());
<|endoftext|>


<commit_before>/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 * @format
 */

import {type ViewConfig} from '../Renderer/shims/ReactNativeTypes';
// $FlowFixMe[nonstrict-import]
import getNativeComponentAttributes from '../ReactNative/getNativeComponentAttributes';
// $FlowFixMe[nonstrict-import]
import {createViewConfig} from './ViewConfig';
import {isIgnored} from './ViewConfigIgnore';

export type Difference =
  | {
      type: 'missing',
      path: Array<string>,
      nativeValue: mixed,
    }
  | {
      type: 'unequal',
      path: Array<string>,
      nativeValue: mixed,
      staticValue: mixed,
    }
  | {
      type: 'unexpected',
      path: Array<string>,
      staticValue: mixed,
    };

export type ValidationResult = ValidResult | InvalidResult;
type ValidResult = {
  type: 'valid',
};
type InvalidResult = {
  type: 'invalid',
  differences: Array<Difference>,
};

// e.g. require('MyNativeComponent') where MyNativeComponent.js exports a HostComponent
type JSModule = $FlowFixMe;

export function validateStaticViewConfigs(nativeComponent: JSModule): {
  componentName: string,
  nativeViewConfig?: ?ViewConfig,
  staticViewConfig?: ?ViewConfig,
  validationResult?: ?ValidationResult,
} {
  const nativeViewConfig = getNativeComponentAttributes(
    nativeComponent.default || nativeComponent,
  );

  const generatedPartialViewConfig = nativeComponent.__INTERNAL_VIEW_CONFIG;
  const staticViewConfig: ?ViewConfig =
    generatedPartialViewConfig && createViewConfig(generatedPartialViewConfig);

  const componentName: string = nativeComponent.default || nativeComponent;
  const validationResult: ?ValidationResult =
    nativeViewConfig &&
    staticViewConfig &&
    validate(componentName, nativeViewConfig, staticViewConfig);

  return {
    componentName,
    nativeViewConfig,
    staticViewConfig,
    validationResult,
  };
}

/**
 * During the migration from native view configs to static view configs, this is
 * used to validate that the two are equivalent.
 */
export function validate(
  name: string,
  nativeViewConfig: ViewConfig,
  staticViewConfig: ViewConfig,
): ValidationResult {
  const differences = [];
  accumulateDifferences(
    differences,
    [],
    {
      bubblingEventTypes: nativeViewConfig.bubblingEventTypes,
      directEventTypes: nativeViewConfig.directEventTypes,
      uiViewClassName: nativeViewConfig.uiViewClassName,
      validAttributes: nativeViewConfig.validAttributes,
    },
    {
      bubblingEventTypes: staticViewConfig.bubblingEventTypes,
      directEventTypes: staticViewConfig.directEventTypes,
      uiViewClassName: staticViewConfig.uiViewClassName,
      validAttributes: staticViewConfig.validAttributes,
    },
  );

  if (differences.length === 0) {
    return {type: 'valid'};
  }

  return {
    type: 'invalid',
    differences,
  };
}

export function stringifyValidationResult(
  name: string,
  validationResult: InvalidResult,
): string {
  const {differences} = validationResult;
  return [
    `StaticViewConfigValidator: Invalid static view config for '${name}'.`,
    '',
    ...differences.map(difference => {
      const {type, path} = difference;
      switch (type) {
        case 'missing':
          return `- '${path.join('.')}' is missing.`;
        case 'unequal':
          return `- '${path.join('.')}' is the wrong value.`;
        case 'unexpected':
          return `- '${path.join('.')}' is present but not expected to be.`;
      }
    }),
    '',
  ].join('\n');
}

function accumulateDifferences(
  differences: Array<Difference>,
  path: Array<string>,
  nativeObject: {...},
  staticObject: {...},
): void {
  for (const nativeKey in nativeObject) {
    const nativeValue = nativeObject[nativeKey];

    if (!staticObject.hasOwnProperty(nativeKey)) {
      differences.push({
        path: [...path, nativeKey],
        type: 'missing',
        nativeValue,
      });
      continue;
    }

    const staticValue = staticObject[nativeKey];

    const nativeValueIfObject = ifObject(nativeValue);
    if (nativeValueIfObject != null) {
      const staticValueIfObject = ifObject(staticValue);
      if (staticValueIfObject != null) {
        path.push(nativeKey);
        accumulateDifferences(
          differences,
          path,
          nativeValueIfObject,
          staticValueIfObject,
        );
        path.pop();
        continue;
      }
    }

    if (nativeValue !== staticValue) {
      differences.push({
        path: [...path, nativeKey],
        type: 'unequal',
        nativeValue,
        staticValue,
      });
    }
  }

  for (const staticKey in staticObject) {
    if (
      !nativeObject.hasOwnProperty(staticKey) &&
      !isIgnored(staticObject[staticKey])
    ) {
      differences.push({
        path: [...path, staticKey],
        type: 'unexpected',
        staticValue: staticObject[staticKey],
      });
    }
  }
}

function ifObject(value: mixed): ?{...} {
  return typeof value === 'object' && !Array.isArray(value) ? value : null;
}
<commit_msg>Move validateStaticViewConfigs to RNHostComponentList route<commit_after>/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 * @format
 */

import {type ViewConfig} from '../Renderer/shims/ReactNativeTypes';
import {isIgnored} from './ViewConfigIgnore';

export type Difference =
  | {
      type: 'missing',
      path: Array<string>,
      nativeValue: mixed,
    }
  | {
      type: 'unequal',
      path: Array<string>,
      nativeValue: mixed,
      staticValue: mixed,
    }
  | {
      type: 'unexpected',
      path: Array<string>,
      staticValue: mixed,
    };

export type ValidationResult = ValidResult | InvalidResult;
type ValidResult = {
  type: 'valid',
};
type InvalidResult = {
  type: 'invalid',
  differences: Array<Difference>,
};

/**
 * During the migration from native view configs to static view configs, this is
 * used to validate that the two are equivalent.
 */
export function validate(
  name: string,
  nativeViewConfig: ViewConfig,
  staticViewConfig: ViewConfig,
): ValidationResult {
  const differences = [];
  accumulateDifferences(
    differences,
    [],
    {
      bubblingEventTypes: nativeViewConfig.bubblingEventTypes,
      directEventTypes: nativeViewConfig.directEventTypes,
      uiViewClassName: nativeViewConfig.uiViewClassName,
      validAttributes: nativeViewConfig.validAttributes,
    },
    {
      bubblingEventTypes: staticViewConfig.bubblingEventTypes,
      directEventTypes: staticViewConfig.directEventTypes,
      uiViewClassName: staticViewConfig.uiViewClassName,
      validAttributes: staticViewConfig.validAttributes,
    },
  );

  if (differences.length === 0) {
    return {type: 'valid'};
  }

  return {
    type: 'invalid',
    differences,
  };
}

export function stringifyValidationResult(
  name: string,
  validationResult: InvalidResult,
): string {
  const {differences} = validationResult;
  return [
    `StaticViewConfigValidator: Invalid static view config for '${name}'.`,
    '',
    ...differences.map(difference => {
      const {type, path} = difference;
      switch (type) {
        case 'missing':
          return `- '${path.join('.')}' is missing.`;
        case 'unequal':
          return `- '${path.join('.')}' is the wrong value.`;
        case 'unexpected':
          return `- '${path.join('.')}' is present but not expected to be.`;
      }
    }),
    '',
  ].join('\n');
}

function accumulateDifferences(
  differences: Array<Difference>,
  path: Array<string>,
  nativeObject: {...},
  staticObject: {...},
): void {
  for (const nativeKey in nativeObject) {
    const nativeValue = nativeObject[nativeKey];

    if (!staticObject.hasOwnProperty(nativeKey)) {
      differences.push({
        path: [...path, nativeKey],
        type: 'missing',
        nativeValue,
      });
      continue;
    }

    const staticValue = staticObject[nativeKey];

    const nativeValueIfObject = ifObject(nativeValue);
    if (nativeValueIfObject != null) {
      const staticValueIfObject = ifObject(staticValue);
      if (staticValueIfObject != null) {
        path.push(nativeKey);
        accumulateDifferences(
          differences,
          path,
          nativeValueIfObject,
          staticValueIfObject,
        );
        path.pop();
        continue;
      }
    }

    if (nativeValue !== staticValue) {
      differences.push({
        path: [...path, nativeKey],
        type: 'unequal',
        nativeValue,
        staticValue,
      });
    }
  }

  for (const staticKey in staticObject) {
    if (
      !nativeObject.hasOwnProperty(staticKey) &&
      !isIgnored(staticObject[staticKey])
    ) {
      differences.push({
        path: [...path, staticKey],
        type: 'unexpected',
        staticValue: staticObject[staticKey],
      });
    }
  }
}

function ifObject(value: mixed): ?{...} {
  return typeof value === 'object' && !Array.isArray(value) ? value : null;
}
<|endoftext|>


<commit_before>const THREE = require('three')
const CANNON = require('cannon')
  // const PointerLockControls = require('./PointerLockControls');
import store from '../store';

import { PointerLockControls } from './PointerLockControls';
import Player from './Player'
import Bomb from './Bomb'

import { Particle, Block } from './Explosion.js';

import Maps from './maps/maps'

import generateMap from './utils/generateMap';

var sphereShape, sphereBody, world, physicsMaterial;
var camera, scene, renderer, light;
var geometry, material, mesh;
var controls, time = Date.now();
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;

export let walls = [];
export let bombs = [];
export let ballMeshes = [];
export let boxes = [];
export let boxMeshes = [];
export let destroyableBoxes = [];
export let destroyableBoxMeshes = [];
export let players = [];
export let playerMeshes = [];
export let yourBombs = [];
export let yourballMeshes = [];

var blocks = new Array();
var blockCount = 25;

export function initCannon() {
  //     // Setup our world
  if (socket) {
    socket.emit('get_players', {});
  }
  world = new CANNON.World();
  world.quatNormalizeSkip = 0;
  world.quatNormalizeFast = false;
  var solver = new CANNON.GSSolver();
  world.defaultContactMaterial.contactEquationStiffness = 1e9;
  world.defaultContactMaterial.contactEquationRelaxation = 4;
  solver.iterations = 7;
  solver.tolerance = 0.1;
  var split = true;
  if (split)
    world.solver = new CANNON.SplitSolver(solver);
  else
    world.solver = solver;
  world.gravity.set(0, -20, 0);
  world.broadphase = new CANNON.NaiveBroadphase();

  //     // Create a slippery material (friction coefficient = 0.0)
  physicsMaterial = new CANNON.Material("slipperyMaterial");
  var physicsContactMaterial = new CANNON.ContactMaterial(physicsMaterial,
    physicsMaterial,
    0.0, // friction coefficient
    0.3 // restitution
  );
  //     // We must add the contact materials to the world
  world.addContactMaterial(physicsContactMaterial);

  //     // Create a sphere
  var mass = 5,
    radius = 1.3;
  sphereShape = new CANNON.Sphere(radius);
  sphereBody = new CANNON.Body({ mass: mass });
  sphereBody.addShape(sphereShape);
  sphereBody.position.set(0, 5, 0);
  sphereBody.linearDamping = 0.9;
  world.addBody(sphereBody);

  // Create a plane
  var groundShape = new CANNON.Plane();
  var groundBody = new CANNON.Body({ mass: 0 });
  groundBody.addShape(groundShape);
  groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
  world.addBody(groundBody);
}

// SHOOTING BOMBS HERE

// cannon sphere(radius)
var ballShape = new CANNON.Sphere(1.5);

// three sphere(radius, numFaces per xyz) higher num means rounder sphere
// 32 should be enough for spheres
var ballGeometry = new THREE.SphereGeometry(ballShape.radius, 32, 32);

// generates a vector with no units if you want units you input
// Vector3(x,y,z)
var shootDirection = new THREE.Vector3();

// speed of ball (m/s maybe?)
var shootVelo = 15;

export function init() {
  camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(0, 3, 0)
  scene = new THREE.Scene();
  scene.fog = new THREE.Fog(0x000000, 0, 500);
  var ambient = new THREE.AmbientLight(0xffffff);
  scene.add(ambient);
  light = new THREE.SpotLight(0xffffff);
  light.position.set(10, 30, 20);
  light.target.position.set(0, 5, 0);
  // if(true){
  //     light.castShadow = false;
  //     light.shadowCameraNear = 20;
  //     light.shadowCameraFar = 50;//camera.far;
  //     light.shadowCameraFov = 40;
  //     light.shadowMapBias = 0.1;
  //     light.shadowMapDarkness = 0.7;
  //     light.shadowMapWidth = 2*512;
  //     light.shadowMapHeight = 2*512;
  //     light.shadowCameraVisible = true;
  // }
  scene.add(light);

  // this attaches bomb to the player (maybe)
  // look at PointerLockControls function
  // sphereBody.position = (0,5,0) so the sphere should be 5+ in y direction above camera

  controls = new PointerLockControls(camera, sphereBody);
  scene.add(controls.getObject());

  // floor
  geometry = new THREE.PlaneBufferGeometry(125, 125, 50, 50);
  geometry.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI / 2));
  material = new THREE.MeshLambertMaterial({ color: 0x3f7cba });
  mesh = new THREE.Mesh(geometry, material);
  mesh.castShadow = true;
  mesh.receiveShadow = true;
  scene.add(mesh);

  // Init Blocks
  for (var i = 0; i < blockCount; i++) {
    var block = new Block(scene, world);
    blocks.push(block);
  }

  renderer = new THREE.WebGLRenderer();
  // renderer.shadowMapEnabled = true;
  // renderer.shadowMapSoft = true;
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setClearColor(scene.fog.color, 1);
  document.body.appendChild(renderer.domElement);
  window.addEventListener('resize', onWindowResize, false);

  createMap();
  sphereBody.position.x = 0;
  sphereBody.position.y = 10;
  sphereBody.position.z = 0;

  let others = store.getState().players.otherPlayers.players;
  let newPlayer;
  if (socket) {
    socket.emit('update_players_position', {
      position: {
        x: sphereBody.position.x,
        y: sphereBody.position.y,
        z: sphereBody.position.z
      },
      id: socket.id
    });
  }
  for (var player in others) {
    newPlayer = new Player(socket.id, others[player].x, others[player].y, others[player].z)
    newPlayer.init()
    players.push(newPlayer.playerBox)
    playerMeshes.push(newPlayer.playerMesh)

  }

  // add event listen to actually shoot
  if (controls) {
    window.addEventListener("click", function(e) {
      if (controls.enabled == true) {
        // because sphereBody position is dependent on camera position
        let x = sphereBody.position.x;
        let y = sphereBody.position.y;
        let z = sphereBody.position.z;

        const newBomb = new Bomb(Math.random(), { x: x, y: y, z: z });
        newBomb.init()
        //take just the id and position of the ball
        //stack overflow from sending bombBody?
        const bombInfo = { id: newBomb.bombBody.id, position: newBomb.bombBody.position, created: Date.now() }

        // push it into our global bombs array

        socket.emit('add_bomb', {
          userId: socket.id,
          position: { x: x, y: y, z: z }
        })

        yourBombs.push(bombInfo)
        // push ball meshes
        yourballMeshes.push(newBomb.bombMesh);

        // get its direction using getShootDir function
        // returns shootDirection altered with correct data
        getShootDir(shootDirection);

        // console.log(newBomb.bombBody)
        // give it a velocity
        // shootVelo is global defined as 15
        newBomb.bombBody.velocity.set(shootDirection.x * shootVelo,
          shootDirection.y * shootVelo,
          shootDirection.z * shootVelo);

        // Move the ball outside the player sphere
        // not sure about this shit here
        // x,y,z adjusted so it's actually updating the position of the sphere
        x += shootDirection.x * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
        y += shootDirection.y * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
        z += shootDirection.z * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
        newBomb.bombBody.position.set(x, y, z);
        newBomb.bombMesh.position.set(x, y, z);
      }
    });
  }
}

export function createMap() {
  let map0 = Maps[0]
  generateMap(map0);
}

export function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

var dt = 1 / 60; // change in time for walking

// animate the walking and the box positions movements

export function animate() {

  setTimeout(() => {
    if (socket) {
      socket.emit('update_players_position', {
        position: {
          x: sphereBody.position.x,
          y: sphereBody.position.y,
          z: sphereBody.position.z
        },
        id: socket.id
      });
      if (bombs.length) {
        socket.emit('update_bomb_positions', {
          userId: socket.id,
          bombs: yourBombs
        })
      }
    }
    requestAnimationFrame(animate);
  }, 1000 / 60)

  if (controls.enabled) {
    world.step(dt); // function that allows walking from CANNON

    // Update ball positions
    // the bombs in our game

    // UPDATES PLAYERS HERE

    let others = store.getState().players.otherPlayers;
    let playerIds = Object.keys(others)

    let state = store.getState();
    let allBombs = state.bombs.allBombs;
    let stateBombs = [];
    console.log('allBombs', allBombs)

    for (let key in allBombs) {
      stateBombs.push(...allBombs[key])
    }

    if (playerIds.length !== players.length) {
      players = [];
      playerMeshes = [];
      for (let player in others) {
        let newPlayer;
        newPlayer = new Player(socket.id, others[player].x, others[player].y, others[player].z)
        newPlayer.init()
        players.push(newPlayer.playerBox)
        playerMeshes.push(newPlayer.playerMesh)
        newPlayer.playerMesh.castShadow = true;
        newPlayer.playerMesh.receiveShadow = true;
      }
    }

    for (let i = 0; i < players.length; i++) {
      let { x, y, z } = others[playerIds[i]]
      playerMeshes[i].position.set(x, y, z);
      players[i].position.x = x;
      players[i].position.y = y;
      players[i].position.z = z;
    }

    for (var i = 0; i < blockCount; i++) {
      blocks[i].loop();
    }

    // add new bomb if there is one
    //we are only adding to the bombs array and bombMesh array when we receive back from the update bombs socket emitter, not when we first create the bomb
    if (stateBombs.length > bombs.length) {
      const mostRecentBomb = stateBombs[stateBombs.length - 1]
      const newBomb = new Bomb(mostRecentBomb.id, mostRecentBomb.position)
      newBomb.init()

      bombs.push(newBomb.bombBody)
      ballMeshes.push(newBomb.bombMesh)
    }

    for (let i = 0; i < bombs.length; i++) {
      let { x, y, z } = stateBombs[i].position
      ballMeshes[i].position.copy(bombs[i].position)
      bombs[i].position.x = x;
      bombs[i].position.y = y;
      bombs[i].position.z = z;
      // bombs[i].position.copy(stateBombs[i].position)
    }

    for (let i = 0; i < yourBombs.length; i++) {
      yourballMeshes[i].position.copy(yourBombs[i].position)
    }

    // Update box positions
    // for(let i=0; i<destroyableBoxes.length; i++){
    //     destroyableBoxMeshes[i].position.set(destroyableBoxes[i].position);
    // }

  }

  controls.update(Date.now() - time);
  renderer.render(scene, camera);
  time = Date.now();
}

// this is outdated should use raycaster instead since it gives more info anyway
// also projector is moved.
// to adjust to use raycaster we need to adjust yawObject and pitch object

TODO: // HERE
  var projector = new THREE.Projector();

// get shoot direction might need to be adjusted to use ray caster instead
const getShootDir = function(targetVec) {
  var vector = targetVec;
  targetVec.set(0, 0, 1);
  projector.unprojectVector(vector, camera);
  var ray = new THREE.Ray(sphereBody.position, vector.sub(sphereBody.position).normalize());
  targetVec.copy(ray.direction);
}

export { scene, camera, renderer, controls, light, getShootDir, world }
<commit_msg>Update main.js<commit_after>const THREE = require('three')
const CANNON = require('cannon')
  // const PointerLockControls = require('./PointerLockControls');
import store from '../store';

import { PointerLockControls } from './PointerLockControls';
import Player from './Player'
import Bomb from './Bomb'

import { Particle, Block } from './Explosion.js';

import Maps from './maps/maps'

import generateMap from './utils/generateMap';

var sphereShape, sphereBody, world, physicsMaterial;
var camera, scene, renderer, light;
var geometry, material, mesh;
var controls, time = Date.now();
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;

export let walls = [];
export let bombs = [];
export let ballMeshes = [];
export let boxes = [];
export let boxMeshes = [];
export let destroyableBoxes = [];
export let destroyableBoxMeshes = [];
export let players = [];
export let playerMeshes = [];
export let yourBombs = [];
export let yourballMeshes = [];

var blocks = new Array();
var blockCount = 25;

export function initCannon() {
  //     // Setup our world
  if (socket) {
    socket.emit('get_players', {});
  }
  world = new CANNON.World();
  world.quatNormalizeSkip = 0;
  world.quatNormalizeFast = false;
  var solver = new CANNON.GSSolver();
  world.defaultContactMaterial.contactEquationStiffness = 1e9;
  world.defaultContactMaterial.contactEquationRelaxation = 4;
  solver.iterations = 7;
  solver.tolerance = 0.1;
  var split = true;
  if (split)
    world.solver = new CANNON.SplitSolver(solver);
  else
    world.solver = solver;
  world.gravity.set(0, -20, 0);
  world.broadphase = new CANNON.NaiveBroadphase();

  //     // Create a slippery material (friction coefficient = 0.0)
  physicsMaterial = new CANNON.Material("slipperyMaterial");
  var physicsContactMaterial = new CANNON.ContactMaterial(physicsMaterial,
    physicsMaterial,
    0.0, // friction coefficient
    0.3 // restitution
  );
  //     // We must add the contact materials to the world
  world.addContactMaterial(physicsContactMaterial);

  //     // Create a sphere
  var mass = 5,
    radius = 1.3;
  sphereShape = new CANNON.Sphere(radius);
  sphereBody = new CANNON.Body({ mass: mass });
  sphereBody.addShape(sphereShape);
  sphereBody.position.set(0, 5, 0);
  sphereBody.linearDamping = 0.9;
  world.addBody(sphereBody);

  // Create a plane
  var groundShape = new CANNON.Plane();
  var groundBody = new CANNON.Body({ mass: 0 });
  groundBody.addShape(groundShape);
  groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
  world.addBody(groundBody);
}

// SHOOTING BOMBS HERE

// cannon sphere(radius)
var ballShape = new CANNON.Sphere(1.5);

// three sphere(radius, numFaces per xyz) higher num means rounder sphere
// 32 should be enough for spheres
var ballGeometry = new THREE.SphereGeometry(ballShape.radius, 32, 32);

// generates a vector with no units if you want units you input
// Vector3(x,y,z)
var shootDirection = new THREE.Vector3();

// speed of ball (m/s maybe?)
var shootVelo = 15;

export function init() {
  camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(0, 3, 0)
  scene = new THREE.Scene();
  scene.fog = new THREE.Fog(0x000000, 0, 500);
  var ambient = new THREE.AmbientLight(0xffffff);
  scene.add(ambient);
  light = new THREE.SpotLight(0xffffff);
  light.position.set(10, 30, 20);
  light.target.position.set(0, 5, 0);
  // if(true){
  //     light.castShadow = false;
  //     light.shadowCameraNear = 20;
  //     light.shadowCameraFar = 50;//camera.far;
  //     light.shadowCameraFov = 40;
  //     light.shadowMapBias = 0.1;
  //     light.shadowMapDarkness = 0.7;
  //     light.shadowMapWidth = 2*512;
  //     light.shadowMapHeight = 2*512;
  //     light.shadowCameraVisible = true;
  // }
  scene.add(light);

  // this attaches bomb to the player (maybe)
  // look at PointerLockControls function
  // sphereBody.position = (0,5,0) so the sphere should be 5+ in y direction above camera

  controls = new PointerLockControls(camera, sphereBody);
  scene.add(controls.getObject());

  // floor
  geometry = new THREE.PlaneBufferGeometry(125, 125, 50, 50);
  geometry.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI / 2));
  material = new THREE.MeshLambertMaterial({ color: 0x3f7cba });
  mesh = new THREE.Mesh(geometry, material);
  mesh.castShadow = true;
  mesh.receiveShadow = true;
  scene.add(mesh);

  // Init Blocks
  for (var i = 0; i < blockCount; i++) {
    var block = new Block(scene, world);
    blocks.push(block);
  }

  renderer = new THREE.WebGLRenderer();
  // renderer.shadowMapEnabled = true;
  // renderer.shadowMapSoft = true;
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setClearColor(scene.fog.color, 1);
  document.body.appendChild(renderer.domElement);
  window.addEventListener('resize', onWindowResize, false);

  createMap();
  sphereBody.position.x = 0;
  sphereBody.position.y = 10;
  sphereBody.position.z = 0;

  let others = store.getState().players.otherPlayers.players;
  let newPlayer;
  if (socket) {
    socket.emit('update_players_position', {
      position: {
        x: sphereBody.position.x,
        y: sphereBody.position.y,
        z: sphereBody.position.z
      },
      id: socket.id
    });
  }
  for (var player in others) {
    newPlayer = new Player(socket.id, others[player].x, others[player].y, others[player].z)
    newPlayer.init()
    players.push(newPlayer.playerBox)
    playerMeshes.push(newPlayer.playerMesh)

  }

  // add event listen to actually shoot
  if (controls) {
    window.addEventListener("click", function(e) {
      if (controls.enabled == true) {
        // because sphereBody position is dependent on camera position
        let x = sphereBody.position.x;
        let y = sphereBody.position.y;
        let z = sphereBody.position.z;

        const newBomb = new Bomb(Math.random(), { x: x, y: y, z: z });
        newBomb.init()
        //take just the id and position of the ball
        //stack overflow from sending bombBody?
        const bombInfo = { id: newBomb.bombBody.id, position: newBomb.bombBody.position, created: Date.now() }

        // push it into our global bombs array

        socket.emit('add_bomb', {
          userId: socket.id,
          position: { x: x, y: y, z: z }
        })

        yourBombs.push(bombInfo)
        // push ball meshes
        yourballMeshes.push(newBomb.bombMesh);

        // get its direction using getShootDir function
        // returns shootDirection altered with correct data
        getShootDir(shootDirection);

        // console.log(newBomb.bombBody)
        // give it a velocity
        // shootVelo is global defined as 15
        newBomb.bombBody.velocity.set(shootDirection.x * shootVelo,
          shootDirection.y * shootVelo,
          shootDirection.z * shootVelo);

        // Move the ball outside the player sphere
        // not sure about this shit here
        // x,y,z adjusted so it's actually updating the position of the sphere
        x += shootDirection.x * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
        y += shootDirection.y * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
        z += shootDirection.z * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
        newBomb.bombBody.position.set(x, y, z);
        newBomb.bombMesh.position.set(x, y, z);
      }
    });
  }
}

export function createMap() {
  let map0 = Maps[0]
  generateMap(map0);
}

export function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

var dt = 1 / 60; // change in time for walking

// animate the walking and the box positions movements

export function animate() {

  setTimeout(() => {
    if (socket) {
      socket.emit('update_players_position', {
        position: {
          x: sphereBody.position.x,
          y: sphereBody.position.y,
          z: sphereBody.position.z
        },
        id: socket.id
      });
      if (bombs.length) {
        socket.emit('update_bomb_positions', {
          userId: socket.id,
          bombs: yourBombs
        })
      }
    }
    requestAnimationFrame(animate);
  }, 1000 / 60)

  if (controls.enabled) {
    world.step(dt); // function that allows walking from CANNON

    // Update ball positions
    // the bombs in our game

    // UPDATES PLAYERS HERE

    let others = store.getState().players.otherPlayers;
    let playerIds = Object.keys(others)

    let state = store.getState();
    let allBombs = state.bombs.allBombs;
    let stateBombs = [];

    for (let key in allBombs) {
      stateBombs.push(...allBombs[key])
    }

    if (playerIds.length !== players.length) {
      players = [];
      playerMeshes = [];
      for (let player in others) {
        let newPlayer;
        newPlayer = new Player(socket.id, others[player].x, others[player].y, others[player].z)
        newPlayer.init()
        players.push(newPlayer.playerBox)
        playerMeshes.push(newPlayer.playerMesh)
        newPlayer.playerMesh.castShadow = true;
        newPlayer.playerMesh.receiveShadow = true;
      }
    }

    for (let i = 0; i < players.length; i++) {
      let { x, y, z } = others[playerIds[i]]
      playerMeshes[i].position.set(x, y, z);
      players[i].position.x = x;
      players[i].position.y = y;
      players[i].position.z = z;
    }

    for (var i = 0; i < blockCount; i++) {
      blocks[i].loop();
    }

    // add new bomb if there is one
    //we are only adding to the bombs array and bombMesh array when we receive back from the update bombs socket emitter, not when we first create the bomb
    if (stateBombs.length > bombs.length) {
      const mostRecentBomb = stateBombs[stateBombs.length - 1]
      const newBomb = new Bomb(mostRecentBomb.id, mostRecentBomb.position)
      newBomb.init()

      bombs.push(newBomb.bombBody)
      ballMeshes.push(newBomb.bombMesh)
    }

    for (let i = 0; i < bombs.length; i++) {
      let { x, y, z } = stateBombs[i].position
      ballMeshes[i].position.copy(bombs[i].position)
      bombs[i].position.x = x;
      bombs[i].position.y = y;
      bombs[i].position.z = z;
      // bombs[i].position.copy(stateBombs[i].position)
    }

    for (let i = 0; i < yourBombs.length; i++) {
      yourballMeshes[i].position.copy(yourBombs[i].position)
    }

    // Update box positions
    // for(let i=0; i<destroyableBoxes.length; i++){
    //     destroyableBoxMeshes[i].position.set(destroyableBoxes[i].position);
    // }

  }

  controls.update(Date.now() - time);
  renderer.render(scene, camera);
  time = Date.now();
}

// this is outdated should use raycaster instead since it gives more info anyway
// also projector is moved.
// to adjust to use raycaster we need to adjust yawObject and pitch object

TODO: // HERE
  var projector = new THREE.Projector();

// get shoot direction might need to be adjusted to use ray caster instead
const getShootDir = function(targetVec) {
  var vector = targetVec;
  targetVec.set(0, 0, 1);
  projector.unprojectVector(vector, camera);
  var ray = new THREE.Ray(sphereBody.position, vector.sub(sphereBody.position).normalize());
  targetVec.copy(ray.direction);
}

export { scene, camera, renderer, controls, light, getShootDir, world }
<|endoftext|>


<commit_before>/**
 * @module modules/commit-detail-sk
 * @description
commit-detail-sk

 *
 * An element to display information around a single commit.
 *
 * The element takes as data a serialized cid.CommitDetail.
 *
 */
import { html, render } from 'lit-html';
import { $$ } from 'common-sk/modules/dom.js';
import { upgradeProperty } from 'elements-sk/upgradeProperty';

const template = (ele) => html`

 ele._click(e)} class=linkish>
${ele.cid.message}

  Explore
  Cluster
  Triage
  Commit

`;

window.customElements.define('commit-detail-sk', class extends HTMLElement {
  constructor() {
    super();
    this._cid = {};
  }

  connectedCallback() {
    upgradeProperty(this, 'cid');
    this._render();
  }

  _render() {
    render(template(this), this);
  }

  _click() {
    $$('.tip', this).classList.toggle('hidden');
  }

  /** @prop cid {Object} cid.CommitId. */
  get cid() { return this._cid }
  set cid(val) {
    this._cid = val;
    this._render();
  }

});
<commit_msg>Perf - Remove unused id from commit-detail-sk.<commit_after>/**
 * @module modules/commit-detail-sk
 * @description
commit-detail-sk

 *
 * An element to display information around a single commit.
 *
 * The element takes as data a serialized cid.CommitDetail.
 *
 */
import { html, render } from 'lit-html';
import { $$ } from 'common-sk/modules/dom.js';
import { upgradeProperty } from 'elements-sk/upgradeProperty';

const template = (ele) => html`

 ele._click(e)} class=linkish>
${ele.cid.message}

  Explore
  Cluster
  Triage
  Commit

`;

window.customElements.define('commit-detail-sk', class extends HTMLElement {
  constructor() {
    super();
    this._cid = {};
  }

  connectedCallback() {
    upgradeProperty(this, 'cid');
    this._render();
  }

  _render() {
    render(template(this), this);
  }

  _click() {
    $$('.tip', this).classList.toggle('hidden');
  }

  /** @prop cid {Object} cid.CommitId. */
  get cid() { return this._cid }
  set cid(val) {
    this._cid = val;
    this._render();
  }

});
<|endoftext|>


<commit_before>import * as THREE from 'three'
import * as CANNON from 'cannon'

import store from '../redux/store'

import socket, { playerArr } from '../socket'

import { PointerLockControls } from './PointerLockControls'

import Player from './Player'
import Bomb from './Bomb'
import {
  animateFire,
  animatePlayers,
  animateExplosion,
  animateBombs,
  deleteWorld,
  createMap,
  getShootDir
} from './utils'

let sphereShape, world, physicsMaterial;
let camera, scene, renderer, light;
let geometry, material, mesh;
let controls, time = Date.now();
let clock;

export let listener;
export let sphereBody;
export let walls = [];
export let bombs = [];
export let bombMeshes = [];
export let boxes = [];
export let boxMeshes = [];
export let players = [];
export let playerMeshes = [];
export let yourBombs = [];
export let yourBombMeshes = [];
export let playerInstances = [];
export const blocksObj = {};
export const blockCount = 50;

let bombObjects = [];
let count = 1;
let dead = false;
let nickname = '';
let allowBomb = true;
const dt = 1 / 60;
let prevStateLength = 0;
let counter = 0;
const spawnPositions = [
  { x: 11.5, y: 1.5, z: -4 },
  { x: -36, y: 1.5, z: 36 },
  { x: 12.1, y: 1.5, z: 36.4 },
  { x: -36.4, y: 1.5, z: -4 },
]
const bombMaterial = new THREE.MeshPhongMaterial({
  color: 0x000000,
  specular: 0x050505,
  shininess: 100
})

export function initCannon() {
  /*----- SETS UP WORLD & CHECKS FOR OTHER PLAYERS -----*/
  if (socket) { socket.emit('get_players', {}); }

  world = new CANNON.World();
  world.quatNormalizeSkip = 0;
  world.quatNormalizeFast = false;
  const solver = new CANNON.GSSolver();
  world.defaultContactMaterial.contactEquationStiffness = 1e9;
  world.defaultContactMaterial.contactEquationRelaxation = 4;
  solver.iterations = 7;
  solver.tolerance = 0.1;
  const split = true;

  if (split) { world.solver = new CANNON.SplitSolver(solver); }
  else { world.solver = solver; }

  /*----- INCREASE SOLVER ITERATIONS (DEF: 10) -----*/
  world.solver.iterations = 20;

  /*----- FORCE SOLVER TO USE ALL ITERATIONS -----*/
  world.solver.tolerance = 0;
  world.gravity.set(0, -40, 0);
  world.broadphase = new CANNON.NaiveBroadphase();
  physicsMaterial = new CANNON.Material('groundMaterial');

  /*----- ADJUSTS CONSTRAINT EQUATION PARAMS FOR GROUND/GROUND CONTACT -----*/
  const physicsContactMaterial = new CANNON.ContactMaterial(physicsMaterial, physicsMaterial, {
    friction: 0.7,
    restitution: 0.3,
    contactEquationStiffness: 1e8,
    contactEquationRelaxation: 3,
    frictionEquationStiffness: 1e8,
    frictionEquationRegularizationTime: 3,
  });

  /*----- ADD CONTACT MATERIALS TO WORLD -----*/
  world.addContactMaterial(physicsContactMaterial);

  /*----- CREATE A SPHERE -----*/
  const mass = 100;
  const radius = 1.3;
  sphereShape = new CANNON.Sphere(radius);
  sphereBody = new CANNON.Body({ mass: mass, material: physicsMaterial });
  sphereBody.addShape(sphereShape);
  sphereBody.position.set(0, 5, 0);
  sphereBody.linearDamping = 0.9;
  world.addBody(sphereBody);

  /*----- CREATE A PLANE -----*/
  const groundShape = new CANNON.Plane();
  const groundBody = new CANNON.Body({ mass: 0 });
  groundBody.addShape(groundShape);
  groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
  world.addBody(groundBody);
}

/*----- CANNON SPHERE RADIUS -----*/
const ballShape = new CANNON.Sphere(1.5);
const ballGeometry = new THREE.SphereGeometry(ballShape.radius, 32, 32);
const shootDirection = new THREE.Vector3();
const shootVelo = 8;

const projector = new THREE.Projector();

export function init() {
  camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1500);
  camera.position.set(0, 3, 0)
  scene = new THREE.Scene();
  const ambient = new THREE.AmbientLight(0xffffff);
  scene.add(ambient);
  light = new THREE.SpotLight(0xffffff);
  light.position.set(10, 30, 20);
  light.target.position.set(0, 5, 0);
  scene.add(light);

  /*----- CREATE CLOCK FOR FIRE ANIMATION -----*/
  clock = new THREE.Clock()

  controls = new PointerLockControls(camera, sphereBody);
  scene.add(controls.getObject());

  /*----- FLOOR -----*/
  geometry = new THREE.PlaneBufferGeometry(125, 125, 50, 50);
  geometry.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI / 2));
  const texture = new THREE.TextureLoader().load('images/grass.png');
  material = new THREE.MeshLambertMaterial({ map: texture });

  /*----- REPEAT TEXTURE TILING FOR FLOOR -----*/
  texture.wrapS = THREE.RepeatWrapping;
  texture.wrapT = THREE.RepeatWrapping;
  texture.repeat.x = 20;
  texture.repeat.y = 20;
  mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  /*----- SKYBOX -----*/
  const skyGeo = new THREE.SphereGeometry(1000, 32, 32);
  const skyMaterial = new THREE.MeshBasicMaterial({ color: '#00bfff' });
  const sky = new THREE.Mesh(skyGeo, skyMaterial);
  sky.material.side = THREE.BackSide;
  scene.add(sky);

  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  window.addEventListener('resize', onWindowResize, false);

  createMap();

  sphereBody.position.x = 100;
  sphereBody.position.y = 100;
  sphereBody.position.z = 100;
  listener = new THREE.AudioListener();
  camera.add(listener);

  const others = store.getState().players;
  let newPlayer;

  for (let player in others) {
    if (others[player].nickname) {
      newPlayer = new Player(player, others[player].x, others[player].y, others[player].z, others[player].dead, others[player].nickname)
      newPlayer.init()
      players.push(newPlayer.playerBox)
      playerMeshes.push(newPlayer.playerMesh)
      playerInstances.push(newPlayer)
    }
  }

  function shootBomb(velocity) {
    if (controls.enabled == true && !dead && allowBomb) {
      /*----- GET CURRENT POSITION TO SHOOT -----*/
      let x = sphereBody.position.x;
      let y = sphereBody.position.y;
      let z = sphereBody.position.z;

      const newBomb = new Bomb(count++, { x, y, z }, bombMaterial, socket.id);
      newBomb.init()
      allowBomb = false;
      setTimeout(() => {
        allowBomb = true;
      }, 3000)

      /*----- EMIT RELEVANT BOMB INFO -----*/
      const bombInfo = { id: newBomb.id, position: newBomb.bombBody.position, created: Date.now() }

      socket.emit('add_bomb', {
        userId: socket.id,
        bombId: bombInfo.id,
        position: { x, y, z }
      })

      /*----- REMOVE FROM YOUR FRONTEND BOMBS ARR -----*/
      /*----- WILL UPDATE GAMESTATE ON NEXT FRAME -----*/
      setTimeout(() => {
        yourBombs = yourBombs.filter((bomb) => {
          return bomb.id !== bombInfo.id
        })
        yourBombMeshes = yourBombMeshes.filter(mesh => {
          return newBomb.bombMesh.id !== mesh.id
        })
      }, 1800)

      /*----- ADD BOMB & MESH TO YOUR BOMBS ARR -----*/
      yourBombs.push(bombInfo)
      bombObjects.push(newBomb)
      yourBombMeshes.push(newBomb.bombMesh);

      /*----- GET DIRECTION USING FUNCTION -----*/
      getShootDir(projector, camera, shootDirection);

      /*----- GIVES BOMB A SHOOT VELOCITY -----*/
      newBomb.bombBody.velocity.set(shootDirection.x * velocity,
        shootDirection.y * velocity,
        shootDirection.z * velocity);

      /*----- SHOOT YOUR BOMB -----*/
      x += shootDirection.x * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
      y += shootDirection.y * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
      z += shootDirection.z * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
      newBomb.bombBody.position.set(x, y, z);
      newBomb.bombMesh.position.set(x, y, z);
    }
  }

  if (controls) {
    window.addEventListener('click', (e) => {
      shootBomb(shootVelo)
    })
    window.addEventListener('keydown', (event) => {
      if (event.keyCode === 32) {
        shootBomb(40)
      }
    })
  }

  /*----- PLAYERS STILL RECEIVE GAMESTATE WHEN INACTIVE-----*/
  setInterval(() => {
    if (socket) {
      socket.emit('update_world', {
        playerId: socket.id,
        playerPosition: {
          x: sphereBody.position.x,
          y: sphereBody.position.y,
          z: sphereBody.position.z
        },
        dead: dead,
        playerBombs: yourBombs
      });
    }
    counter++;

    /*----- SETS PLAYER SPAWN AFTER GETTING INIT STATE FROM SOCKETS -----*/
    if (counter === 50) {
      sphereBody.position.x = spawnPositions[playerArr.indexOf(socket.id)].x;
      sphereBody.position.y = 5
      sphereBody.position.z = spawnPositions[playerArr.indexOf(socket.id)].z;
    }

    /*----- ALLOWS WALKING IN CANNONJS -----*/
    world.step(dt);

    /*----- GETS CURRENT STATE -----*/
    const state = store.getState();
    const others = state.players;
    const playerIds = Object.keys(others)
    const allBombs = state.bombs;
    const stateBombs = [];

    for (let key in allBombs) {
      let userBombs = allBombs[key].map((bomb) => {
        bomb.userId = key
        return bomb
      })
      stateBombs.push(...userBombs)
    }

    if (playerIds.length !== players.length) {
      players.forEach(body => {
        world.remove(body)
      })

      playerMeshes.forEach(playermesh => {
        scene.remove(playermesh)
      })
      players = [];
      playerMeshes = [];
      playerInstances = [];
      for (let player in others) {
        /*----- CHECKS IF PLAYER HAS NICKNAME BEFORE CREATING NEW PLAYER -----*/
        if (others[player].nickname) {
          let newPlayer;
          newPlayer = new Player(player, others[player].x, others[player].y, others[player].z, false)
          newPlayer.init()

          players.push(newPlayer.playerBox)
          playerMeshes.push(newPlayer.playerMesh)
          playerInstances.push(newPlayer)
        }
      }
    }

    /*----- ADDS NEW BOMB IF THERE IS ONE -----*/
    if (stateBombs.length > prevStateLength) {
      const mostRecentBomb = stateBombs[stateBombs.length - 1]
      const newBomb = new Bomb(mostRecentBomb.id, mostRecentBomb.position, bombMaterial, mostRecentBomb.userId)
      newBomb.init()

      bombs.push(newBomb.bombBody)
      bombObjects.push(newBomb)
      bombMeshes.push(newBomb.bombMesh)
    }
    /*----- RESTS PREV STATE LENGTH -----*/
    prevStateLength = stateBombs.length

    /*----- ANIMATE FIRE W/ BOMB -----*/
    dead = animateFire(bombObjects, clock, dead)

    /*----- UPDATE PLAYER POSITIONS -----*/
    animatePlayers(players, playerIds, others, playerMeshes)

    /*----- ANIMATE EXPLOSION PARTICLES -----*/
    animateExplosion(blocksObj)

    /*----- ANIMATE BOMB POSITIONS -----*/
    animateBombs(yourBombs, yourBombMeshes, bombs, stateBombs, bombMeshes, prevStateLength)

  }, 1000 / 60)
}

export function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

/*----- ANIMATION GAME LOOP & THROTTLE LOOP-----*/
export function animate() {
  setTimeout(() => {
    requestAnimationFrame(animate);
  }, 1000 / 60)

  controls.update(Date.now() - time);
  renderer.render(scene, camera);
  time = Date.now();
}

/*----- CLEAR AND REBUILD MAP TO RESTART & RESPAWN PLAYER -----*/
export function restartWorld() {
  deleteWorld(scene, world, boxMeshes, boxes, bombs, bombMeshes, yourBombs, bombObjects, yourBombMeshes, players, playerMeshes);

  boxMeshes = [];
  boxes = [];
  bombs = [];
  bombMeshes = [];
  yourBombs = [];
  bombObjects = [];
  yourBombMeshes = [];
  players = [];
  playerMeshes = [];
  playerInstances = [];

  createMap();

  sphereBody.position.x = spawnPositions[playerArr.indexOf(socket.id)].x;
  sphereBody.position.y = 5;
  sphereBody.position.z = spawnPositions[playerArr.indexOf(socket.id)].z;
  dead = false;
}

export {
  scene,
  camera,
  renderer,
  controls,
  light,
  world,
  dead
}
<commit_msg>deleted new lines<commit_after>import * as THREE from 'three'
import * as CANNON from 'cannon'

import store from '../redux/store'
import socket, { playerArr } from '../socket'
import { PointerLockControls } from './PointerLockControls'

import Player from './Player'
import Bomb from './Bomb'
import {
  animateFire,
  animatePlayers,
  animateExplosion,
  animateBombs,
  deleteWorld,
  createMap,
  getShootDir
} from './utils'

let sphereShape, world, physicsMaterial;
let camera, scene, renderer, light;
let geometry, material, mesh;
let controls, time = Date.now();
let clock;

export let listener;
export let sphereBody;
export let walls = [];
export let bombs = [];
export let bombMeshes = [];
export let boxes = [];
export let boxMeshes = [];
export let players = [];
export let playerMeshes = [];
export let yourBombs = [];
export let yourBombMeshes = [];
export let playerInstances = [];
export const blocksObj = {};
export const blockCount = 50;

let bombObjects = [];
let count = 1;
let dead = false;
let nickname = '';
let allowBomb = true;
const dt = 1 / 60;
let prevStateLength = 0;
let counter = 0;
const spawnPositions = [
  { x: 11.5, y: 1.5, z: -4 },
  { x: -36, y: 1.5, z: 36 },
  { x: 12.1, y: 1.5, z: 36.4 },
  { x: -36.4, y: 1.5, z: -4 },
]
const bombMaterial = new THREE.MeshPhongMaterial({
  color: 0x000000,
  specular: 0x050505,
  shininess: 100
})

export function initCannon() {
  /*----- SETS UP WORLD & CHECKS FOR OTHER PLAYERS -----*/
  if (socket) { socket.emit('get_players', {}); }

  world = new CANNON.World();
  world.quatNormalizeSkip = 0;
  world.quatNormalizeFast = false;
  const solver = new CANNON.GSSolver();
  world.defaultContactMaterial.contactEquationStiffness = 1e9;
  world.defaultContactMaterial.contactEquationRelaxation = 4;
  solver.iterations = 7;
  solver.tolerance = 0.1;
  const split = true;

  if (split) { world.solver = new CANNON.SplitSolver(solver); }
  else { world.solver = solver; }

  /*----- INCREASE SOLVER ITERATIONS (DEF: 10) -----*/
  world.solver.iterations = 20;

  /*----- FORCE SOLVER TO USE ALL ITERATIONS -----*/
  world.solver.tolerance = 0;
  world.gravity.set(0, -40, 0);
  world.broadphase = new CANNON.NaiveBroadphase();
  physicsMaterial = new CANNON.Material('groundMaterial');

  /*----- ADJUSTS CONSTRAINT EQUATION PARAMS FOR GROUND/GROUND CONTACT -----*/
  const physicsContactMaterial = new CANNON.ContactMaterial(physicsMaterial, physicsMaterial, {
    friction: 0.7,
    restitution: 0.3,
    contactEquationStiffness: 1e8,
    contactEquationRelaxation: 3,
    frictionEquationStiffness: 1e8,
    frictionEquationRegularizationTime: 3,
  });

  /*----- ADD CONTACT MATERIALS TO WORLD -----*/
  world.addContactMaterial(physicsContactMaterial);

  /*----- CREATE A SPHERE -----*/
  const mass = 100;
  const radius = 1.3;
  sphereShape = new CANNON.Sphere(radius);
  sphereBody = new CANNON.Body({ mass: mass, material: physicsMaterial });
  sphereBody.addShape(sphereShape);
  sphereBody.position.set(0, 5, 0);
  sphereBody.linearDamping = 0.9;
  world.addBody(sphereBody);

  /*----- CREATE A PLANE -----*/
  const groundShape = new CANNON.Plane();
  const groundBody = new CANNON.Body({ mass: 0 });
  groundBody.addShape(groundShape);
  groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);
  world.addBody(groundBody);
}

/*----- CANNON SPHERE RADIUS -----*/
const ballShape = new CANNON.Sphere(1.5);
const ballGeometry = new THREE.SphereGeometry(ballShape.radius, 32, 32);
const shootDirection = new THREE.Vector3();
const shootVelo = 8;

const projector = new THREE.Projector();

export function init() {
  camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1500);
  camera.position.set(0, 3, 0)
  scene = new THREE.Scene();
  const ambient = new THREE.AmbientLight(0xffffff);
  scene.add(ambient);
  light = new THREE.SpotLight(0xffffff);
  light.position.set(10, 30, 20);
  light.target.position.set(0, 5, 0);
  scene.add(light);

  /*----- CREATE CLOCK FOR FIRE ANIMATION -----*/
  clock = new THREE.Clock()

  controls = new PointerLockControls(camera, sphereBody);
  scene.add(controls.getObject());

  /*----- FLOOR -----*/
  geometry = new THREE.PlaneBufferGeometry(125, 125, 50, 50);
  geometry.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI / 2));
  const texture = new THREE.TextureLoader().load('images/grass.png');
  material = new THREE.MeshLambertMaterial({ map: texture });

  /*----- REPEAT TEXTURE TILING FOR FLOOR -----*/
  texture.wrapS = THREE.RepeatWrapping;
  texture.wrapT = THREE.RepeatWrapping;
  texture.repeat.x = 20;
  texture.repeat.y = 20;
  mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  /*----- SKYBOX -----*/
  const skyGeo = new THREE.SphereGeometry(1000, 32, 32);
  const skyMaterial = new THREE.MeshBasicMaterial({ color: '#00bfff' });
  const sky = new THREE.Mesh(skyGeo, skyMaterial);
  sky.material.side = THREE.BackSide;
  scene.add(sky);

  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  window.addEventListener('resize', onWindowResize, false);

  createMap();

  sphereBody.position.x = 100;
  sphereBody.position.y = 100;
  sphereBody.position.z = 100;
  listener = new THREE.AudioListener();
  camera.add(listener);

  const others = store.getState().players;
  let newPlayer;

  for (let player in others) {
    if (others[player].nickname) {
      newPlayer = new Player(player, others[player].x, others[player].y, others[player].z, others[player].dead, others[player].nickname)
      newPlayer.init()
      players.push(newPlayer.playerBox)
      playerMeshes.push(newPlayer.playerMesh)
      playerInstances.push(newPlayer)
    }
  }

  function shootBomb(velocity) {
    if (controls.enabled == true && !dead && allowBomb) {
      /*----- GET CURRENT POSITION TO SHOOT -----*/
      let x = sphereBody.position.x;
      let y = sphereBody.position.y;
      let z = sphereBody.position.z;

      const newBomb = new Bomb(count++, { x, y, z }, bombMaterial, socket.id);
      newBomb.init()
      allowBomb = false;
      setTimeout(() => {
        allowBomb = true;
      }, 3000)

      /*----- EMIT RELEVANT BOMB INFO -----*/
      const bombInfo = { id: newBomb.id, position: newBomb.bombBody.position, created: Date.now() }

      socket.emit('add_bomb', {
        userId: socket.id,
        bombId: bombInfo.id,
        position: { x, y, z }
      })

      /*----- REMOVE FROM YOUR FRONTEND BOMBS ARR -----*/
      /*----- WILL UPDATE GAMESTATE ON NEXT FRAME -----*/
      setTimeout(() => {
        yourBombs = yourBombs.filter((bomb) => {
          return bomb.id !== bombInfo.id
        })
        yourBombMeshes = yourBombMeshes.filter(mesh => {
          return newBomb.bombMesh.id !== mesh.id
        })
      }, 1800)

      /*----- ADD BOMB & MESH TO YOUR BOMBS ARR -----*/
      yourBombs.push(bombInfo)
      bombObjects.push(newBomb)
      yourBombMeshes.push(newBomb.bombMesh);

      /*----- GET DIRECTION USING FUNCTION -----*/
      getShootDir(projector, camera, shootDirection);

      /*----- GIVES BOMB A SHOOT VELOCITY -----*/
      newBomb.bombBody.velocity.set(shootDirection.x * velocity,
        shootDirection.y * velocity,
        shootDirection.z * velocity);

      /*----- SHOOT YOUR BOMB -----*/
      x += shootDirection.x * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
      y += shootDirection.y * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
      z += shootDirection.z * (sphereShape.radius * 1.02 + newBomb.bombShape.radius);
      newBomb.bombBody.position.set(x, y, z);
      newBomb.bombMesh.position.set(x, y, z);
    }
  }

  if (controls) {
    window.addEventListener('click', (e) => {
      shootBomb(shootVelo)
    })
    window.addEventListener('keydown', (event) => {
      if (event.keyCode === 32) {
        shootBomb(40)
      }
    })
  }

  /*----- PLAYERS STILL RECEIVE GAMESTATE WHEN INACTIVE-----*/
  setInterval(() => {
    if (socket) {
      socket.emit('update_world', {
        playerId: socket.id,
        playerPosition: {
          x: sphereBody.position.x,
          y: sphereBody.position.y,
          z: sphereBody.position.z
        },
        dead: dead,
        playerBombs: yourBombs
      });
    }
    counter++;

    /*----- SETS PLAYER SPAWN AFTER GETTING INIT STATE FROM SOCKETS -----*/
    if (counter === 50) {
      sphereBody.position.x = spawnPositions[playerArr.indexOf(socket.id)].x;
      sphereBody.position.y = 5
      sphereBody.position.z = spawnPositions[playerArr.indexOf(socket.id)].z;
    }

    /*----- ALLOWS WALKING IN CANNONJS -----*/
    world.step(dt);

    /*----- GETS CURRENT STATE -----*/
    const state = store.getState();
    const others = state.players;
    const playerIds = Object.keys(others)
    const allBombs = state.bombs;
    const stateBombs = [];

    for (let key in allBombs) {
      let userBombs = allBombs[key].map((bomb) => {
        bomb.userId = key
        return bomb
      })
      stateBombs.push(...userBombs)
    }

    if (playerIds.length !== players.length) {
      players.forEach(body => {
        world.remove(body)
      })

      playerMeshes.forEach(playermesh => {
        scene.remove(playermesh)
      })
      players = [];
      playerMeshes = [];
      playerInstances = [];
      for (let player in others) {
        /*----- CHECKS IF PLAYER HAS NICKNAME BEFORE CREATING NEW PLAYER -----*/
        if (others[player].nickname) {
          let newPlayer;
          newPlayer = new Player(player, others[player].x, others[player].y, others[player].z, false)
          newPlayer.init()

          players.push(newPlayer.playerBox)
          playerMeshes.push(newPlayer.playerMesh)
          playerInstances.push(newPlayer)
        }
      }
    }

    /*----- ADDS NEW BOMB IF THERE IS ONE -----*/
    if (stateBombs.length > prevStateLength) {
      const mostRecentBomb = stateBombs[stateBombs.length - 1]
      const newBomb = new Bomb(mostRecentBomb.id, mostRecentBomb.position, bombMaterial, mostRecentBomb.userId)
      newBomb.init()

      bombs.push(newBomb.bombBody)
      bombObjects.push(newBomb)
      bombMeshes.push(newBomb.bombMesh)
    }
    /*----- RESTS PREV STATE LENGTH -----*/
    prevStateLength = stateBombs.length

    /*----- ANIMATE FIRE W/ BOMB -----*/
    dead = animateFire(bombObjects, clock, dead)

    /*----- UPDATE PLAYER POSITIONS -----*/
    animatePlayers(players, playerIds, others, playerMeshes)

    /*----- ANIMATE EXPLOSION PARTICLES -----*/
    animateExplosion(blocksObj)

    /*----- ANIMATE BOMB POSITIONS -----*/
    animateBombs(yourBombs, yourBombMeshes, bombs, stateBombs, bombMeshes, prevStateLength)

  }, 1000 / 60)
}

export function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

/*----- ANIMATION GAME LOOP & THROTTLE LOOP-----*/
export function animate() {
  setTimeout(() => {
    requestAnimationFrame(animate);
  }, 1000 / 60)

  controls.update(Date.now() - time);
  renderer.render(scene, camera);
  time = Date.now();
}

/*----- CLEAR AND REBUILD MAP TO RESTART & RESPAWN PLAYER -----*/
export function restartWorld() {
  deleteWorld(scene, world, boxMeshes, boxes, bombs, bombMeshes, yourBombs, bombObjects, yourBombMeshes, players, playerMeshes);

  boxMeshes = [];
  boxes = [];
  bombs = [];
  bombMeshes = [];
  yourBombs = [];
  bombObjects = [];
  yourBombMeshes = [];
  players = [];
  playerMeshes = [];
  playerInstances = [];

  createMap();

  sphereBody.position.x = spawnPositions[playerArr.indexOf(socket.id)].x;
  sphereBody.position.y = 5;
  sphereBody.position.z = spawnPositions[playerArr.indexOf(socket.id)].z;
  dead = false;
}

export {
  scene,
  camera,
  renderer,
  controls,
  light,
  world,
  dead
}
<|endoftext|>


<commit_before>exports.BattleScripts = {
	init: function () {
		this.modData('Pokedex', 'archeops').abilities['1'] = 'Vital Spirit';
		this.modData('Pokedex', 'porygonz').types = ['Normal', 'Ghost'];
		this.modData('Pokedex', 'weezing').types = ['Poison', 'Steel'];
		this.modData('Pokedex', 'moltres').abilities['1'] = 'Magic Guard';
		this.modData('Pokedex', 'abomasnowmega').abilities['0'] = 'Technician';
		this.modData('Pokedex', 'cradily').abilities['1'] = 'Sand Stream';
		this.modData('Pokedex', 'froslass').abilities['1'] = 'Prankster';
		this.modData('Learnsets', 'absol').learnset.partingshot = ['6T'];
		this.modData('Pokedex', 'goodra').abilities['1'] = 'Protean';
		this.modData('Pokedex', 'entei').abilities['1'] = 'Defiant';
		this.modData('Pokedex', 'milotic').abilities['H'] = 'Multiscale';
		this.modData('Pokedex', 'empoleon').abilities['1'] = 'Lightning Rod';
		this.modData('Learnsets', 'reuniclus').learnset.voltswitch = ['6T'];
		this.modData('Pokedex', 'steelixmega').abilities['0'] = 'Arena Trap';
		this.modData('Pokedex', 'audinomega').abilities['0'] = 'Simple';
		this.modData('Learnsets', 'ampharos').learnset.wish = ['6T'];
		this.modData('Pokedex', 'absolmega').types = ['Dark', 'Fairy'];
		this.modData('Pokedex', 'weavile').abilities['1'] = 'Moxie';
		this.modData('Learnsets', 'pangoro').learnset.suckerpunch = ['6T'];
		this.modData('Pokedex', 'rotomfan').types = ['Electric', 'Steel'];
		this.modData('Learnsets', 'rotomfan').learnset.flashcannon = this.data.Learnsets.rotomfan.learnset.airslash;
		this.modData('Learnsets', 'rotomfan').learnset.airslash = null;
		this.modData('Learnsets', 'mantine').learnset.roost = ['6T'];
		this.modData('Learnsets', 'pidgeot').learnset.focusblast = ['6T'];
		this.modData('Pokedex', 'granbull').abilities['1'] = 'Fur Coat';
		this.modData('Pokedex', 'aggronmega').types = ['Steel', 'Dragon'];
		this.modData('Learnsets', 'floatzel').learnset.bellydrum = ['6T'];
		this.modData('Pokedex', 'forretress').abilities['1'] = 'Water Absorb';
	}
};
<commit_msg>Add latest Theorymon winner<commit_after>exports.BattleScripts = {
	init: function () {
		this.modData('Pokedex', 'archeops').abilities['1'] = 'Vital Spirit';
		this.modData('Pokedex', 'porygonz').types = ['Normal', 'Ghost'];
		this.modData('Pokedex', 'weezing').types = ['Poison', 'Steel'];
		this.modData('Pokedex', 'moltres').abilities['1'] = 'Magic Guard';
		this.modData('Pokedex', 'abomasnowmega').abilities['0'] = 'Technician';
		this.modData('Pokedex', 'cradily').abilities['1'] = 'Sand Stream';
		this.modData('Pokedex', 'froslass').abilities['1'] = 'Prankster';
		this.modData('Learnsets', 'absol').learnset.partingshot = ['6T'];
		this.modData('Pokedex', 'goodra').abilities['1'] = 'Protean';
		this.modData('Pokedex', 'entei').abilities['1'] = 'Defiant';
		this.modData('Pokedex', 'milotic').abilities['H'] = 'Multiscale';
		this.modData('Pokedex', 'empoleon').abilities['1'] = 'Lightning Rod';
		this.modData('Learnsets', 'reuniclus').learnset.voltswitch = ['6T'];
		this.modData('Pokedex', 'steelixmega').abilities['0'] = 'Arena Trap';
		this.modData('Pokedex', 'audinomega').abilities['0'] = 'Simple';
		this.modData('Learnsets', 'ampharos').learnset.wish = ['6T'];
		this.modData('Pokedex', 'absolmega').types = ['Dark', 'Fairy'];
		this.modData('Pokedex', 'weavile').abilities['1'] = 'Moxie';
		this.modData('Learnsets', 'pangoro').learnset.suckerpunch = ['6T'];
		this.modData('Pokedex', 'rotomfan').types = ['Electric', 'Steel'];
		this.modData('Learnsets', 'rotomfan').learnset.flashcannon = this.data.Learnsets.rotomfan.learnset.airslash;
		this.modData('Learnsets', 'rotomfan').learnset.airslash = null;
		this.modData('Learnsets', 'mantine').learnset.roost = ['6T'];
		this.modData('Learnsets', 'pidgeot').learnset.focusblast = ['6T'];
		this.modData('Pokedex', 'granbull').abilities['1'] = 'Fur Coat';
		this.modData('Pokedex', 'aggronmega').types = ['Steel', 'Dragon'];
		this.modData('Learnsets', 'floatzel').learnset.bellydrum = ['6T'];
		this.modData('Pokedex', 'forretress').abilities['1'] = 'Water Absorb';
		this.modData('Learnsets', 'bronzong').learnset.recover = ['6T'];
	}
};
<|endoftext|>


<commit_before>import Context from './context';
import imageUtils from './image';

function SVGCanvasElement(options) {

    this.ctx = new Context(options);
    this.svg = this.ctx.__root;

    // sync attributes to svg
    var svg = this.svg;
    var _this = this;

    var wrapper = document.createElement('div');
    wrapper.style.display = 'inline-block';
    wrapper.appendChild(svg);
    this.wrapper = wrapper;

    Object.defineProperty(this, 'className', {
        get: function() {
            return wrapper.getAttribute('class') || '';
        },
        set: function(val) {
            return wrapper.setAttribute('class', val);
        }
    });

    ["width", "height"].forEach(function(prop) {
        Object.defineProperty(_this, prop, {
            get: function() {
                return svg.getAttribute(prop) | 0;
            },
            set: function(val) {
                if (isNaN(val) || (typeof val === "undefined")) {
                    return;
                }
                _this.ctx[prop] = val;
                svg.setAttribute(prop, val);
                return wrapper[prop] = val;
            }
        });
    });

    ["style", "id"].forEach(function(prop) {
        Object.defineProperty(_this, prop, {
            get: function() {
                return wrapper[prop];
            },
            set: function(val) {
                if (typeof val !== "undefined") {
                    return wrapper[prop] = val;
                }
            }
        });
    });

    ["getBoundingClientRect"].forEach(function(fn) {
        _this[fn] = function() {
            return svg[fn]();
        };
    });
}

SVGCanvasElement.prototype.getContext = function(type) {
    if (type !== '2d') {
        throw new Error('Unsupported type of context for SVGCanvas');
    }

    return this.ctx;
};

// you should always use URL.revokeObjectURL after your work done
SVGCanvasElement.prototype.toObjectURL = function() {
    var data = new XMLSerializer().serializeToString(this.svg);
    var svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
    return URL.createObjectURL(svg);
};

/**
 * toDataURL returns a data URI containing a representation of the image in the format specified by the type parameter.
 *
 * @param {String} type A DOMString indicating the image format. The default type is image/svg+xml; this image format will be also used if the specified type is not supported.
 * @param {Number} encoderOptions A Number between 0 and 1 indicating the image quality to be used when creating images using file formats that support lossy compression (such as image/jpeg or image/webp). A user agent will use its default quality value if this option is not specified, or if the number is outside the allowed range.
 * @param {Boolean} options.async Will return a Promise<String> if true, must be set to true if type is not image/svg+xml
 */
SVGCanvasElement.prototype.toDataURL = function(type, encoderOptions, options) {
    return imageUtils.toDataURL(this.svg, this.width, this.height, type, encoderOptions, options)
};

SVGCanvasElement.prototype.addEventListener = function() {
    return this.svg.addEventListener.apply(this.svg, arguments);
};

// will return wrapper element:
<svg></svg>

SVGCanvasElement.prototype.getElement = function() {
    return this.wrapper;
};

SVGCanvasElement.prototype.getAttribute = function(prop) {
    return this.wrapper.getAttribute(prop);
};

SVGCanvasElement.prototype.setAttribute = function(prop, val) {
    this.wrapper.setAttribute(prop, val);
};

export default SVGCanvasElement;
<commit_msg>Add support for tagName property<commit_after>import Context from './context';
import imageUtils from './image';

function SVGCanvasElement(options) {

    this.ctx = new Context(options);
    this.svg = this.ctx.__root;

    // sync attributes to svg
    var svg = this.svg;
    var _this = this;

    var wrapper = document.createElement('div');
    wrapper.style.display = 'inline-block';
    wrapper.appendChild(svg);
    this.wrapper = wrapper;

    Object.defineProperty(this, 'className', {
        get: function() {
            return wrapper.getAttribute('class') || '';
        },
        set: function(val) {
            return wrapper.setAttribute('class', val);
        }
    });

    Object.defineProperty(this, 'tagName', {
        get: function() {
            return "CANVAS";
        },
        set: function() {} // no-op
    });

    ["width", "height"].forEach(function(prop) {
        Object.defineProperty(_this, prop, {
            get: function() {
                return svg.getAttribute(prop) | 0;
            },
            set: function(val) {
                if (isNaN(val) || (typeof val === "undefined")) {
                    return;
                }
                _this.ctx[prop] = val;
                svg.setAttribute(prop, val);
                return wrapper[prop] = val;
            }
        });
    });

    ["style", "id"].forEach(function(prop) {
        Object.defineProperty(_this, prop, {
            get: function() {
                return wrapper[prop];
            },
            set: function(val) {
                if (typeof val !== "undefined") {
                    return wrapper[prop] = val;
                }
            }
        });
    });

    ["getBoundingClientRect"].forEach(function(fn) {
        _this[fn] = function() {
            return svg[fn]();
        };
    });
}

SVGCanvasElement.prototype.getContext = function(type) {
    if (type !== '2d') {
        throw new Error('Unsupported type of context for SVGCanvas');
    }

    return this.ctx;
};

// you should always use URL.revokeObjectURL after your work done
SVGCanvasElement.prototype.toObjectURL = function() {
    var data = new XMLSerializer().serializeToString(this.svg);
    var svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
    return URL.createObjectURL(svg);
};

/**
 * toDataURL returns a data URI containing a representation of the image in the format specified by the type parameter.
 *
 * @param {String} type A DOMString indicating the image format. The default type is image/svg+xml; this image format will be also used if the specified type is not supported.
 * @param {Number} encoderOptions A Number between 0 and 1 indicating the image quality to be used when creating images using file formats that support lossy compression (such as image/jpeg or image/webp). A user agent will use its default quality value if this option is not specified, or if the number is outside the allowed range.
 * @param {Boolean} options.async Will return a Promise<String> if true, must be set to true if type is not image/svg+xml
 */
SVGCanvasElement.prototype.toDataURL = function(type, encoderOptions, options) {
    return imageUtils.toDataURL(this.svg, this.width, this.height, type, encoderOptions, options)
};

SVGCanvasElement.prototype.addEventListener = function() {
    return this.svg.addEventListener.apply(this.svg, arguments);
};

// will return wrapper element:
<svg></svg>

SVGCanvasElement.prototype.getElement = function() {
    return this.wrapper;
};

SVGCanvasElement.prototype.getAttribute = function(prop) {
    return this.wrapper.getAttribute(prop);
};

SVGCanvasElement.prototype.setAttribute = function(prop, val) {
    this.wrapper.setAttribute(prop, val);
};

export default SVGCanvasElement;
<|endoftext|>


<commit_before>/**
 * A function used by Babel to transpile JSX code into jQuery elements
 */
let $ = require("jquery");

function buildElement(type, props, ...children) {
    // Is our element a TextNode?
    if (props === undefined) {
        // Type will be the text content, which can simply be returned here
        return type;
    }

    // Create a jQuery element
    let $el = $(document.createElement(type));

    // Iterate through props
    if (props !== null) {
        for (let propName in props) {
            // onClick gets turned into a jQuery event handler
            // TODO: Handle props like onHover, onFocus, etc.
            if (propName === "onClick") {
                let handler = props[propName];
                $el.click(handler);
            } else {
                let value = props[propName];
                $el.prop(propName, value);
            }
        }
    }

    // Recurse through the children and append each resulting element to the
    // parent
    children.forEach((child) => {
        $el.append(buildElement(child));
    });

    return $el;
}

module.exports = buildElement;
<commit_msg>prep JSX transpile target for unit testing<commit_after>/**
 * A function used by Babel to transpile JSX code into jQuery elements
 */
function buildElement(type, props, ...children) {
    // We need to require jQuery inside of this method because `require()`
    // will work different after mocha's magic "before" method runs.
    //
    // This allows us to use the jQuery instance provided by our jsdom
    // instance.
    let $ = require("jquery");

    // Is our element a TextNode?
    if (props === undefined) {
        // Type will be the text content, which can simply be returned here
        return type;
    }

    // Create a jQuery element
    let $el = $("<" + type + ">");

    // Iterate through props
    if (props !== null) {
        for (let propName in props) {
            // onClick gets turned into a jQuery event handler
            // TODO: Handle props like onHover, onFocus, etc.
            if (propName === "onClick") {
                let handler = props[propName];
                $el.click(handler);
            } else {
                let value = props[propName];
                $el.prop(propName, value);
            }
        }
    }

    // Recurse through the children and append each resulting element to the
    // parent
    children.forEach((child) => {
        $el.append(buildElement(child));
    });

    return $el;
}

module.exports = buildElement;
<|endoftext|>


<commit_before>const functions = require('firebase-functions');
const admin = require('firebase-admin');
const rp = require('request-promise');
const jsonDiff = require('json-diff');

admin.initializeApp();

exports.showConfigDiff = functions.remoteConfig.onUpdate(versionMetadata => {
  return admin.credential.applicationDefault().getAccessToken()
    .then(accessTokenObj => {
      return accessTokenObj.access_token;
    })
    .then(accessToken => {
      const currentVersion = versionMetadata.versionNumber;
      const templatePromises = [];
      templatePromises.push(getTemplate(currentVersion, accessToken));
      templatePromises.push(getTemplate(currentVersion - 1, accessToken));

      return Promise.all(templatePromises);
    })
    .then(results => {
      const currentTemplate = results[0];
      const previousTemplate = results[1];

      const diff = jsonDiff.diffString(previousTemplate, currentTemplate);

      console.log(diff);

      return null;
    }).catch(error => {
      console.error(error);
      return null;
    });
});

function getTemplate(version, accessToken) {
  const options = {
    uri: 'https://firebaseremoteconfig.googleapis.com/v1/projects/remote-config-function/remoteConfig',
    qs: {
      versionNumber: version
    },
    headers: {
        Authorization: 'Bearer ' + accessToken
    },
    json: true // Automatically parses the JSON string in the response
  };
  return rp(options).then(resp => {
    return Promise.resolve(resp);
  }).catch(err => {
    console.error(err);
    return Promise.resolve(null);
  });
}
<commit_msg>Add tag<commit_after>const functions = require('firebase-functions');
const admin = require('firebase-admin');
const rp = require('request-promise');
const jsonDiff = require('json-diff');

admin.initializeApp();

// [START js_remote_config_function]
exports.showConfigDiff = functions.remoteConfig.onUpdate(versionMetadata => {
  return admin.credential.applicationDefault().getAccessToken()
    .then(accessTokenObj => {
      return accessTokenObj.access_token;
    })
    .then(accessToken => {
      const currentVersion = versionMetadata.versionNumber;
      const templatePromises = [];
      templatePromises.push(getTemplate(currentVersion, accessToken));
      templatePromises.push(getTemplate(currentVersion - 1, accessToken));

      return Promise.all(templatePromises);
    })
    .then(results => {
      const currentTemplate = results[0];
      const previousTemplate = results[1];

      const diff = jsonDiff.diffString(previousTemplate, currentTemplate);

      console.log(diff);

      return null;
    }).catch(error => {
      console.error(error);
      return null;
    });
});
// [END js_remote_config_function]

function getTemplate(version, accessToken) {
  const options = {
    uri: 'https://firebaseremoteconfig.googleapis.com/v1/projects/remote-config-function/remoteConfig',
    qs: {
      versionNumber: version
    },
    headers: {
        Authorization: 'Bearer ' + accessToken
    },
    json: true // Automatically parses the JSON string in the response
  };
  return rp(options).then(resp => {
    return Promise.resolve(resp);
  }).catch(err => {
    console.error(err);
    return Promise.resolve(null);
  });
}
<|endoftext|>


<commit_before>
var pword = '';
var cPword = '';
var username = '';

//set submit button to disabled to start
$('input[name="submit"]').prop('disabled', true);

//verify form on any input keyup
$('input').keyup(function(){
	verifyForm();
});

//check for password match on any password input keyup
$('input[type="password"]').keyup(function(){
	var passwordMatch = checkPasswords();
	if(passwordMatch){
		var text = "Passwords match";
		updateFeedback(text, 'green');
	}else{
		var text = "Passwords don't match!";
		updateFeedback(text, 'red');
	}
});

function verifyForm(){
	pword = $('input[name="password"]').val();
	cPword = $('input[name="password_confirm"]').val();
	username = $('#login_username').val();

	if(pword && cPword && username){
		var passwordsMatch = checkPasswords();
		if(passwordsMatch){
			$('input[name="submit"]').prop('disabled', false);
		}
	}else{
		$('input[name="submit"]').prop('disabled', true);
	}
}

function updateFeedback(text, color='black'){
	$('#feedback_display').text(text);
	$('#feedback_display').css('color', color);
}

function checkPasswords(){
	pword = $('input[name="password"]').val();
	cPword = $('input[name="password_confirm"]').val();
	if(pword && cPword){
		if(pword === cPword){
			return true;
		}else{
			return false;
		}
	}else{
		return false;
	}
}
<commit_msg>I keep forgetting stuff =(<commit_after>
var pword = '';
var cPword = '';
var username = '';

//set submit button to disabled to start
$('input[name="submit"]').prop('disabled', true);

//verify form on any input keyup
$('input').keyup(function(){
	verifyForm();
});

//check for password match on any password input keyup
$('input[type="password"]').keyup(function(){
	var passwordMatch = checkPasswords();
	if(passwordMatch){
		var text = "Passwords match";
		updateFeedback(text, 'green');
	}else{
		var text = "Passwords don't match!";
		updateFeedback(text, 'red');
	}
});

function verifyForm(){
	pword = $('input[name="password"]').val();
	cPword = $('input[name="password_confirm"]').val();
	username = $('#login_username').val();

	if(pword && cPword && username){
		var passwordsMatch = checkPasswords();
		if(passwordsMatch){
			$('input[name="submit"]').prop('disabled', false);
		}else{
			$('input[name="submit"]').prop('disabled', true);
		}
	}else{
		$('input[name="submit"]').prop('disabled', true);
	}
}

function updateFeedback(text, color='black'){
	$('#feedback_display').text(text);
	$('#feedback_display').css('color', color);
}

function checkPasswords(){
	pword = $('input[name="password"]').val();
	cPword = $('input[name="password_confirm"]').val();
	if(pword && cPword){
		if(pword === cPword){
			return true;
		}else{
			return false;
		}
	}else{
		return false;
	}
}
<|endoftext|>