<commit_before>import config from '../config.json';
import {autoDetectRenderer, Container, Point, Texture, extras} from 'pixi.js';
const {TilingSprite} = extras;
import {Entity} from './entity';
import {Key} from './input';
import uuid from 'uuid';
import EntityService from './EntityService';
import LevelService from './LevelService';
import Radar from './Radar';
import {centeredToTopLeft} from "../../utils/coordinate";
import Map from './Map';
import spacePNG from '../resources/images/space.png';

let name = 'top-down-arena-shooter';
let version = '0.0.1';
document.title = `${name} v${version}`;
document.body.style.position = 'relative';
document.body.style.backgroundColor = '#111111';
document.body.style.padding = '0';
document.body.style.margin = '0';
document.body.style.overflow = 'hidden';

let renderer = autoDetectRenderer(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.view);
renderer.view.style.borderColor = '#222222';
renderer.view.style.borderStyle = 'solid';
renderer.view.style.borderWidth = '1px';

let masterContainer = new Container();
let backgroundContainer = new Container();
masterContainer.addChild(backgroundContainer);
let sceneContainer = new Container();
masterContainer.addChild(sceneContainer);
let debugContainer = new Container();
masterContainer.addChild(debugContainer);

let background = new TilingSprite(Texture.fromImage(spacePNG));
background.width = renderer.width;
background.height = renderer.height;
backgroundContainer.addChild(background);

window.addEventListener('resize', (event) => {
  console.log(`window.resize event: w:${event.target.innerWidth}, h:${event.target.innerHeight}`);
  renderer.resize(event.target.innerWidth, event.target.innerHeight);
  background.width = renderer.width;
  background.height = renderer.height;
});

let entityService = EntityService.get();
let levelService = LevelService.get();
let radar = new Radar();
let map = new Map();

const getOrCreateSessionID = () => {
  if (!sessionStorage.sessionID) {
    sessionStorage.sessionID = uuid();
  }

  return sessionStorage.sessionID;
};

const handleInitializeEvent = (eventData) => {
  // input: id,x,y,r|...
  sceneContainer.removeChildren();
  entityService.clear();
  eventData = eventData.split('|');
  eventData.forEach(entityData => {
    let properties = entityData.split(',');
    let id = properties[0];
    let type = properties[1];
    let x = parseFloat(properties[2]);
    let y = parseFloat(properties[3]);
    let r = parseFloat(properties[4]);
    let w = parseFloat(properties[5]);
    let h = parseFloat(properties[6]);
    let entity = new Entity(id, type, x, y, r, w, h);
    sceneContainer.addChild(entity.sprite);
    entityService.add(entity);
  });
};

const handleMapEvent = (eventData) => {
  // input width,height
  let dimensions = eventData.split(',');
  levelService.setDimensions(dimensions[0], dimensions[1]);
};

const handleIdentityEvent = (eventData) => {
  // input: id
  entityService.setLocalPlayer(eventData);
};

const handleAddEvent = (eventData) => {
  // input: id,x,y,r
  let properties = eventData.split(',');
  let id = properties[0];
  let type = properties[1];
  let x = parseFloat(properties[2]);
  let y = parseFloat(properties[3]);
  let r = parseFloat(properties[4]);
  let w = parseFloat(properties[5]);
  let h = parseFloat(properties[6]);
  let entity = new Entity(id, type, x, y, r, w, h);
  sceneContainer.addChild(entity.sprite);
  entityService.add(entity);
};

const handleUpdateEvent = (eventData) => {
  // input: id,x,y,r|...
  eventData = eventData.split('|');
  eventData.forEach(entityData => {
    let properties = entityData.split(',');
    let id = properties[0];
    let entity = entityService.getById(id);
    if (entity) {
      let x = parseFloat(properties[2]);
      let y = parseFloat(properties[3]);
      let r = parseFloat(properties[4]);
      let w = parseFloat(properties[5]);
      let h = parseFloat(properties[6]);
      entity.setPosition(x, y);
      entity.setRotation(r);
      entity.setSize(w, h);
    } else {
      console.log(`can't find entity: ${id}`);
    }
  });
};

const handleRemoveEvent = (eventData) => {
  // input: id
  let entity = entityService.removeById(eventData);
  if (entity) {
    sceneContainer.removeChild(entity.sprite);
  }
};

const handleDebugPointsEvent = (eventData) => {
  // input: x,y|...
  eventData = eventData.split('|');
  let points = eventData.map(pointData => {
    let properties = pointData.split(',');
    return {
      x: parseFloat(properties[0]),
      y: parseFloat(properties[1])
    };
  });

  for (let i = 0; i < points.length; ++i) {
    let point = points[i];
    point = convertServerPositionToPIXIPosition(point);
    let nextPoint = (i !== points.length - 1) ? points[i + 1] : points[0];
    nextPoint = convertServerPositionToPIXIPosition(nextPoint);

    let primitive = new PIXI.Graphics();
    debugContainer.addChild(primitive);
    primitive.lineStyle(1, 0x00FF00);
    primitive.moveTo(point.x, point.y);
    primitive.lineTo(nextPoint.x, nextPoint.y);
  }
};

const handleDebugNormalsEvent = (eventData) => {
  // input: Px,Py|Nx0,Ny0|Nx1,Ny1|Nx2,Ny2|Nx3,Ny3
  eventData = eventData.split('|');

  let positionData = eventData.shift().split(',');
  let position = {
    x: parseFloat(positionData[0]),
    y: parseFloat(positionData[1])
  };
  position = convertServerPositionToPIXIPosition(position);

  let normals = eventData.map(normalData => {
    let properties = normalData.split(',');
    return {
      x: parseFloat(properties[0]),
      y: parseFloat(properties[1])
    };
  });

  for (let i = 0; i < normals.length; ++i) {
    let normal = {
      x: normals[i].x + position.x,
      y: -normals[i].y + position.y
    };

    let primitive = new PIXI.Graphics();
    debugContainer.addChild(primitive);
    primitive.lineStyle(1, 0x0000FF);
    primitive.moveTo(position.x, position.y);
    primitive.lineTo(normal.x, normal.y);
  }
};

function convertServerPositionToPIXIPosition(position) {
  let levelService = LevelService.get();
  let w = levelService.getWidth();
  let h = levelService.getHeight();
  return centeredToTopLeft(position.x, position.y, w, h);
}

const getEventHandler = (name) => {
  switch (name) {
    case 'initialize': return handleInitializeEvent;
    case 'map': return handleMapEvent;
    case 'identity': return handleIdentityEvent;
    case 'add': return handleAddEvent;
    case 'update': return handleUpdateEvent;
    case 'remove': return handleRemoveEvent;
    case 'debug-points': return handleDebugPointsEvent;
    case 'debug-normals': return handleDebugNormalsEvent;
  }
};

let sessionID = getOrCreateSessionID();

const socket = new WebSocket(`ws://${config.server}/${sessionID}`);

socket.addEventListener('open', (event) => {
  console.log('websocket opened:', config.server);
});

socket.addEventListener('message', (event) => {
  console.log('websocket message received:', event.data);
  let split = event.data.indexOf('|');
  if (split !== -1) {
    let command = event.data.slice(0, split);
    let parameters = event.data.slice(split + 1);
    let eventHandler = getEventHandler(command);
    eventHandler(parameters);
  }
});

socket.addEventListener('close', (event) => {
  console.log('websocket closed:', config.server);
});

let keysDown = [];

window.addEventListener('keydown', (event) => {
  // console.log(`keydown: ${event.key} (${event.keyCode})`);

  if (keysDown.includes(event.keyCode)) return;
  keysDown.push(event.keyCode);

  if (event.keyCode === Key.A || event.keyCode === Key.Left) {
    socket.send(`start-rotate|left`);
  }

  if (event.keyCode === Key.D || event.keyCode === Key.Right) {
    socket.send(`start-rotate|right`);
  }

  if (event.keyCode === Key.W || event.keyCode === Key.Up) {
    socket.send(`start-thrust|forward`);
  }

  if (event.keyCode === Key.S || event.keyCode === Key.Down) {
    socket.send(`start-thrust|backward`);
  }

  if (event.keyCode === Key.Space) {
    socket.send(`start-fire`);
  }

  if (event.keyCode === Key.M) {
    if (!map.isVisible) {
      map.toggleVisibility();
    }
  }

});

window.addEventListener('keyup', (event) => {
  // console.log(`keyup: ${event.key} (${event.keyCode})`);

  let index = keysDown.indexOf(event.keyCode);
  if (index !== -1) {
    keysDown.splice(index, 1);
  }

  if (event.keyCode === Key.A || event.keyCode === Key.Left) {
    socket.send(`stop-rotate|left`);
  }

  if (event.keyCode === Key.D || event.keyCode === Key.Right) {
    socket.send(`stop-rotate|right`);
  }

  if (event.keyCode === Key.W || event.keyCode === Key.Up) {
    socket.send(`stop-thrust|forward`);
  }

  if (event.keyCode === Key.S || event.keyCode === Key.Down) {
    socket.send(`stop-thrust|backward`);
  }

  if (event.keyCode === Key.Space) {
    socket.send(`stop-fire`);
  }

  if (event.keyCode === Key.M) {
    if (map.isVisible) {
      map.toggleVisibility();
    }
  }

});

const loop = () => {
  requestAnimationFrame(loop);
  if (entityService.localPlayer) {
    let player = entityService.getLocalPlayer().sprite.position;
    masterContainer.position.x = renderer.width / 2;
    masterContainer.position.y = renderer.height / 2;
    masterContainer.pivot.x = player.x;
    masterContainer.pivot.y = player.y;
    backgroundContainer.position.x = player.x - renderer.width / 2;
    backgroundContainer.position.y = player.y - renderer.height / 2;
  }
  renderer.render(masterContainer);
  if (entityService.localPlayer) {
    let nearbyEntities = entityService.getNearby(config.radar.range);
    radar.update(nearbyEntities);
    radar.draw();
  }
  if (map.isVisible) {
    map.update(entityService.entities);
    map.draw();
  }
  debugContainer.removeChildren();
};

loop();
<commit_msg>Minor refactor for readability.<commit_after>import config from '../config.json';
import {autoDetectRenderer, Container, Point, Texture, extras} from 'pixi.js';
const {TilingSprite} = extras;
import {Entity} from './entity';
import {Key} from './input';
import uuid from 'uuid';
import EntityService from './EntityService';
import LevelService from './LevelService';
import Radar from './Radar';
import {centeredToTopLeft} from "../../utils/coordinate";
import Map from './Map';
import spacePNG from '../resources/images/space.png';

let name = 'top-down-arena-shooter';
let version = '0.0.1';
document.title = `${name} v${version}`;
document.body.style.position = 'relative';
document.body.style.backgroundColor = '#111111';
document.body.style.padding = '0';
document.body.style.margin = '0';
document.body.style.overflow = 'hidden';

let renderer = autoDetectRenderer(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.view);
renderer.view.style.borderColor = '#222222';
renderer.view.style.borderStyle = 'solid';
renderer.view.style.borderWidth = '1px';

let masterContainer = new Container();
let backgroundContainer = new Container();
masterContainer.addChild(backgroundContainer);
let sceneContainer = new Container();
masterContainer.addChild(sceneContainer);
let debugContainer = new Container();
masterContainer.addChild(debugContainer);

let background = new TilingSprite(Texture.fromImage(spacePNG));
background.width = renderer.width;
background.height = renderer.height;
backgroundContainer.addChild(background);

window.addEventListener('resize', (event) => {
  let width = event.target.innerWidth;
  let height = event.target.innerHeight;
  console.log(`window.resize event: w:${width}, h:${height}`);
  renderer.resize(width, event.target.innerHeight);
  background.width = renderer.width;
  background.height = renderer.height;
});

let entityService = EntityService.get();
let levelService = LevelService.get();
let radar = new Radar();
let map = new Map();

const getOrCreateSessionID = () => {
  if (!sessionStorage.sessionID) {
    sessionStorage.sessionID = uuid();
  }

  return sessionStorage.sessionID;
};

const handleInitializeEvent = (eventData) => {
  // input: id,x,y,r|...
  sceneContainer.removeChildren();
  entityService.clear();
  eventData = eventData.split('|');
  eventData.forEach(entityData => {
    let properties = entityData.split(',');
    let id = properties[0];
    let type = properties[1];
    let x = parseFloat(properties[2]);
    let y = parseFloat(properties[3]);
    let r = parseFloat(properties[4]);
    let w = parseFloat(properties[5]);
    let h = parseFloat(properties[6]);
    let entity = new Entity(id, type, x, y, r, w, h);
    sceneContainer.addChild(entity.sprite);
    entityService.add(entity);
  });
};

const handleMapEvent = (eventData) => {
  // input width,height
  let dimensions = eventData.split(',');
  levelService.setDimensions(dimensions[0], dimensions[1]);
};

const handleIdentityEvent = (eventData) => {
  // input: id
  entityService.setLocalPlayer(eventData);
};

const handleAddEvent = (eventData) => {
  // input: id,x,y,r
  let properties = eventData.split(',');
  let id = properties[0];
  let type = properties[1];
  let x = parseFloat(properties[2]);
  let y = parseFloat(properties[3]);
  let r = parseFloat(properties[4]);
  let w = parseFloat(properties[5]);
  let h = parseFloat(properties[6]);
  let entity = new Entity(id, type, x, y, r, w, h);
  sceneContainer.addChild(entity.sprite);
  entityService.add(entity);
};

const handleUpdateEvent = (eventData) => {
  // input: id,x,y,r|...
  eventData = eventData.split('|');
  eventData.forEach(entityData => {
    let properties = entityData.split(',');
    let id = properties[0];
    let entity = entityService.getById(id);
    if (entity) {
      let x = parseFloat(properties[2]);
      let y = parseFloat(properties[3]);
      let r = parseFloat(properties[4]);
      let w = parseFloat(properties[5]);
      let h = parseFloat(properties[6]);
      entity.setPosition(x, y);
      entity.setRotation(r);
      entity.setSize(w, h);
    } else {
      console.log(`can't find entity: ${id}`);
    }
  });
};

const handleRemoveEvent = (eventData) => {
  // input: id
  let entity = entityService.removeById(eventData);
  if (entity) {
    sceneContainer.removeChild(entity.sprite);
  }
};

const handleDebugPointsEvent = (eventData) => {
  // input: x,y|...
  eventData = eventData.split('|');
  let points = eventData.map(pointData => {
    let properties = pointData.split(',');
    return {
      x: parseFloat(properties[0]),
      y: parseFloat(properties[1])
    };
  });

  for (let i = 0; i < points.length; ++i) {
    let point = points[i];
    point = convertServerPositionToPIXIPosition(point);
    let nextPoint = (i !== points.length - 1) ? points[i + 1] : points[0];
    nextPoint = convertServerPositionToPIXIPosition(nextPoint);

    let primitive = new PIXI.Graphics();
    debugContainer.addChild(primitive);
    primitive.lineStyle(1, 0x00FF00);
    primitive.moveTo(point.x, point.y);
    primitive.lineTo(nextPoint.x, nextPoint.y);
  }
};

const handleDebugNormalsEvent = (eventData) => {
  // input: Px,Py|Nx0,Ny0|Nx1,Ny1|Nx2,Ny2|Nx3,Ny3
  eventData = eventData.split('|');

  let positionData = eventData.shift().split(',');
  let position = {
    x: parseFloat(positionData[0]),
    y: parseFloat(positionData[1])
  };
  position = convertServerPositionToPIXIPosition(position);

  let normals = eventData.map(normalData => {
    let properties = normalData.split(',');
    return {
      x: parseFloat(properties[0]),
      y: parseFloat(properties[1])
    };
  });

  for (let i = 0; i < normals.length; ++i) {
    let normal = {
      x: normals[i].x + position.x,
      y: -normals[i].y + position.y
    };

    let primitive = new PIXI.Graphics();
    debugContainer.addChild(primitive);
    primitive.lineStyle(1, 0x0000FF);
    primitive.moveTo(position.x, position.y);
    primitive.lineTo(normal.x, normal.y);
  }
};

function convertServerPositionToPIXIPosition(position) {
  let levelService = LevelService.get();
  let w = levelService.getWidth();
  let h = levelService.getHeight();
  return centeredToTopLeft(position.x, position.y, w, h);
}

const getEventHandler = (name) => {
  switch (name) {
    case 'initialize': return handleInitializeEvent;
    case 'map': return handleMapEvent;
    case 'identity': return handleIdentityEvent;
    case 'add': return handleAddEvent;
    case 'update': return handleUpdateEvent;
    case 'remove': return handleRemoveEvent;
    case 'debug-points': return handleDebugPointsEvent;
    case 'debug-normals': return handleDebugNormalsEvent;
  }
};

let sessionID = getOrCreateSessionID();

const socket = new WebSocket(`ws://${config.server}/${sessionID}`);

socket.addEventListener('open', (event) => {
  console.log('websocket opened:', config.server);
});

socket.addEventListener('message', (event) => {
  console.log('websocket message received:', event.data);
  let split = event.data.indexOf('|');
  if (split !== -1) {
    let command = event.data.slice(0, split);
    let parameters = event.data.slice(split + 1);
    let eventHandler = getEventHandler(command);
    eventHandler(parameters);
  }
});

socket.addEventListener('close', (event) => {
  console.log('websocket closed:', config.server);
});

let keysDown = [];

window.addEventListener('keydown', (event) => {
  // console.log(`keydown: ${event.key} (${event.keyCode})`);

  if (keysDown.includes(event.keyCode)) return;
  keysDown.push(event.keyCode);

  if (event.keyCode === Key.A || event.keyCode === Key.Left) {
    socket.send(`start-rotate|left`);
  }

  if (event.keyCode === Key.D || event.keyCode === Key.Right) {
    socket.send(`start-rotate|right`);
  }

  if (event.keyCode === Key.W || event.keyCode === Key.Up) {
    socket.send(`start-thrust|forward`);
  }

  if (event.keyCode === Key.S || event.keyCode === Key.Down) {
    socket.send(`start-thrust|backward`);
  }

  if (event.keyCode === Key.Space) {
    socket.send(`start-fire`);
  }

  if (event.keyCode === Key.M) {
    if (!map.isVisible) {
      map.toggleVisibility();
    }
  }

});

window.addEventListener('keyup', (event) => {
  // console.log(`keyup: ${event.key} (${event.keyCode})`);

  let index = keysDown.indexOf(event.keyCode);
  if (index !== -1) {
    keysDown.splice(index, 1);
  }

  if (event.keyCode === Key.A || event.keyCode === Key.Left) {
    socket.send(`stop-rotate|left`);
  }

  if (event.keyCode === Key.D || event.keyCode === Key.Right) {
    socket.send(`stop-rotate|right`);
  }

  if (event.keyCode === Key.W || event.keyCode === Key.Up) {
    socket.send(`stop-thrust|forward`);
  }

  if (event.keyCode === Key.S || event.keyCode === Key.Down) {
    socket.send(`stop-thrust|backward`);
  }

  if (event.keyCode === Key.Space) {
    socket.send(`stop-fire`);
  }

  if (event.keyCode === Key.M) {
    if (map.isVisible) {
      map.toggleVisibility();
    }
  }

});

const loop = () => {
  requestAnimationFrame(loop);
  if (entityService.localPlayer) {
    let player = entityService.getLocalPlayer().sprite.position;
    masterContainer.position.x = renderer.width / 2;
    masterContainer.position.y = renderer.height / 2;
    masterContainer.pivot.x = player.x;
    masterContainer.pivot.y = player.y;
    backgroundContainer.position.x = player.x - renderer.width / 2;
    backgroundContainer.position.y = player.y - renderer.height / 2;
  }
  renderer.render(masterContainer);
  if (entityService.localPlayer) {
    let nearbyEntities = entityService.getNearby(config.radar.range);
    radar.update(nearbyEntities);
    radar.draw();
  }
  if (map.isVisible) {
    map.update(entityService.entities);
    map.draw();
  }
  debugContainer.removeChildren();
};

loop();
<|endoftext|>


<commit_before>module.exports = [
    '#define SHADER_NAME PHASER_POINTLIGHT_FS',
    '',
    'precision mediump float;',
    '',
    'uniform vec2 uResolution;',
    '',
    'varying vec4 lightPosition;',
    'varying vec4 lightColor;',
    'varying float lightRadius;',
    '',
    'void main()',
    '{',
    '    vec2 center = vec2((lightPosition.x + 1.0) * uResolution.x, (lightPosition.y + 1.0) * uResolution.y);',
    '',
    '    float distance = length(center - gl_FragCoord.xy);',
    '',
    '    // float attenuation = 1.0 / distance;',
    '    // float attenuation = 1.0 / (0.01 * distance + 0.01 * distance * distance);',
    '    float attenuation = 1.0 / (0.01 * distance * distance);',
    '    float radius = 1.0 - min(distance, lightRadius) / lightRadius;',
    '    float intensity = smoothstep(0.0, 1.0, min(attenuation, radius));',
    '',
    '    vec4 color = vec4(intensity, intensity, intensity, 0.0) * lightColor;',
    '',
    '    gl_FragColor = vec4(color.rgb * lightColor.a, color.a);',
    '}',
    ''
].join('\n');
<commit_msg>Update PointLight-frag.js<commit_after>module.exports = [
    '#define SHADER_NAME PHASER_POINTLIGHT_FS',
    '',
    'precision mediump float;',
    '',
    'uniform vec2 uResolution;',
    '',
    'varying vec4 lightPosition;',
    'varying vec4 lightColor;',
    'varying float lightRadius;',
    '',
    'void main()',
    '{',
    '    vec2 center = vec2((lightPosition.x + 1.0) * uResolution.x, (lightPosition.y + 1.0) * uResolution.y);',
    '',
    '    float distance = length(center - gl_FragCoord.xy);',
    '',
    '    float attenuation = 1.0 / (0.01 * distance * distance);',
    '    float radius = 1.0 - min(distance, lightRadius) / lightRadius;',
    '    float intensity = smoothstep(0.0, 1.0, min(attenuation, radius));',
    '',
    '    vec4 color = vec4(intensity, intensity, intensity, 0.0) * lightColor;',
    '',
    '    gl_FragColor = vec4(color.rgb * lightColor.a, color.a);',
    '}',
    ''
].join('\n');
<|endoftext|>


<commit_before>/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactErrorUtils
 * @flow
 */

'use strict';

var caughtError = null;

/**
 * Call a function while guarding against errors that happens within it.
 *
 * @param {String} name of the guard to use for logging or debugging
 * @param {Function} func The function to invoke
 * @param {*} a First argument
 * @param {*} b Second argument
 */
function invokeGuardedCallback<A>(
  name: string,
  func: (a: A) => void,
  a: A,
): void {
  try {
    func(a);
  } catch (x) {
    if (caughtError === null) {
      caughtError = x;
    }
  }
}

var ReactErrorUtils = {
  invokeGuardedCallback: invokeGuardedCallback,

  /**
   * Invoked by ReactTestUtils.Simulate so that any errors thrown by the event
   * handler are sure to be rethrown by rethrowCaughtError.
   */
  invokeGuardedCallbackWithCatch: invokeGuardedCallback,

  /**
   * During execution of guarded functions we will capture the first error which
   * we will rethrow to be handled by the top level error handler.
   */
  rethrowCaughtError: function() {
    if (caughtError) {
      var error = caughtError;
      caughtError = null;
      throw error;
    }
  },
};

if (__DEV__) {
  /**
   * To help development we can get better devtools integration by simulating a
   * real browser event.
   */
  if (typeof window !== 'undefined' &&
      typeof window.dispatchEvent === 'function' &&
      typeof document !== 'undefined' &&
      typeof document.createEvent === 'function') {
    var fakeNode = document.createElement('react');
    ReactErrorUtils.invokeGuardedCallback = function<A>(
      name: string,
      func: (a: A) => void,
      a: A,
    ): void {
      var boundFunc = func.bind(null, a);
      var evtType = `react-${name}`;
      fakeNode.addEventListener(evtType, boundFunc, false);
      var evt = document.createEvent('Event');
      evt.initEvent(evtType, false, false);
      fakeNode.dispatchEvent(evt);
      fakeNode.removeEventListener(evtType, boundFunc, false);
    };
  }
}

module.exports = ReactErrorUtils;
<commit_msg>Cleanup ReactErrorUtils (#8145)<commit_after>/**
 * Copyright 2013-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule ReactErrorUtils
 * @flow
 */

'use strict';

var caughtError = null;

/**
 * Call a function while guarding against errors that happens within it.
 *
 * @param {String} name of the guard to use for logging or debugging
 * @param {Function} func The function to invoke
 * @param {*} a Argument
 */
function invokeGuardedCallback<A>(
  name: string,
  func: (a: A) => void,
  a: A,
): void {
  try {
    func(a);
  } catch (x) {
    if (caughtError === null) {
      caughtError = x;
    }
  }
}

var ReactErrorUtils = {
  invokeGuardedCallback: invokeGuardedCallback,

  /**
   * Invoked by ReactTestUtils.Simulate so that any errors thrown by the event
   * handler are sure to be rethrown by rethrowCaughtError.
   */
  invokeGuardedCallbackWithCatch: invokeGuardedCallback,

  /**
   * During execution of guarded functions we will capture the first error which
   * we will rethrow to be handled by the top level error handler.
   */
  rethrowCaughtError: function() {
    if (caughtError) {
      var error = caughtError;
      caughtError = null;
      throw error;
    }
  },
};

if (__DEV__) {
  /**
   * To help development we can get better devtools integration by simulating a
   * real browser event.
   */
  if (typeof window !== 'undefined' &&
      typeof window.dispatchEvent === 'function' &&
      typeof document !== 'undefined' &&
      typeof document.createEvent === 'function') {
    var fakeNode = document.createElement('react');
    ReactErrorUtils.invokeGuardedCallback = function<A>(
      name: string,
      func: (a: A) => void,
      a: A,
    ): void {
      var boundFunc = func.bind(null, a);
      var evtType = `react-${name}`;
      fakeNode.addEventListener(evtType, boundFunc, false);
      var evt = document.createEvent('Event');
      evt.initEvent(evtType, false, false);
      fakeNode.dispatchEvent(evt);
      fakeNode.removeEventListener(evtType, boundFunc, false);
    };
  }
}

module.exports = ReactErrorUtils;
<|endoftext|>


<commit_before>import assign from "./assign";

/**
    @function configPrep
    @desc Preps a config object for d3plus data, and optionally bubbles up a specific nested type. When using this function, you must bind a d3plus class' `this` context.
    @param {Object} [config = this._shapeConfig] The configuration object to parse.
    @param {String} [type = "shape"] The event classifier to user for "on" events. For example, the default event type of "shape" will apply all events in the "on" config object with that key, like "click.shape" and "mouseleave.shape", in addition to any gloval events like "click" and "mouseleave".
    @param {String} [nest] An optional nested key to bubble up to the parent config level.
*/
export default function configPrep(config = this._shapeConfig, type = "shape", nest = false) {

  let newConfig = {duration: this._duration, on: {}};

  const wrapFunction = func => (d, i, s) => {
    while (d.__d3plus__ && d.data) {
      i = d.i;
      d = d.data;
    }
    return func(d, i, s);
  };

  const parseEvents = (newObj, on) => {

    for (const event in on) {

      if ({}.hasOwnProperty.call(on, event) && !event.includes(".") || event.includes(`.${type}`)) {

        newObj.on[event] = wrapFunction(on[event]);

      }

    }

  };

  const keyEval = (newObj, obj) => {

    for (const key in obj) {

      if ({}.hasOwnProperty.call(obj, key)) {

        if (key === "on") parseEvents(newObj, obj[key]);
        else if (typeof obj[key] === "function") {
          newObj[key] = wrapFunction(obj[key]);
        }
        else if (typeof obj[key] === "object" && !(obj instanceof Array)) {
          newObj[key] = {on: {}};
          keyEval(newObj[key], obj[key]);
        }
        else newObj[key] = obj[key];

      }

    }

  };

  keyEval(newConfig, config);
  if (this._on) parseEvents(newConfig, this._on);

  if (nest && config[nest]) newConfig = assign(newConfig, config[nest]);
  return newConfig;

}
<commit_msg>fixes nested object assignment in configPrep (closes d3plus/d3plus-plot#48)<commit_after>/**
    @function configPrep
    @desc Preps a config object for d3plus data, and optionally bubbles up a specific nested type. When using this function, you must bind a d3plus class' `this` context.
    @param {Object} [config = this._shapeConfig] The configuration object to parse.
    @param {String} [type = "shape"] The event classifier to user for "on" events. For example, the default event type of "shape" will apply all events in the "on" config object with that key, like "click.shape" and "mouseleave.shape", in addition to any gloval events like "click" and "mouseleave".
    @param {String} [nest] An optional nested key to bubble up to the parent config level.
*/
export default function configPrep(config = this._shapeConfig, type = "shape", nest = false) {

  const newConfig = {duration: this._duration, on: {}};

  const wrapFunction = func => (d, i, s) => {
    while (d.__d3plus__ && d.data) {
      i = d.i;
      d = d.data;
    }
    return func(d, i, s);
  };

  const parseEvents = (newObj, on) => {

    for (const event in on) {

      if ({}.hasOwnProperty.call(on, event) && !event.includes(".") || event.includes(`.${type}`)) {

        newObj.on[event] = wrapFunction(on[event]);

      }

    }

  };

  const keyEval = (newObj, obj) => {

    for (const key in obj) {

      if ({}.hasOwnProperty.call(obj, key)) {

        if (key === "on") parseEvents(newObj, obj[key]);
        else if (typeof obj[key] === "function") {
          newObj[key] = wrapFunction(obj[key]);
        }
        else if (typeof obj[key] === "object" && !(obj instanceof Array)) {
          newObj[key] = {on: {}};
          keyEval(newObj[key], obj[key]);
        }
        else newObj[key] = obj[key];

      }

    }

  };

  keyEval(newConfig, config);
  if (this._on) parseEvents(newConfig, this._on);
  if (nest && config[nest]) keyEval(newConfig, config[nest]);

  return newConfig;

}
<|endoftext|>


<commit_before>/**
 * This is the main conf file for protractor. Change the base URL to the URL of the application to test.
 * Also change the browsers where the application needs to be tested. Use 'multiCapabilities' to test on different browsers.
 */

exports.config = {

    //The address of a running Selenium server
    //seleniumAddress: 'http://localhost:4444/wd/hub',
    // Spec patterns are relative to the current working directly when
    // protractor is called.
    specs: ['e2e_tests/protractor/tests/HomePageTest.js'],

    // Capabilities to be passed to the webdriver instance.
    capabilities: {
        'browserName': 'firefox'
    },

    //If the ng-app is not declared on body, then specify where it is declared.
    rootElement: 'html',

    //this can be replaced by localhost address to run tests locally, the following address is the old staging server address
    baseUrl: 'http://localhost:9090'
};
<commit_msg>Added Selenium Update to install dependency to test Protractor Trial-3<commit_after>/**
 * This is the main conf file for protractor. Change the base URL to the URL of the application to test.
 * Also change the browsers where the application needs to be tested. Use 'multiCapabilities' to test on different browsers.
 */

exports.config = {

    //The address of a running Selenium server
    //seleniumAddress: 'http://localhost:4444/wd/hub',
    // Spec patterns are relative to the current working directly when
    // protractor is called.
    specs: ['e2e_tests/protractor/tests/HomePageTest.js'],

    // Capabilities to be passed to the webdriver instance.
    capabilities: {
        'browserName': 'firefox'
    },

    //If the ng-app is not declared on body, then specify where it is declared.
    rootElement: 'html',

    //this can be replaced by localhost address to run tests locally, the following address is the old staging server address
    baseUrl: ''
};
<|endoftext|>


<commit_before>import { Korean } from './korean';
import { Hindi } from './hindi';
import { French } from './french';

const Conjugator = {
  create: (lang) => {
    switch (lang.toLowerCase()) {
      case 'korean':
        return new Korean();
      case 'hindi':
        return new Hindi();
      case 'french':
        return new French();
      default:
        break;
    }
  },

  getLanguageList: () => {
    return ['Korean', 'Hindi', 'French'];
  }
};

export default Conjugator;
module.exports = Conjugator;
<commit_msg>eslint fux<commit_after>import { Korean } from './korean';
import { Hindi } from './hindi';
import { French } from './french';

const Conjugator = {
  create: (lang) => {
    switch (lang.toLowerCase()) {
      case 'korean':
        return new Korean();
      case 'hindi':
        return new Hindi();
      case 'french':
        return new French();
      default:
        break;
    }
  },

  getLanguageList: () => ['Korean', 'Hindi', 'French']
};

export default Conjugator;
module.exports = Conjugator;
<|endoftext|>


<commit_before>/*
 * Copyright 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import $ from 'jquery';
import { materialColor } from './material-colors.js';

export const THEME_PROPERTIES = [
  { short: 'b', id: 'bgColor', name: 'Background', type: 'color' },
  { short: 't', id: 'textColor', name: 'Plain text', type: 'color' },
  { short: 'p', id: 'punctuationColor', name: 'Punctuation', type: 'color' },
  { short: 's', id: 'stringAndValueColor', name: 'Strings, values', type: 'color' },
  { short: 'k', id: 'keywordTagColor', name: 'Keywords, tags', type: 'color' },
  { short: 'c', id: 'commentColor', name: 'Comments', type: 'color' },
  { short: 'y', id: 'typeColor', name: 'Types', type: 'color' },
  { short: 'n', id: 'numberColor', name: 'Numbers', type: 'color' },
  { short: 'd', id: 'declarationColor', name: 'Declarations', type: 'color' },
  { short: 'i', id: 'dimmedColor', name: 'Selection: Unfocused', type: 'color' },
  { short: 'h', id: 'highlightColor', name: 'Selection: Highlighter', type: 'color' },
  { short: 'lh', id: 'lineHeight', name: 'Line height', hideEditor: true },
];

export function setTheme(theme, typeSize) {
  let { bgColor, textColor, punctuationColor, stringAndValueColor,
    keywordTagColor, commentColor, typeColor, numberColor,
    declarationColor, dimmedColor, highlightColor, lineHeight } = theme;
  lineHeight = lineHeight || 1.5;
  let css = `
    #output pre,
    #output pre mark {
      line-height: ${lineHeight * typeSize}px;
      color: ${textColor};
    }
    #output.has-highlights[data-seltreat="focus"] pre > :not(mark),
    #output.has-highlights[data-seltreat="focus"] pre :not(mark),
    #output.has-highlights[data-seltreat="focus"] pre {
      color: ${dimmedColor || 'grey'};
    }
    #output.has-highlights[data-seltreat="highlight"] pre mark {
      background-color: ${highlightColor || 'yellow'};
    }
    #output::after {
      /* to avoid background color being copied to clipboard */
      background-color: ${bgColor};
    }

    #output pre .token.comment,
    #output pre .token.prolog,
    #output pre .token.doctype,
    #output pre .token.cdata {
      color: ${commentColor};
    }

    #output pre .token.namespace {
      opacity: .7;
    }

    #output pre .token.string,
    #output pre .token.regex,
    #output pre .token.attr-value {
      color: ${stringAndValueColor};
    }

    #output pre .token.punctuation,
    #output pre .token.operator {
      color: ${punctuationColor};
    }

    #output pre .token.entity,
    #output pre .token.url,
    #output pre .token.symbol,
    #output pre .token.number,
    #output pre .token.variable,
    #output pre .token.constant,
    #output pre .token.inserted {
      color: ${numberColor};
    }

    #output pre .token.atrule,
    #output pre .token.class-name,
    #output pre .token.attr-name,
    #output pre .token.selector,
    #output pre .token.builtin {
      color: ${typeColor};
    }

    #output pre .token.deleted,
    #output pre .token.property,
    #output pre .token.boolean,
    #output pre .token.keyword,
    #output pre .token.tag {
      color: ${keywordTagColor};
    }

    #output pre .token.important {
      color: ${declarationColor};
    }

    #output pre .token.bold {
      font-weight: bold;
    }

    #output pre .token.italic {
      font-style: italic;
    }
  `;

  $('[theme-rules]').remove();

  $('<style>')
    .attr('theme-rules', true)
    .text(css)
    .appendTo(document.body);
  $('.message-bgcolor').text(`Set your background color to: ${bgColor.toUpperCase()}`);
}

export const DEFAULT_THEMES = {
  'light': {
    bgColor: materialColor('grey', '100'),
    textColor: materialColor('blue-grey', '800'),
    punctuationColor: materialColor('blue-grey', '800'),
    stringAndValueColor: materialColor('green', '700'),
    keywordTagColor: materialColor('indigo', '500'),
    commentColor: materialColor('pink', '600'),
    typeColor: materialColor('purple', '500'),
    numberColor: '#c53929', // g-red 700
    declarationColor: materialColor('indigo', '500'),
    dimmedColor: materialColor('grey', '400'),
    highlightColor: materialColor('grey', '300'),
    lineHeight: 1.5,
  },
  'light-alt': {
    bgColor: '#eeeeee',
    textColor: '#000000',
    punctuationColor: '#a3a3a3',
    stringAndValueColor: '#0f9d58',
    keywordTagColor: '#4285f4',
    commentColor: '#999999',
    typeColor: '#673ab7',
    numberColor: '#db4437',
    // attrNameColor: #e91e63,
    declarationColor: '#e67c73',
    dimmedColor: materialColor('grey', '400'),
    highlightColor: '#dddddd',
    lineHeight: 1.5,
  },
  'dark': {
    bgColor: materialColor('grey', '900'),
    textColor: materialColor('blue-grey', '50'),
    punctuationColor: materialColor('blue-grey', '50'),
    stringAndValueColor: materialColor('light-green', '400'),
    keywordTagColor: materialColor('cyan', '300'),
    commentColor: materialColor('pink', '300'),
    typeColor: materialColor('purple', '200'),
    numberColor: materialColor('yellow', '700'),
    declarationColor: materialColor('yellow', '700'),
    dimmedColor: materialColor('grey', '500'),
    highlightColor: materialColor('grey', '700'),
    lineHeight: 1.5,
  },
  'dark-alt': {
    bgColor: '#000000',
    textColor: '#ffffff',
    punctuationColor: '#a3a3a3',
    stringAndValueColor: '#57bb8a',
    keywordTagColor: '#7baaf7',
    commentColor: '#aaaaaa',
    typeColor: '#ff8a65', // alt #f06292
    numberColor: '#f4b400',
    declarationColor: '#e67c73',
    dimmedColor: '#777777',
    highlightColor: '#444444',
    lineHeight: 1.5,
  },
  'design-dark': {
    bgColor: '#263238',
    textColor: '#ffffff',
    punctuationColor: '#90a4ae',
    stringAndValueColor: '#00bfa4',
    keywordTagColor: '#26c6da',
    commentColor: '#607d8b',
    typeColor: '#ff8a80',
    numberColor: '#ffbc00',
    declarationColor: '#90a4ae',
    dimmedColor: '#5f6c73',
    highlightColor: '#586870',
    lineHeight: 1.5,
  },
  'io17': {
    bgColor: '#263238', // #546dfe
    textColor: '#ffffff',
    punctuationColor: '#90a4ae',
    stringAndValueColor: '#1ce8b5',
    keywordTagColor: '#00e4ff',
    commentColor: '#ff5cb4',
    typeColor: '#ff8857', // ff6d00
    numberColor: '#ffd500',
    declarationColor: '#90a4ae',
    dimmedColor: '#5f6c73',
    highlightColor: '#586870',
    lineHeight: 1.2,
  },
  'io19': {
    bgColor: '#202124',
    textColor: '#ffffff',
    punctuationColor: '#9aa0a6',
    stringAndValueColor: '#5bb974',
    keywordTagColor: '#669df6',
    commentColor: '#9aa0a6',
    typeColor: '#ee675c',
    numberColor: '#fcc934',
    declarationColor: '#fcc934',
    dimmedColor: '#5f6c73',
    highlightColor: '#4d555b',
    lineHeight: 1.2,
  },
  'flutter-interact-19': {
    bgColor: "#241e30",
    textColor: "#fafbfb",
    punctuationColor: "#8be9fd",
    stringAndValueColor: "#ffa65c",
    keywordTagColor: "#1cdec9",
    commentColor: "#808080",
    typeColor: "#d65bad",
    numberColor: "#bd93f9",
    declarationColor: "#ff8383",
    dimmedColor: "#87858e",
    highlightColor: '#425a6c',
    lineHeight: 1.2,
  },
  'angular-material': {
    bgColor: "#382e42",
    textColor: "#ffffff",
    punctuationColor: materialColor('light-blue', '100'),
    stringAndValueColor: "#c3e88d",
    keywordTagColor: materialColor('light-blue', '100'),
    commentColor: materialColor('grey', '500'),
    typeColor: materialColor('orange', '200'),
    numberColor: materialColor('purple', '200'),
    declarationColor: materialColor('purple', '200'),
    dimmedColor: "#4d4d4d",
    highlightColor: "#4d3663",
    lineHeight: 1.2
  }
};
<commit_msg>treat metadata tokens as declaration color, also slight light theme tweak<commit_after>/*
 * Copyright 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import $ from 'jquery';
import { materialColor } from './material-colors.js';

export const THEME_PROPERTIES = [
  { short: 'b', id: 'bgColor', name: 'Background', type: 'color' },
  { short: 't', id: 'textColor', name: 'Plain text', type: 'color' },
  { short: 'p', id: 'punctuationColor', name: 'Punctuation', type: 'color' },
  { short: 's', id: 'stringAndValueColor', name: 'Strings, values', type: 'color' },
  { short: 'k', id: 'keywordTagColor', name: 'Keywords, tags', type: 'color' },
  { short: 'c', id: 'commentColor', name: 'Comments', type: 'color' },
  { short: 'y', id: 'typeColor', name: 'Types', type: 'color' },
  { short: 'n', id: 'numberColor', name: 'Numbers', type: 'color' },
  { short: 'd', id: 'declarationColor', name: 'Declarations', type: 'color' },
  { short: 'i', id: 'dimmedColor', name: 'Selection: Unfocused', type: 'color' },
  { short: 'h', id: 'highlightColor', name: 'Selection: Highlighter', type: 'color' },
  { short: 'lh', id: 'lineHeight', name: 'Line height', hideEditor: true },
];

export function setTheme(theme, typeSize) {
  let { bgColor, textColor, punctuationColor, stringAndValueColor,
    keywordTagColor, commentColor, typeColor, numberColor,
    declarationColor, dimmedColor, highlightColor, lineHeight } = theme;
  lineHeight = lineHeight || 1.5;
  let css = `
    #output pre,
    #output pre mark {
      line-height: ${lineHeight * typeSize}px;
      color: ${textColor};
    }
    #output.has-highlights[data-seltreat="focus"] pre > :not(mark),
    #output.has-highlights[data-seltreat="focus"] pre :not(mark),
    #output.has-highlights[data-seltreat="focus"] pre {
      color: ${dimmedColor || 'grey'};
    }
    #output.has-highlights[data-seltreat="highlight"] pre mark {
      background-color: ${highlightColor || 'yellow'};
    }
    #output::after {
      /* to avoid background color being copied to clipboard */
      background-color: ${bgColor};
    }

    #output pre .token.comment,
    #output pre .token.prolog,
    #output pre .token.doctype,
    #output pre .token.cdata {
      color: ${commentColor};
    }

    #output pre .token.namespace {
      opacity: .7;
    }

    #output pre .token.string,
    #output pre .token.regex,
    #output pre .token.attr-value {
      color: ${stringAndValueColor};
    }

    #output pre .token.punctuation,
    #output pre .token.operator {
      color: ${punctuationColor};
    }

    #output pre .token.entity,
    #output pre .token.url,
    #output pre .token.symbol,
    #output pre .token.number,
    #output pre .token.variable,
    #output pre .token.constant,
    #output pre .token.inserted {
      color: ${numberColor};
    }

    #output pre .token.atrule,
    #output pre .token.class-name,
    #output pre .token.attr-name,
    #output pre .token.selector,
    #output pre .token.builtin {
      color: ${typeColor};
    }

    #output pre .token.deleted,
    #output pre .token.property,
    #output pre .token.boolean,
    #output pre .token.keyword,
    #output pre .token.tag {
      color: ${keywordTagColor};
    }

    #output pre .token.important,
    #output pre .token.metadata {
      color: ${declarationColor};
    }

    #output pre .token.bold {
      font-weight: bold;
    }

    #output pre .token.italic {
      font-style: italic;
    }
  `;

  $('[theme-rules]').remove();

  $('<style>')
    .attr('theme-rules', true)
    .text(css)
    .appendTo(document.body);
  $('.message-bgcolor').text(`Set your background color to: ${bgColor.toUpperCase()}`);
}

export const DEFAULT_THEMES = {
  'light': {
    bgColor: materialColor('grey', '100'),
    textColor: materialColor('blue-grey', '800'),
    punctuationColor: materialColor('blue-grey', '800'),
    stringAndValueColor: materialColor('green', '700'),
    keywordTagColor: materialColor('indigo', '500'),
    commentColor: materialColor('pink', '600'),
    typeColor: materialColor('purple', '500'),
    numberColor: '#c53929', // g-red 700
    declarationColor: materialColor('cyan', '700'),
    dimmedColor: materialColor('grey', '400'),
    highlightColor: materialColor('grey', '300'),
    lineHeight: 1.5,
  },
  'light-alt': {
    bgColor: '#eeeeee',
    textColor: '#000000',
    punctuationColor: '#a3a3a3',
    stringAndValueColor: '#0f9d58',
    keywordTagColor: '#4285f4',
    commentColor: '#999999',
    typeColor: '#673ab7',
    numberColor: '#db4437',
    // attrNameColor: #e91e63,
    declarationColor: '#e67c73',
    dimmedColor: materialColor('grey', '400'),
    highlightColor: '#dddddd',
    lineHeight: 1.5,
  },
  'dark': {
    bgColor: materialColor('grey', '900'),
    textColor: materialColor('blue-grey', '50'),
    punctuationColor: materialColor('blue-grey', '50'),
    stringAndValueColor: materialColor('light-green', '400'),
    keywordTagColor: materialColor('cyan', '300'),
    commentColor: materialColor('pink', '300'),
    typeColor: materialColor('purple', '200'),
    numberColor: materialColor('yellow', '700'),
    declarationColor: materialColor('yellow', '700'),
    dimmedColor: materialColor('grey', '500'),
    highlightColor: materialColor('grey', '700'),
    lineHeight: 1.5,
  },
  'dark-alt': {
    bgColor: '#000000',
    textColor: '#ffffff',
    punctuationColor: '#a3a3a3',
    stringAndValueColor: '#57bb8a',
    keywordTagColor: '#7baaf7',
    commentColor: '#aaaaaa',
    typeColor: '#ff8a65', // alt #f06292
    numberColor: '#f4b400',
    declarationColor: '#f06292',
    dimmedColor: '#777777',
    highlightColor: '#444444',
    lineHeight: 1.5,
  },
  'design-dark': {
    bgColor: '#263238',
    textColor: '#ffffff',
    punctuationColor: '#90a4ae',
    stringAndValueColor: '#00bfa4',
    keywordTagColor: '#26c6da',
    commentColor: '#607d8b',
    typeColor: '#ff8a80',
    numberColor: '#ffbc00',
    declarationColor: '#90a4ae',
    dimmedColor: '#5f6c73',
    highlightColor: '#586870',
    lineHeight: 1.5,
  },
  'io17': {
    bgColor: '#263238', // #546dfe
    textColor: '#ffffff',
    punctuationColor: '#90a4ae',
    stringAndValueColor: '#1ce8b5',
    keywordTagColor: '#00e4ff',
    commentColor: '#ff5cb4',
    typeColor: '#ff8857', // ff6d00
    numberColor: '#ffd500',
    declarationColor: '#90a4ae',
    dimmedColor: '#5f6c73',
    highlightColor: '#586870',
    lineHeight: 1.2,
  },
  'io19': {
    bgColor: '#202124',
    textColor: '#ffffff',
    punctuationColor: '#9aa0a6',
    stringAndValueColor: '#5bb974',
    keywordTagColor: '#669df6',
    commentColor: '#9aa0a6',
    typeColor: '#ee675c',
    numberColor: '#fcc934',
    declarationColor: '#fcc934',
    dimmedColor: '#5f6c73',
    highlightColor: '#4d555b',
    lineHeight: 1.2,
  },
  'flutter-interact-19': {
    bgColor: "#241e30",
    textColor: "#fafbfb",
    punctuationColor: "#8be9fd",
    stringAndValueColor: "#ffa65c",
    keywordTagColor: "#1cdec9",
    commentColor: "#808080",
    typeColor: "#d65bad",
    numberColor: "#bd93f9",
    declarationColor: "#ff8383",
    dimmedColor: "#87858e",
    highlightColor: '#425a6c',
    lineHeight: 1.2,
  },
  'angular-material': {
    bgColor: "#382e42",
    textColor: "#ffffff",
    punctuationColor: materialColor('light-blue', '100'),
    stringAndValueColor: "#c3e88d",
    keywordTagColor: materialColor('light-blue', '100'),
    commentColor: materialColor('grey', '500'),
    typeColor: materialColor('orange', '200'),
    numberColor: materialColor('purple', '200'),
    declarationColor: materialColor('purple', '200'),
    dimmedColor: "#4d4d4d",
    highlightColor: "#4d3663",
    lineHeight: 1.2
  }
};
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import values from 'lodash/values';
import classNames from 'classnames';
import isNullOrUndefined from './utils/isNullOrUndefined';
import ReactChildren from './utils/ReactChildren';

const propTypes = {
  name: PropTypes.string,
  inline: PropTypes.bool,
  onChange: PropTypes.func,
  value: PropTypes.any,       // eslint-disable-line react/forbid-prop-types
  defaultValue: PropTypes.any // eslint-disable-line react/forbid-prop-types
};

class RadioGroup extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.radios = {};
    this.state = {
      value: props.defaultValue
    };
  }

  handleChange(value, event) {

    const { onChange } = this.props;
    const radios = values(this.radios);
    const shouldChange = (should) => {
      if (should && onChange) {
        onChange(value, event);
      }
    };

    radios.forEach((radio, index) => {
      radio.updateCheckedState(radio.props.value === value, () => (
        shouldChange((index + 1) === radios.length)
      ));
    });

  }

  render() {

    const {
      className,
      inline,
      name,
      value,
      children,
      ...props
    } = this.props;

    const clesses = classNames({
      'radio-list': true
    }, className);

    const nextValue = value || this.state.value;
    const items = ReactChildren.mapCloneElement(children, (child, index) => {

      let childProps = {
        inline,
        name,
        checked: isNullOrUndefined(nextValue) ?
          child.props.checked : nextValue === child.props.value,
        onChange: this.handleChange,
        ref: (ref) => {
          this.radios[index] = ref;
        }
      };

      if (child.type.displayName === 'Radio') {
        return childProps;
      }

      return child.props;
    });
    return (
      <div
        {...props}
        className={clesses}
        role="button"
      >
        {items}
      </div>
    );
  }
}

RadioGroup.propTypes = propTypes;

export default RadioGroup;
<commit_msg>Fix: Radio be unchecked when value be false<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import values from 'lodash/values';
import isUndefined from 'lodash/isUndefined';
import classNames from 'classnames';
import isNullOrUndefined from './utils/isNullOrUndefined';
import ReactChildren from './utils/ReactChildren';

const propTypes = {
  name: PropTypes.string,
  inline: PropTypes.bool,
  onChange: PropTypes.func,
  value: PropTypes.any,       // eslint-disable-line react/forbid-prop-types
  defaultValue: PropTypes.any // eslint-disable-line react/forbid-prop-types
};

class RadioGroup extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.radios = {};
    this.state = {
      value: props.defaultValue
    };
  }

  handleChange(value, event) {

    const { onChange } = this.props;
    const radios = values(this.radios);
    const shouldChange = (should) => {
      if (should && onChange) {
        onChange(value, event);
      }
    };

    radios.forEach((radio, index) => {
      radio.updateCheckedState(radio.props.value === value, () => (
        shouldChange((index + 1) === radios.length)
      ));
    });

  }

  render() {

    const {
      className,
      inline,
      name,
      value,
      children,
      ...props
    } = this.props;

    const clesses = classNames({
      'radio-list': true
    }, className);

    const nextValue = isUndefined(value) ? this.state.value : value;
    const items = ReactChildren.mapCloneElement(children, (child, index) => {

      let childProps = {
        inline,
        name,
        checked: isNullOrUndefined(nextValue) ?
          child.props.checked : nextValue === child.props.value,
        onChange: this.handleChange,
        ref: (ref) => {
          this.radios[index] = ref;
        }
      };

      if (child.type.displayName === 'Radio') {
        return childProps;
      }

      return child.props;
    });
    return (
      <div
        {...props}
        className={clesses}
        role="button"
      >
        {items}
      </div>
    );
  }
}

RadioGroup.propTypes = propTypes;

export default RadioGroup;
<|endoftext|>


<commit_before>require('ember');

debit = Ember.Object.create({
    value: 'debit',
    isDebit: true,
    isCredit: false
});
credit = Ember.Object.create({
    value: 'credit',
    isDebit: false,
    isCredit: true
});

//Set opposites
debit.opposite = credit;
credit.opposite = debit;

//Set toString methods (can't be handled by Ember, crashes in older versions of IE)
debit.toString = function() {
    return '<PostingSide.debit>';
};
credit.toString = function() {
    return '<PostingSide.credit>';
};

function resolveSide(side) {
    if (side === debit || side === credit) {
        return side;
    }
    if (side === 'debit') {
        return debit;
    }
    if (side === 'credit') {
        return credit;
    }
    throw new Error('Invalid side `'+side+'`');
}

module.exports = {
    debit: debit,
    credit: credit,
    resolveSide: resolveSide
};<commit_msg>fixed global variables<commit_after>require('ember');

var debit = Ember.Object.create({
    value: 'debit',
    isDebit: true,
    isCredit: false
});

var credit = Ember.Object.create({
    value: 'credit',
    isDebit: false,
    isCredit: true
});

//Set opposites
debit.opposite = credit;
credit.opposite = debit;

//Set toString methods (can't be handled by Ember, crashes in older versions of IE)
debit.toString = function() {
    return '<PostingSide.debit>';
};
credit.toString = function() {
    return '<PostingSide.credit>';
};

function resolveSide(side) {
    if (side === debit || side === credit) {
        return side;
    }
    if (side === 'debit') {
        return debit;
    }
    if (side === 'credit') {
        return credit;
    }
    throw new Error('Invalid side `'+side+'`');
}

module.exports = {
    debit: debit,
    credit: credit,
    resolveSide: resolveSide
};<|endoftext|>


<commit_before>/*
 * OOP facilities of the library.
 * Thanks to Leaflet's inspiration (http://www.leafletjs.com)
 * @class maptalks.Class
 */
Z.Class = function () {};

Z.Class.extend = function (props) {
    // extended class with the new prototype
    var NewClass = function () {
        // call the constructor
        if (this.initialize) {
            this.initialize.apply(this, arguments);
        }

        // call all constructor hooks
        if(this._initHooks) {
            this.callInitHooks();
        }
    };

    var parentProto = NewClass.__super__ = this.prototype;

    var proto = Z.Util.create(parentProto);

    proto.constructor = NewClass;

    NewClass.prototype = proto;

    // inherit parent's statics
    for (var i in this) {
        if (this.hasOwnProperty(i) && i !== 'prototype') {
            NewClass[i] = this[i];
        }
    }

    // mix static properties into the class
    if (props.statics) {
        Z.Util.extend(NewClass, props.statics);
        delete props.statics;
    }

    // mix includes into the prototype
    if (props.includes) {
        Z.Util.extend.apply(null, [proto].concat(props.includes));
        delete props.includes;
    }

    // merge options
    if (proto.options) {
        props.options = Z.Util.extend(Z.Util.create(proto.options), props.options);
    }

    // exception definitions
    if (props.exceptionDefs) {
        var lang = Z.Browser.language;
        if ( lang !== 'zh-CN') {
            lang = 'en-US'; //only support chinese and english now;
        }
        Z.Util.extend(proto, {exceptions:props.exceptionDefs[lang]});
        delete props.exceptionDefs;
    }

    // mix given properties into the prototype
    Z.Util.extend(proto, props);

    proto._initHooks = [];

    // add method for calling all hooks
    proto.callInitHooks = function () {

        if (this._initHooksCalled ) { return; }

        if (parentProto.callInitHooks) {
            parentProto.callInitHooks.call(this);
        }

        this._initHooksCalled = true;

        for (var i = 0, len = proto._initHooks.length; i < len; i++) {
            proto._initHooks[i].call(this);
        }
    };
    // config to set option and enable/disable handler
    proto.config = function(conf) {
        if (!conf) {
            var config = {};
            for (var p in this.options) {
                if (this.options.hasOwnProperty(p)) {
                    config[p] = this.options[p];
                }
            }
            return config;
        } else {
            if (arguments.length === 2) {
                var convert = {};
                convert[conf] = arguments[1];
                conf = convert;
            }
            for (var i in conf) {
                if (conf.hasOwnProperty(i)) {
                     this.options[i] = conf[i];
                    //handler
                    if (this[i] && (this[i] instanceof Z.Handler)) {
                        if (conf[i]) {
                            this[i].enable();
                        } else {
                            this[i].disable();
                        }
                    }
                }
            }
            //callback when set config
            if (this.onConfig && (typeof this.onConfig == 'function' || (this.onConfig.constructor!==null && this.onConfig.constructor == Function))) {
                this.onConfig(conf);
            }
        }
        return this;
    };

    return NewClass;
};

// method for adding properties to prototype
Z.Class.include = function (props) {
    var sources = arguments;
    for (var j = 0, len = sources.length; j < len; j++) {
        Z.Util.extend(this.prototype, sources[j]);
    }

};

// merge new default options to the Class
Z.Class.mergeOptions = function (options) {
    Z.Util.extend(this.prototype.options, options);
};

// add a constructor hook
Z.Class.addInitHook = function (fn) { // (Function) || (String, args...)
    var args = Array.prototype.slice.call(arguments, 1);

    var init = typeof fn === 'function' ? fn : function () {
        this[fn].apply(this, args);
    };

    this.prototype._initHooks = this.prototype._initHooks || [];
    this.prototype._initHooks.push(init);
};
<commit_msg>add obj.config(conf): return value of 'conf'<commit_after>/*
 * OOP facilities of the library.
 * Thanks to Leaflet's inspiration (http://www.leafletjs.com)
 * @class maptalks.Class
 */
Z.Class = function () {};

Z.Class.extend = function (props) {
    // extended class with the new prototype
    var NewClass = function () {
        // call the constructor
        if (this.initialize) {
            this.initialize.apply(this, arguments);
        }

        // call all constructor hooks
        if(this._initHooks) {
            this.callInitHooks();
        }
    };

    var parentProto = NewClass.__super__ = this.prototype;

    var proto = Z.Util.create(parentProto);

    proto.constructor = NewClass;

    NewClass.prototype = proto;

    // inherit parent's statics
    for (var i in this) {
        if (this.hasOwnProperty(i) && i !== 'prototype') {
            NewClass[i] = this[i];
        }
    }

    // mix static properties into the class
    if (props.statics) {
        Z.Util.extend(NewClass, props.statics);
        delete props.statics;
    }

    // mix includes into the prototype
    if (props.includes) {
        Z.Util.extend.apply(null, [proto].concat(props.includes));
        delete props.includes;
    }

    // merge options
    if (proto.options) {
        props.options = Z.Util.extend(Z.Util.create(proto.options), props.options);
    }

    // exception definitions
    if (props.exceptionDefs) {
        var lang = Z.Browser.language;
        if ( lang !== 'zh-CN') {
            lang = 'en-US'; //only support chinese and english now;
        }
        Z.Util.extend(proto, {exceptions:props.exceptionDefs[lang]});
        delete props.exceptionDefs;
    }

    // mix given properties into the prototype
    Z.Util.extend(proto, props);

    proto._initHooks = [];

    // add method for calling all hooks
    proto.callInitHooks = function () {

        if (this._initHooksCalled ) { return; }

        if (parentProto.callInitHooks) {
            parentProto.callInitHooks.call(this);
        }

        this._initHooksCalled = true;

        for (var i = 0, len = proto._initHooks.length; i < len; i++) {
            proto._initHooks[i].call(this);
        }
    };
    // config to set option and enable/disable handler
    proto.config = function(conf) {
        if (!conf) {
            var config = {};
            for (var p in this.options) {
                if (this.options.hasOwnProperty(p)) {
                    config[p] = this.options[p];
                }
            }
            return config;
        } else {
            if (arguments.length === 1) {
                return this.options[conf];
            }
            if (arguments.length === 2) {
                var convert = {};
                convert[conf] = arguments[1];
                conf = convert;
            }
            for (var i in conf) {
                if (conf.hasOwnProperty(i)) {
                     this.options[i] = conf[i];
                    //handler
                    if (this[i] && (this[i] instanceof Z.Handler)) {
                        if (conf[i]) {
                            this[i].enable();
                        } else {
                            this[i].disable();
                        }
                    }
                }
            }
            //callback when set config
            if (this.onConfig && (typeof this.onConfig == 'function' || (this.onConfig.constructor!==null && this.onConfig.constructor == Function))) {
                this.onConfig(conf);
            }
        }
        return this;
    };

    return NewClass;
};

// method for adding properties to prototype
Z.Class.include = function (props) {
    var sources = arguments;
    for (var j = 0, len = sources.length; j < len; j++) {
        Z.Util.extend(this.prototype, sources[j]);
    }

};

// merge new default options to the Class
Z.Class.mergeOptions = function (options) {
    Z.Util.extend(this.prototype.options, options);
};

// add a constructor hook
Z.Class.addInitHook = function (fn) { // (Function) || (String, args...)
    var args = Array.prototype.slice.call(arguments, 1);

    var init = typeof fn === 'function' ? fn : function () {
        this[fn].apply(this, args);
    };

    this.prototype._initHooks = this.prototype._initHooks || [];
    this.prototype._initHooks.push(init);
};
<|endoftext|>


<commit_before>import React from 'react';
import { injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { Grid, Row, Col } from 'react-flexbox-grid/lib';
import * as d3 from 'd3';
import messages from '../../../resources/messages';
import QueryForm from './QueryForm';
import AppButton from '../../common/AppButton';
import ItemSlider from '../../common/ItemSlider';
import QueryPickerItem from './QueryPickerItem';
import { selectQuery, updateQuery, addCustomQuery, saveQuerySet, deleteQuery } from '../../../actions/explorerActions';
import { AddQueryButton } from '../../common/IconButton';
import { getPastTwoWeeksDateRange } from '../../../lib/dateUtil';
import { DEFAULT_COLLECTION_OBJECT_ARRAY } from '../../../lib/explorerUtil';
import { getUserRoles, hasPermissions, PERMISSION_LOGGED_IN } from '../../../lib/auth';

const localMessages = {
  mainTitle: { id: 'explorer.querypicker.mainTitle', defaultMessage: 'Query List' },
  intro: { id: 'explorer.querypicker.intro', defaultMessage: 'Here are all available queries' },
  addQuery: { id: 'explorer.querypicker.addQuery', defaultMessage: 'Add query' },
  querySearch: { id: 'explorer.queryBuilder.advanced', defaultMessage: 'Search' },
  searchHint: { id: 'explorer.queryBuilder.hint', defaultMessage: 'Search' },
};

const MAX_COLORS = 20;

class QueryPicker extends React.Component {
  addAQuery(newQueryObj) {
    const { addAQuery } = this.props;
    addAQuery(newQueryObj);
  }
  updateDemoQueryLabel(query, newValue) {
    const { updateCurrentQuery } = this.props;
    const updatedQuery = { ...query };
    updatedQuery.label = newValue;
    updatedQuery.q = newValue;
    // now update it in the store
    updateCurrentQuery(updatedQuery);
  }
  // called by query picker to update things like label or color
  updateQueryProperty(query, propertyName, newValue) {
    const { updateCurrentQuery } = this.props;
    const updatedQuery = { ...query };
    updatedQuery[propertyName] = newValue;
    // now update it in the store
    updateCurrentQuery(updatedQuery);
  }

  updateQuery(newInfo) {
    const { updateCurrentQuery, selected } = this.props;
    const updateObject = selected;
    if (newInfo.length) { // assume it's an array, and either sources or collections
      if (newInfo[0].type === 'source' || newInfo[0].media_id !== undefined) {
        updateObject.sources = newInfo; // replace
      } else if (newInfo[0].type === 'collection' || newInfo[0].tags_id !== undefined) {
        updateObject.collections = newInfo;
      }
    } else {
      const fieldName = newInfo.target ? newInfo.target.name : newInfo.name;
      const fieldValue = newInfo.target ? newInfo.target.value : newInfo.value;
      updateObject[fieldName] = fieldValue;
      // TODO check the logic of this. if demo mode and the user changes the q, label should be equivalent?
      if (fieldName === 'q') {
        updateObject.label = fieldValue;
      }
    }
    updateCurrentQuery(updateObject);
  }

  handleSaveQuerySet() {
    const { selected, saveThisQuerySet } = this.props;
    saveThisQuerySet(selected);
  }
  handleOpenStub() {
    return this.props;
  }
  isDeletable() {
    const { queries } = this.props;
    const unDeletedQueries = queries.filter(q => !q.deleted);
    return unDeletedQueries.length >= 2; // because we always have an empty query in the query array
  }
  handleDeleteAndSelectQuery(query) {
    const { queries, handleDeleteQuery } = this.props;
    const queryIndex = queries.findIndex(q => q.index !== null && q.index === query.index);
    const replaceSelectionWithWhichQuery = queryIndex === 0 ? 1 : 0; // replace with the query, not the position
    if (this.isDeletable()) {
      handleDeleteQuery(query, queries[replaceSelectionWithWhichQuery]);
    }
  }

  render() {
    const { selected, queries, user, collectionsResults, sourcesResults, handleQuerySelected, isEditable, handleSearch } = this.props;
    const { formatMessage } = this.props.intl;
    let queryPickerContent; // editable if demo mode
    let queryFormContent; // hidden if demo mode
    let fixedQuerySlides;
    let canSelectMedia = false;
    const userLoggedIn = hasPermissions(getUserRoles(user), PERMISSION_LOGGED_IN);

    const unDeletedQueries = queries.filter(q => !q.deleted);
    if (unDeletedQueries && unDeletedQueries.length > 0 && selected &&
      collectionsResults && collectionsResults.length > 0 &&
      sourcesResults && sourcesResults.length >= 0) {
      fixedQuerySlides = unDeletedQueries.map((query, index) => (

          <QueryPickerItem
            user={user}
            key={index}
            query={query}
            isSelected={selected.index === query.index}
            isEditable={isEditable} // if custom, true for either mode, else if logged in no
            isDeletable={() => this.isDeletable()}
            displayLabel={false}
            onQuerySelected={() => handleQuerySelected(query, query.index ? query.index : index)} // careful! unDeleted has different index
            updateQueryProperty={(propertyName, newValue) => this.updateQueryProperty(query, propertyName, newValue)}
            updateDemoQueryLabel={newValue => this.updateDemoQueryLabel(query, newValue)}
            handleSearch={handleSearch}
            handleDeleteQuery={() => this.handleDeleteAndSelectQuery(query)}
            // loadDialog={loadQueryEditDialog}
          />

      ));
      canSelectMedia = userLoggedIn;
      // provide the add Query button, load with default values when Added is clicked
      if (isEditable) {
        const colorPallette = idx => d3.schemeCategory20[idx < MAX_COLORS ? idx : 0];
        const dateObj = getPastTwoWeeksDateRange();
        const newIndex = queries.length; // NOTE: all queries, including 'deleted' ones
        const genDefColor = colorPallette(newIndex);
        const defaultQuery = { index: newIndex, label: 'enter query', q: '', description: 'new', startDate: dateObj.start, endDate: dateObj.end, collections: DEFAULT_COLLECTION_OBJECT_ARRAY, sources: [], color: genDefColor, custom: true };

        const emptyQuerySlide = (

                <AddQueryButton
                  key={fixedQuerySlides.length} // this isn't working
                  tooltip={formatMessage(localMessages.addQuery)}
                  onClick={() => this.addAQuery(defaultQuery)}
                />
                <FormattedMessage {...localMessages.addQuery} />

        );

        fixedQuerySlides.push(emptyQuerySlide);
      }
      let demoSearchButtonContent; // in demo mode we need a search button outside the form (cause we can't see the form)
      if (!userLoggedIn) {
        demoSearchButtonContent = (
          <Grid>
            <Row>
              <Col lg={10} />
              <Col lg={1}>
                <AppButton
                  style={{ marginTop: 30 }}
                  type="submit"
                  label={formatMessage(messages.search)}
                  primary
                  onTouchTap={handleSearch}
                />
              </Col>
            </Row>
          </Grid>
        );
      }
      queryPickerContent = (

            <Grid>
              <ItemSlider
                title={formatMessage(localMessages.intro)}
                slides={fixedQuerySlides}
                settings={{ height: 60, dots: false, slidesToShow: 4, slidesToScroll: 1, infinite: false, arrows: fixedQuerySlides.length > 4 }}
              />
            </Grid>

          {demoSearchButtonContent}

      );
      if (userLoggedIn) {  // if logged in show full form
        queryFormContent = (
          <QueryForm
            initialValues={selected}
            selected={selected}
            form="queryForm"
            enableReinitialize
            destroyOnUnmount={false}
            buttonLabel={formatMessage(localMessages.querySearch)}
            onSave={handleSearch}
            onChange={event => this.updateQuery(event)}
            handleOpenHelp={this.handleOpenStub}
            handleSaveQuerySet={q => this.handleSaveQuerySet(q)}
            isEditable={canSelectMedia}
          />
        );
      }
      // indicate which queryPickerItem is selected -
      // const selectedWithSandCLabels = queries.find(q => q.index === selected.index);
      return (

          {queryPickerContent}
          {queryFormContent}

      );
    }
    return ('error - no queries ');
  }
}

QueryPicker.propTypes = {
  user: React.PropTypes.object.isRequired,
  queries: React.PropTypes.array,
  sourcesResults: React.PropTypes.array,
  collectionsResults: React.PropTypes.array,
  fetchStatus: React.PropTypes.string.isRequired,
  selected: React.PropTypes.object,
  intl: React.PropTypes.object.isRequired,
  handleQuerySelected: React.PropTypes.func.isRequired,
  isEditable: React.PropTypes.bool.isRequired,
  isDeletable: React.PropTypes.func,
  handleSearch: React.PropTypes.func.isRequired,
  updateCurrentQuery: React.PropTypes.func.isRequired,
  handleDeleteAndSelectQuery: React.PropTypes.func,
  handleDeleteQuery: React.PropTypes.func.isRequired,
  saveThisQuerySet: React.PropTypes.func.isRequired,
  addAQuery: React.PropTypes.func.isRequired,
  handleOpenStub: React.PropTypes.func,
};

const mapStateToProps = state => ({
  selected: state.explorer.selected,
  queries: state.explorer.queries.queries,
  sourcesResults: state.explorer.queries.sources.results ? state.explorer.queries.sources.results : null,
  collectionsResults: state.explorer.queries.collections.results ? state.explorer.queries.collections.results : null,
  fetchStatus: state.explorer.queries.collections.fetchStatus,
  user: state.user,
  // formData: formSelector(state, 'q', 'start_date', 'end_date', 'color'),
});

const mapDispatchToProps = (dispatch, ownProps) => ({
  handleQuerySelected: (query, index) => {
    const queryWithIndex = Object.assign({}, query, { index }); // if this doesn't exist...
    dispatch(selectQuery(queryWithIndex));
  },
  updateCurrentQuery: (query) => {
    if (query) {
      dispatch(updateQuery(query));
    } else {
      dispatch(updateQuery(ownProps.selected)); // this won't e right
    }
  },
  addAQuery: (query) => {
    if (query) {
      dispatch(addCustomQuery(query));
      dispatch(selectQuery(query));
    }
  },
  saveThisQuerySet: (query) => {
    if (query) { // TODO - save as JSON
      dispatch(saveQuerySet({ label: query.label, query_string: query.q }));
    }
  },
  handleDeleteQuery: (query, replacementSelectionQuery) => {
    if (query) {
      dispatch(deleteQuery(query)); // will change queries, but not URL, this is the problem
      dispatch(selectQuery(replacementSelectionQuery));
    }
  },
});

export default
  injectIntl(
    connect(mapStateToProps, mapDispatchToProps)(
      QueryPicker
    )
  );

<commit_msg>Enable adding if user is logged in<commit_after>import React from 'react';
import { injectIntl, FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { Grid, Row, Col } from 'react-flexbox-grid/lib';
import * as d3 from 'd3';
import messages from '../../../resources/messages';
import QueryForm from './QueryForm';
import AppButton from '../../common/AppButton';
import ItemSlider from '../../common/ItemSlider';
import QueryPickerItem from './QueryPickerItem';
import { selectQuery, updateQuery, addCustomQuery, saveQuerySet, deleteQuery } from '../../../actions/explorerActions';
import { AddQueryButton } from '../../common/IconButton';
import { getPastTwoWeeksDateRange } from '../../../lib/dateUtil';
import { DEFAULT_COLLECTION_OBJECT_ARRAY } from '../../../lib/explorerUtil';
import { getUserRoles, hasPermissions, PERMISSION_LOGGED_IN } from '../../../lib/auth';

const localMessages = {
  mainTitle: { id: 'explorer.querypicker.mainTitle', defaultMessage: 'Query List' },
  intro: { id: 'explorer.querypicker.intro', defaultMessage: 'Here are all available queries' },
  addQuery: { id: 'explorer.querypicker.addQuery', defaultMessage: 'Add query' },
  querySearch: { id: 'explorer.queryBuilder.advanced', defaultMessage: 'Search' },
  searchHint: { id: 'explorer.queryBuilder.hint', defaultMessage: 'Search' },
};

const MAX_COLORS = 20;

class QueryPicker extends React.Component {
  addAQuery(newQueryObj) {
    const { addAQuery } = this.props;
    addAQuery(newQueryObj);
  }
  updateDemoQueryLabel(query, newValue) {
    // update both label and q for query
    const { updateCurrentQuery } = this.props;
    const updatedQuery = { ...query };
    updatedQuery.label = newValue;
    updatedQuery.q = newValue;
    updateCurrentQuery(updatedQuery);
  }
  // called by query picker to update things like label or color
  updateQueryProperty(query, propertyName, newValue) {
    const { updateCurrentQuery } = this.props;
    const updatedQuery = { ...query };
    updatedQuery[propertyName] = newValue;
    // now update it in the store
    updateCurrentQuery(updatedQuery);
  }

  updateQuery(newInfo) {
    const { updateCurrentQuery, selected } = this.props;
    const updateObject = selected;
    if (newInfo.length) { // assume it's an array, and either sources or collections
      if (newInfo[0].type === 'source' || newInfo[0].media_id !== undefined) {
        updateObject.sources = newInfo; // replace
      } else if (newInfo[0].type === 'collection' || newInfo[0].tags_id !== undefined) {
        updateObject.collections = newInfo;
      }
    } else {
      const fieldName = newInfo.target ? newInfo.target.name : newInfo.name;
      const fieldValue = newInfo.target ? newInfo.target.value : newInfo.value;
      updateObject[fieldName] = fieldValue;
      // TODO check the logic of this. if demo mode and the user changes the q, label should be equivalent?
      if (fieldName === 'q') {
        updateObject.label = fieldValue;
      }
    }
    updateCurrentQuery(updateObject);
  }

  handleSaveQuerySet() {
    const { selected, saveThisQuerySet } = this.props;
    saveThisQuerySet(selected);
  }
  handleOpenStub() {
    return this.props;
  }
  isDeletable() {
    const { queries } = this.props;
    const unDeletedQueries = queries.filter(q => !q.deleted);
    return unDeletedQueries.length >= 2; // because we always have an empty query in the query array
  }
  handleDeleteAndSelectQuery(query) {
    const { queries, handleDeleteQuery } = this.props;
    const queryIndex = queries.findIndex(q => q.index !== null && q.index === query.index);
    const replaceSelectionWithWhichQuery = queryIndex === 0 ? 1 : 0; // replace with the query, not the position
    if (this.isDeletable()) {
      handleDeleteQuery(query, queries[replaceSelectionWithWhichQuery]);
    }
  }

  render() {
    const { selected, queries, user, collectionsResults, sourcesResults, handleQuerySelected, isEditable, handleSearch } = this.props;
    const { formatMessage } = this.props.intl;
    let queryPickerContent; // editable if demo mode
    let queryFormContent; // hidden if demo mode
    let fixedQuerySlides;
    let canSelectMedia = false;
    const userLoggedIn = hasPermissions(getUserRoles(user), PERMISSION_LOGGED_IN);

    const unDeletedQueries = queries.filter(q => !q.deleted);
    if (unDeletedQueries && unDeletedQueries.length > 0 && selected &&
      collectionsResults && collectionsResults.length > 0 &&
      sourcesResults && sourcesResults.length >= 0) {
      fixedQuerySlides = unDeletedQueries.map((query, index) => (

          <QueryPickerItem
            user={user}
            key={index}
            query={query}
            isSelected={selected.index === query.index}
            isLabelEditable={isEditable} // if custom, true for either mode, else if logged in no
            isDeletable={() => this.isDeletable()}
            displayLabel={false}
            onQuerySelected={() => handleQuerySelected(query, query.index ? query.index : index)} // careful! unDeleted has different index
            updateQueryProperty={(propertyName, newValue) => this.updateQueryProperty(query, propertyName, newValue)}
            updateDemoQueryLabel={newValue => this.updateDemoQueryLabel(query, newValue)}
            handleSearch={handleSearch}
            handleDeleteQuery={() => this.handleDeleteAndSelectQuery(query)}
            // loadDialog={loadQueryEditDialog}
          />

      ));
      canSelectMedia = userLoggedIn;
      // provide the add Query button, load with default values when Added is clicked
      if (userLoggedIn) {
        const colorPallette = idx => d3.schemeCategory20[idx < MAX_COLORS ? idx : 0];
        const dateObj = getPastTwoWeeksDateRange();
        const newIndex = queries.length; // NOTE: all queries, including 'deleted' ones
        const genDefColor = colorPallette(newIndex);
        const defaultQuery = { index: newIndex, label: 'enter query', q: '', description: 'new', startDate: dateObj.start, endDate: dateObj.end, collections: DEFAULT_COLLECTION_OBJECT_ARRAY, sources: [], color: genDefColor, custom: true };

        const emptyQuerySlide = (

                <AddQueryButton
                  key={fixedQuerySlides.length} // this isn't working
                  tooltip={formatMessage(localMessages.addQuery)}
                  onClick={() => this.addAQuery(defaultQuery)}
                />
                <FormattedMessage {...localMessages.addQuery} />

        );

        fixedQuerySlides.push(emptyQuerySlide);
      }
      let demoSearchButtonContent; // in demo mode we need a search button outside the form (cause we can't see the form)
      if (!userLoggedIn) {
        demoSearchButtonContent = (
          <Grid>
            <Row>
              <Col lg={10} />
              <Col lg={1}>
                <AppButton
                  style={{ marginTop: 30 }}
                  type="submit"
                  label={formatMessage(messages.search)}
                  primary
                  onTouchTap={handleSearch}
                />
              </Col>
            </Row>
          </Grid>
        );
      }
      queryPickerContent = (

            <Grid>
              <ItemSlider
                title={formatMessage(localMessages.intro)}
                slides={fixedQuerySlides}
                settings={{ height: 60, dots: false, slidesToShow: 4, slidesToScroll: 1, infinite: false, arrows: fixedQuerySlides.length > 4 }}
              />
            </Grid>

          {demoSearchButtonContent}

      );
      if (userLoggedIn) {  // if logged in show full form
        queryFormContent = (
          <QueryForm
            initialValues={selected}
            selected={selected}
            form="queryForm"
            enableReinitialize
            destroyOnUnmount={false}
            buttonLabel={formatMessage(localMessages.querySearch)}
            onSave={handleSearch}
            onChange={event => this.updateQuery(event)}
            handleOpenHelp={this.handleOpenStub}
            handleSaveQuerySet={q => this.handleSaveQuerySet(q)}
            isEditable={canSelectMedia}
          />
        );
      }
      // indicate which queryPickerItem is selected -
      // const selectedWithSandCLabels = queries.find(q => q.index === selected.index);
      return (

          {queryPickerContent}
          {queryFormContent}

      );
    }
    return ('error - no queries ');
  }
}

QueryPicker.propTypes = {
  user: React.PropTypes.object.isRequired,
  queries: React.PropTypes.array,
  sourcesResults: React.PropTypes.array,
  collectionsResults: React.PropTypes.array,
  fetchStatus: React.PropTypes.string.isRequired,
  selected: React.PropTypes.object,
  intl: React.PropTypes.object.isRequired,
  handleQuerySelected: React.PropTypes.func.isRequired,
  isEditable: React.PropTypes.bool.isRequired,
  isDeletable: React.PropTypes.func,
  handleSearch: React.PropTypes.func.isRequired,
  updateCurrentQuery: React.PropTypes.func.isRequired,
  handleDeleteAndSelectQuery: React.PropTypes.func,
  handleDeleteQuery: React.PropTypes.func.isRequired,
  saveThisQuerySet: React.PropTypes.func.isRequired,
  addAQuery: React.PropTypes.func.isRequired,
  handleOpenStub: React.PropTypes.func,
};

const mapStateToProps = state => ({
  selected: state.explorer.selected,
  queries: state.explorer.queries.queries,
  sourcesResults: state.explorer.queries.sources.results ? state.explorer.queries.sources.results : null,
  collectionsResults: state.explorer.queries.collections.results ? state.explorer.queries.collections.results : null,
  fetchStatus: state.explorer.queries.collections.fetchStatus,
  user: state.user,
  // formData: formSelector(state, 'q', 'start_date', 'end_date', 'color'),
});

const mapDispatchToProps = (dispatch, ownProps) => ({
  handleQuerySelected: (query, index) => {
    const queryWithIndex = Object.assign({}, query, { index }); // if this doesn't exist...
    dispatch(selectQuery(queryWithIndex));
  },
  updateCurrentQuery: (query) => {
    if (query) {
      dispatch(updateQuery(query));
    } else {
      dispatch(updateQuery(ownProps.selected)); // this won't e right
    }
  },
  addAQuery: (query) => {
    if (query) {
      dispatch(addCustomQuery(query));
      dispatch(selectQuery(query));
    }
  },
  saveThisQuerySet: (query) => {
    if (query) { // TODO - save as JSON
      dispatch(saveQuerySet({ label: query.label, query_string: query.q }));
    }
  },
  handleDeleteQuery: (query, replacementSelectionQuery) => {
    if (query) {
      dispatch(deleteQuery(query)); // will change queries, but not URL, this is the problem
      dispatch(selectQuery(replacementSelectionQuery));
    }
  },
});

export default
  injectIntl(
    connect(mapStateToProps, mapDispatchToProps)(
      QueryPicker
    )
  );

<|endoftext|>


<commit_before>/**
 * @author alteredq / http://alteredqualia.com/
 */

THREE.Clock = function ( autoStart ) {

	this.autoStart = ( autoStart !== undefined ) ? autoStart : true;

	this.startTime = 0;
	this.oldTime = 0;
	this.elapsedTime = 0;

	this.running = false;

};

THREE.Clock.prototype = {

	constructor: THREE.Clock,

	start: function () {

		this.startTime = self.performance !== undefined && self.performance.now !== undefined
					 ? self.performance.now()
					 : Date.now();

		this.oldTime = this.startTime;
		this.running = true;
	},

	stop: function () {

		this.getElapsedTime();
		this.running = false;

	},

	getElapsedTime: function () {

		this.getDelta();
		return this.elapsedTime;

	},

	getDelta: function () {

		var diff = 0;

		if ( this.autoStart && ! this.running ) {

			this.start();

		}

		if ( this.running ) {

			var newTime = self.performance !== undefined && self.performance.now !== undefined
					 ? self.performance.now()
					 : Date.now();

			diff = 0.001 * ( newTime - this.oldTime );
			this.oldTime = newTime;

			this.elapsedTime += diff;

		}

		return diff;

	}

};
<commit_msg>Fixing the Clock to work with Qt QML.<commit_after>/**
 * @author alteredq / http://alteredqualia.com/
 */

THREE.Clock = function ( autoStart ) {

	this.autoStart = ( autoStart !== undefined ) ? autoStart : true;

	this.startTime = 0;
	this.oldTime = 0;
	this.elapsedTime = 0;

	this.running = false;

};

THREE.Clock.prototype = {

	constructor: THREE.Clock,

	start: function () {

        this.startTime = ( Qt === undefined &&
                           self.performance !== undefined &&
                           self.performance.now !== undefined )
                     ? self.performance.now()
                     : Date.now();

		this.oldTime = this.startTime;
		this.running = true;
	},

	stop: function () {

		this.getElapsedTime();
		this.running = false;

	},

	getElapsedTime: function () {

		this.getDelta();
		return this.elapsedTime;

	},

	getDelta: function () {

		var diff = 0;

		if ( this.autoStart && ! this.running ) {

			this.start();

		}

		if ( this.running ) {

            var newTime = ( Qt === undefined &&
                               self.performance !== undefined &&
                               self.performance.now !== undefined )
                         ? self.performance.now()
                         : Date.now();

			diff = 0.001 * ( newTime - this.oldTime );
			this.oldTime = newTime;

			this.elapsedTime += diff;

		}

		return diff;

	}

};
<|endoftext|>


<commit_before>import React, {Component, PropTypes} from 'react';
import ReactDOM from 'react-dom';
import ComponentBaseBehaviour from '../../../behaviours/component-base';
import MDBehaviour from '../../../behaviours/material';

@MDBehaviour('materialInput')
@ComponentBaseBehaviour
class AutocompleteTextEdit extends Component {
    static defaultProps = {
        placeholder: 'Search here...'
    };

    static propTypes = {
        querySearcher: PropTypes.func.isRequired,
        value: PropTypes.string,
        onChange: PropTypes.func.isRequired,
        error: PropTypes.string,
        placeholder: PropTypes.string
    };

    state = {
        inputValue: this.props.value,
        suggestions: [],
        hasSuggestions: false,
        error: this.props.error,
        hasFocus: false
    };

    // Returns the state's inputValue
    getValue = () =>  {
        const {inputValue} = this.state;
        if(inputValue !== undefined)
        return inputValue;
        else
        return null;
    }
    componentWillUpdate(){
        //console.log('The component will update', this.state, this.props);
    }
    componentDidUpdate() {
        if (this.state.error != '')
        this.refs.inputText.classList.add('is-invalid');
        else
        this.refs.inputText.classList.remove('is-invalid');

    }

    // Get the defined props' querySearch and return the object given by the promise
    // Sets the hasSuggestions' state if the given object has a none empty array
    _querySearcher = value => {
        const {querySearcher} = this.props;
        const {hasSuggestions} = this.state;

        querySearcher(value).then(({data, totalCount}) => {
            if(totalCount > 0) {
                this.setState({hasSuggestions: true, suggestions: data, error: ''});
            }
            else if(totalCount === 0 && this.props.error == '') {
                this.setState({error: 'No data founded'});
            }
            else if(totalCount === 0 && this.props.error != '') {
                this.setState({error: this.props.error});
            }
            else if(totalCount === 1 && data[0].key == 'ERR') {
                //Here temporary solution to give the opportunity for the dev to have a error list dropdown message
                this.setState({hasSuggestions: true, suggestions: data, error: ''});
            }
        }).catch(err => {
            this.setState({error: JSON.stringify(err)});
            this.refs.materialInput.classList.add('is-invalid');
        });
    }

    // Sets the state's inputValue when the user is typing
    onQueryChange = ({target: {value}}) => {
        this.setState({inputValue: value});
        if(!value)
            this.setState({hasSuggestions: false});
        else
            this._querySearcher(value);
    }

    onResultClick(value) {
        this.refs.inputText.value = value;
        this.setState({inputValue: value, hasSuggestions: false});
        return value;
    }

    // Returns an html list whith the Suggestions
    renderSuggestions = () => {
        const {suggestions} = this.state;
        const allSuggestions = suggestions.map(({key, label}, index) => <li ref={`result${index}`} key={key} onMouseDown={() => {this.onResultClick(label)}} data-focus='option' >{label}
);
        return(

                {allSuggestions}

        );
    }

    toggleHasFocus = e => {
        const {hasSuggestions} = this.state;
        this.setState({hasFocus: !this.state.hasFocus});
        if(hasSuggestions)
        this.setState({hasSuggestions: false})
        return true;
    }

    //Maybe give the option for the floating label
    render() {
        const {inputValue, hasSuggestions, error, hasFocus, ...otherProps} = this.state;
        const {placeholder} = this.props
        return(

                    <input onFocus={this.toggleHasFocus} onBlur={this.toggleHasFocus} className='mdl-textfield__input' type='text' value={inputValue} ref='inputText' onChange={::this.onQueryChange} {...otherProps} />
                    {placeholder}
                    {error}

                {hasSuggestions && hasFocus &&
                    this.renderSuggestions()
                }

        );
    }
}

export default AutocompleteTextEdit;
<commit_msg>Adjusting the case when the input is empty even when the space bar is typed<commit_after>import React, {Component, PropTypes} from 'react';
import ReactDOM from 'react-dom';
import ComponentBaseBehaviour from '../../../behaviours/component-base';
import MDBehaviour from '../../../behaviours/material';

@MDBehaviour('materialInput')
@ComponentBaseBehaviour
class AutocompleteTextEdit extends Component {
    static defaultProps = {
        placeholder: 'Search here...'
    };

    static propTypes = {
        querySearcher: PropTypes.func.isRequired,
        value: PropTypes.string,
        onChange: PropTypes.func.isRequired,
        error: PropTypes.string,
        placeholder: PropTypes.string
    };

    state = {
        inputValue: this.props.value,
        suggestions: [],
        hasSuggestions: false,
        error: this.props.error,
        hasFocus: false
    };

    // Returns the state's inputValue
    getValue = () =>  {
        const {inputValue} = this.state;
        if(inputValue !== undefined)
        return inputValue;
        else
        return null;
    }
    componentWillUpdate(){
        //console.log('The component will update', this.state, this.props);
    }
    componentDidUpdate() {
        if (this.state.error != '')
        this.refs.inputText.classList.add('is-invalid');
        else
        this.refs.inputText.classList.remove('is-invalid');

    }

    // Get the defined props' querySearch and return the object given by the promise
    // Sets the hasSuggestions' state if the given object has a none empty array
    _querySearcher = value => {
        const {querySearcher} = this.props;
        const {hasSuggestions} = this.state;

        querySearcher(value).then(({data, totalCount}) => {
            if(totalCount > 0) {
                this.setState({hasSuggestions: true, suggestions: data, error: ''});
            }
            else if(totalCount === 0 && this.props.error == '') {
                this.setState({error: 'No data founded'});
            }
            else if(totalCount === 0 && this.props.error != '') {
                this.setState({error: this.props.error});
            }
            else if(totalCount === 1 && data[0].key == 'ERR') {
                //Here temporary solution to give the opportunity for the dev to have a error list dropdown message
                this.setState({hasSuggestions: true, suggestions: data, error: ''});
            }
        }).catch(err => {
            this.setState({error: JSON.stringify(err)});
            this.refs.materialInput.classList.add('is-invalid');
        });
    }

    // Sets the state's inputValue when the user is typing
    onQueryChange = ({target: {value}}) => {
        this.setState({inputValue: value});
        if(value.trim() == '')
            this.setState({hasSuggestions: false});
        else
            this._querySearcher(value);
    }

    onResultClick(value) {
        this.refs.inputText.value = value;
        this.setState({inputValue: value, hasSuggestions: false});
        return value;
    }

    // Returns an html list whith the Suggestions
    renderSuggestions = () => {
        const {suggestions} = this.state;
        const allSuggestions = suggestions.map(({key, label}, index) => <li ref={`result${index}`} key={key} onMouseDown={() => {this.onResultClick(label)}} data-focus='option' >{label}
);
        return(

                {allSuggestions}

        );
    }

    toggleHasFocus = e => {
        const {hasSuggestions} = this.state;
        this.setState({hasFocus: !this.state.hasFocus});
        if(hasSuggestions)
        this.setState({hasSuggestions: false})
        return true;
    }

    //Maybe give the option for the floating label
    render() {
        const {inputValue, hasSuggestions, error, hasFocus, ...otherProps} = this.state;
        const {placeholder} = this.props
        return(

                    <input onFocus={this.toggleHasFocus} onBlur={this.toggleHasFocus} className='mdl-textfield__input' type='text' value={inputValue} ref='inputText' onChange={::this.onQueryChange} {...otherProps} />
                    {placeholder}
                    {error}

                {hasSuggestions && hasFocus &&
                    this.renderSuggestions()
                }

        );
    }
}

export default AutocompleteTextEdit;
<|endoftext|>