<commit_before>
/*import MaterialDateTimePicker from 'material-datetime-picker';*/
{

    let dp_soon = moment(Number($('.c-datepicker-input').val()));
    if(!dp_soon._isValid) dp_soon = moment().add(2, 'h').minute(0);
    $('.c-datepicker-input').val( dp_soon.format('HH:mm YYYY/MM/DD') );

    const picker = new MaterialDatetimePicker({defualt: dp_soon, min: moment()}).on('submit', value => {
        if(value.toDate() < Date.now()) value = moment().add(2, 'h').minute(0);
        $('.c-datepicker-input').val( value.format('HH:mm YYYY/MM/DD') );
    });

    $('.c-datepicker-input').focus( e => {
        e.preventDefault();
        picker.open();
    });

    $('.req-ing-table input[name="req_want"], .req-ing-table input[name="req_have"]').change(function(e){

        if($(this).attr('name') === 'req_want'){ //set the other to false
            $('input[name="req_have"][value="'+$(this).attr('value')+'"]').prop('checked', false);
        } else {
            $('input[name="req_want"][value="'+$(this).attr('value')+'"]').prop('checked', false);
        }

        setTimeout(()=>{
            $('.req-have-table tbody tr, .req-want-table tbody tr').remove();
            $('.req-ing-table input[name="req_want"]:checked').each(function(){
                $('.req-want-table tbody').append('
'+$(this).attr('value')+'
');
            });
            $('.req-ing-table input[name="req_have"]:checked').each(function(){
                $('.req-have-table tbody').append('
'+$(this).attr('value')+'
');
            });
            $('.req-have-table tbody tr td').click(function(){
                $('input[name="req_have"][value="'+$(this).text()+'"]').prop('checked', false);
                $(this).remove();
            });
            $('.req-want-table tbody tr td').click(function(){
                $('input[name="req_want"][value="'+$(this).text()+'"]').prop('checked', false);
                $(this).remove();
            });
        }, 50);
    });

    $('input#req-ing-search').keyup(function(){
        if($(this).val().trim() !== ''){
            $('.req-ing-table tbody tr').hide();
            $('.req-ing-table tbody tr[data-text*="'+$(this).val()+'"]').show();
        } else {
            $('.req-ing-table tbody tr').show();
        }
    });

    $('button[type="submit"]').click(() => {
        $('input#req-end').val(new Date($('input#req-end').val()).getTime());
    });

}

var initMap = function(){

    // setup objects //
    let geocoder = new google.maps.Geocoder();
    let autocomplete = new google.maps.places.Autocomplete(document.getElementById('req-loc'), {componentRestrictions: {country: 'au'}});

    let getLoc = new google.maps.LatLng( -26.0906899, 128.1506632);

    let map = new google.maps.Map(document.getElementById('req_getLocMap'), {
      center: getLoc,
      zoom: 5
    });

    let marker = new google.maps.Marker({
        map,
        position: getLoc
    });

    let circle = new google.maps.Circle({
        map,
        center: getLoc,
        radius: (Number($('input#req-dist').val()) || 2) * 1000,
        fillColor: "#004445",
        fillOpacity: 0.5,
        strokeWeight: 0,
        clickable: false
    });

    // setup helper functions //

    let updatePos = (e, dontName = false)=>{
        if(dontName){
            getLoc = e.latLng;
            marker.setPosition(getLoc);
            circle.setCenter(getLoc);
            map.setCenter(getLoc);
            $('input#req-lat').val(getLoc.lat());
            $('input#req-long').val(getLoc.lng());
        } else {
            geocoder.geocode( { location: e.latLng}, (results, status) => {
                if (status == 'OK') {
                    updatePos({latLng: results[0].geometry.location}, true);
                    $('input#req-loc').val(results[0].formatted_address);
                } else {
                    console.log(status);
                    updatePos({latLng: e.latLng});
                }
                map.setZoom(14);
            });
        }
    };

    let geoErr = (hasGeo) => {
        if(hasGeo) swal('Error', 'You must allow location permission.', 'error');
        else swal('Error', 'Unfortunately your browser does not support getting your location, try using firefox or chrome.', 'error');
    }

    // handle events //

    map.addListener('click', updatePos);

    $('button.getloc').click( e => {
        e.preventDefault();
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(position => {
                let geoloc = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                updatePos({latLng: geoloc});
            }, ()=> {
                geoErr(true);
            });
        } else geoErr(false);
    });

    $('input#req-dist').change( () => {
        circle.setRadius((Number($('input#req-dist').val()) || 2) * 1000);
    });

    $('input#req-loc').change( e => {
        setTimeout( ()=>{
            geocoder.geocode( { address: $('input#req-loc').val(), region: 'au'}, (results, status) => {
                if (status == 'OK') {
                    updatePos({latLng: results[0].geometry.location}, true);
                    console.log(results);
                    //$('input#req-loc').val(results[0].formatted_address);
                } else {
                    alert('Adress lookup failed. ' + status);
                }
                map.setZoom(14);
            });
        }, 100);
    });

    // load passed lat-long if passed
    if(
        $('input#req-lat').val() !== "" &&
        !isNaN(Number($('input#req-lat').val())) &&
        $('input#req-long').val() !== "" &&
        !isNaN(Number($('input#req-long').val()))
    ){
        updatePos({
            latLng: new google.maps.LatLng(Number($('input#req-lat').val()), Number($('input#req-long').val()))
        });
    }
};<commit_msg>log it<commit_after>
/*import MaterialDateTimePicker from 'material-datetime-picker';*/
{

    let dp_soon = moment(Number($('.c-datepicker-input').val()));
    console.log(dp_soon);
    if(!dp_soon._isValid) dp_soon = moment().add(2, 'h').minute(0);
    $('.c-datepicker-input').val( dp_soon.format('HH:mm YYYY/MM/DD') );

    const picker = new MaterialDatetimePicker({defualt: dp_soon, min: moment()}).on('submit', value => {
        if(value.toDate() < Date.now()) value = moment().add(2, 'h').minute(0);
        $('.c-datepicker-input').val( value.format('HH:mm YYYY/MM/DD') );
    });

    $('.c-datepicker-input').focus( e => {
        e.preventDefault();
        picker.open();
    });

    $('.req-ing-table input[name="req_want"], .req-ing-table input[name="req_have"]').change(function(e){

        if($(this).attr('name') === 'req_want'){ //set the other to false
            $('input[name="req_have"][value="'+$(this).attr('value')+'"]').prop('checked', false);
        } else {
            $('input[name="req_want"][value="'+$(this).attr('value')+'"]').prop('checked', false);
        }

        setTimeout(()=>{
            $('.req-have-table tbody tr, .req-want-table tbody tr').remove();
            $('.req-ing-table input[name="req_want"]:checked').each(function(){
                $('.req-want-table tbody').append('
'+$(this).attr('value')+'
');
            });
            $('.req-ing-table input[name="req_have"]:checked').each(function(){
                $('.req-have-table tbody').append('
'+$(this).attr('value')+'
');
            });
            $('.req-have-table tbody tr td').click(function(){
                $('input[name="req_have"][value="'+$(this).text()+'"]').prop('checked', false);
                $(this).remove();
            });
            $('.req-want-table tbody tr td').click(function(){
                $('input[name="req_want"][value="'+$(this).text()+'"]').prop('checked', false);
                $(this).remove();
            });
        }, 50);
    });

    $('input#req-ing-search').keyup(function(){
        if($(this).val().trim() !== ''){
            $('.req-ing-table tbody tr').hide();
            $('.req-ing-table tbody tr[data-text*="'+$(this).val()+'"]').show();
        } else {
            $('.req-ing-table tbody tr').show();
        }
    });

    $('button[type="submit"]').click(() => {
        $('input#req-end').val(new Date($('input#req-end').val()).getTime());
    });

}

var initMap = function(){

    // setup objects //
    let geocoder = new google.maps.Geocoder();
    let autocomplete = new google.maps.places.Autocomplete(document.getElementById('req-loc'), {componentRestrictions: {country: 'au'}});

    let getLoc = new google.maps.LatLng( -26.0906899, 128.1506632);

    let map = new google.maps.Map(document.getElementById('req_getLocMap'), {
      center: getLoc,
      zoom: 5
    });

    let marker = new google.maps.Marker({
        map,
        position: getLoc
    });

    let circle = new google.maps.Circle({
        map,
        center: getLoc,
        radius: (Number($('input#req-dist').val()) || 2) * 1000,
        fillColor: "#004445",
        fillOpacity: 0.5,
        strokeWeight: 0,
        clickable: false
    });

    // setup helper functions //

    let updatePos = (e, dontName = false)=>{
        if(dontName){
            getLoc = e.latLng;
            marker.setPosition(getLoc);
            circle.setCenter(getLoc);
            map.setCenter(getLoc);
            $('input#req-lat').val(getLoc.lat());
            $('input#req-long').val(getLoc.lng());
        } else {
            geocoder.geocode( { location: e.latLng}, (results, status) => {
                if (status == 'OK') {
                    updatePos({latLng: results[0].geometry.location}, true);
                    $('input#req-loc').val(results[0].formatted_address);
                } else {
                    console.log(status);
                    updatePos({latLng: e.latLng});
                }
                map.setZoom(14);
            });
        }
    };

    let geoErr = (hasGeo) => {
        if(hasGeo) swal('Error', 'You must allow location permission.', 'error');
        else swal('Error', 'Unfortunately your browser does not support getting your location, try using firefox or chrome.', 'error');
    }

    // handle events //

    map.addListener('click', updatePos);

    $('button.getloc').click( e => {
        e.preventDefault();
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(position => {
                let geoloc = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                updatePos({latLng: geoloc});
            }, ()=> {
                geoErr(true);
            });
        } else geoErr(false);
    });

    $('input#req-dist').change( () => {
        circle.setRadius((Number($('input#req-dist').val()) || 2) * 1000);
    });

    $('input#req-loc').change( e => {
        setTimeout( ()=>{
            geocoder.geocode( { address: $('input#req-loc').val(), region: 'au'}, (results, status) => {
                if (status == 'OK') {
                    updatePos({latLng: results[0].geometry.location}, true);
                    console.log(results);
                    //$('input#req-loc').val(results[0].formatted_address);
                } else {
                    alert('Adress lookup failed. ' + status);
                }
                map.setZoom(14);
            });
        }, 100);
    });

    // load passed lat-long if passed
    if(
        $('input#req-lat').val() !== "" &&
        !isNaN(Number($('input#req-lat').val())) &&
        $('input#req-long').val() !== "" &&
        !isNaN(Number($('input#req-long').val()))
    ){
        updatePos({
            latLng: new google.maps.LatLng(Number($('input#req-lat').val()), Number($('input#req-long').val()))
        });
    }
};<|endoftext|>


<commit_before>// Eclass-Assignment-Filter

 (function () {
   var btn = document.createElement("BUTTON");
   var t = document.createTextNode("미제출 보기");
   btn.appendChild(t);
   btn.onclick = function(){
	   var term = "미제출";
	   var tables = document.getElementsByClassName('list-table');
	   var table = tables[0];
	   var tr = table.getElementsByTagName('TR');
	   for (var i = tr.length - 1; i >= 1; i--) {
	       var td = tr[i].getElementsByTagName('TD');
		   if (td[4].innerText == term) {
		       //alert(td[2].innerText);
		       //tr[i].style.backgroundColor = "yellow";
		       //td[4].innerHTML = "찾았다.";
		   }
	       else
		   {
		       table.removeChild(tr[i]);
		       //for (var j = 1; j < td.length; j++) {
		       //    td[j].style.color = "white";
		       //}
		   }
		   //else
		   //{
		   //    alert(i + "번째 는 완료된 항목" + td[2]);
		   //}
	   }
	   };
   document.body.appendChild(btn);
 })();

//(function () {
//  var term = "미제출";
//  var tables = document.getElementsByClassName('list-table');
//  var table = tables[0];
//  var tr = table.getElementsByTagName('TR');
//  for(var i = 0; i < tr.length; i++){
//	  var td = tr[i].getElementsByTagName('TD');
//	  for(var j = 0; j < td.length; j++){
//		  if(td[j].innerHTML == term){
//			  td[j].innerHTML = "찾았다.";
//		  }
//	  }
//  }
//})();<commit_msg>fixed<commit_after>// Eclass-Assignment-Filter

 (function () {
   var btn = document.createElement("BUTTON");
   var t = document.createTextNode("미제출 보기");
   btn.appendChild(t);
   btn.onclick = function(){
	   var term = "미제출";
	   var tables = document.getElementsByClassName('list-table');
	   var table = tables[0];
	   var tr = table.getElementsByTagName('TR');
	   for (var i = tr.length - 1; i >= 1; i--) {
	       var td = tr[i].getElementsByTagName('TD');
		   if (td[4].innerText == term) {
		       //alert(td[2].innerText);
		       //tr[i].style.backgroundColor = "yellow";
		       //td[4].innerHTML = "찾았다.";
		   }
	       else
		   {
               table.parentNode.removeChild(tr[i]);
		       //for (var j = 1; j < td.length; j++) {
		       //    td[j].style.color = "white";
		       //}
		   }
		   //else
		   //{
		   //    alert(i + "번째 는 완료된 항목" + td[2]);
		   //}
	   }
	   };
   document.body.appendChild(btn);
 })();

//(function () {
//  var term = "미제출";
//  var tables = document.getElementsByClassName('list-table');
//  var table = tables[0];
//  var tr = table.getElementsByTagName('TR');
//  for(var i = 0; i < tr.length; i++){
//	  var td = tr[i].getElementsByTagName('TD');
//	  for(var j = 0; j < td.length; j++){
//		  if(td[j].innerHTML == term){
//			  td[j].innerHTML = "찾았다.";
//		  }
//	  }
//  }
//})();<|endoftext|>


<commit_before>/* @flow */

var resolveStyles = require('./resolve-styles.js');
var printStyles = require('./print-styles.js');

var copyProperties = function (source, target) {
  Object.getOwnPropertyNames(source).forEach(key => {
    const ignoreKeys = ['type', 'arguments', 'callee', 'caller', 'length', 'name', 'prototype'];
    if (ignoreKeys.indexOf(key) < 0 && !target.hasOwnProperty(key)) {
      var descriptor = Object.getOwnPropertyDescriptor(source, key);
      Object.defineProperty(target, key, descriptor);
    }
  });
};

var enhanceWithRadium = function (ComposedComponent: constructor): constructor {
  class RadiumEnhancer extends ComposedComponent {
    _radiumMediaQueryListenersByQuery: {[query: string]: {remove: () => void}};
    _radiumMouseUpListener: {remove: () => void};

    constructor () {
      super(...arguments);

      this.state = this.state || {};
      this.state._radiumStyleState = {};

      if (RadiumEnhancer.printStyleClass) {
        this.printStyleClass = RadiumEnhancer.printStyleClass;
      }
    }

    render () {
      var renderedElement = super.render();
      return resolveStyles(this, renderedElement);
    }

    componentWillUnmount () {
      if (super.componentWillUnmount) {
        super.componentWillUnmount();
      }

      if (this._radiumMouseUpListener) {
        this._radiumMouseUpListener.remove();
      }

      if (this._radiumMediaQueryListenersByQuery) {
        Object.keys(this._radiumMediaQueryListenersByQuery).forEach(
          function (query) {
            this._radiumMediaQueryListenersByQuery[query].remove();
          },
          this
        );
      }
    }
  }

  // Class inheritance uses Object.create and because of __proto__ issues
  // with IE <10 any static properties of the superclass aren't inherited and
  // so need to be manually populated.
  // See http://babeljs.io/docs/advanced/caveats/#classes-10-and-below-
  copyProperties(ComposedComponent, RadiumEnhancer);

  // This also fixes React Hot Loader by exposing the original components top level
  // prototype methods on the Radium enhanced prototype as discussed in #219.
  copyProperties(ComposedComponent.prototype, RadiumEnhancer.prototype);

  RadiumEnhancer.displayName =
    ComposedComponent.displayName ||
    ComposedComponent.name ||
    'Component';

  RadiumEnhancer.printStyleClass = printStyles.addPrintStyles(RadiumEnhancer);

  return RadiumEnhancer;
};

module.exports = enhanceWithRadium;
<commit_msg>using var instead of const to remove flow errors<commit_after>/* @flow */

var resolveStyles = require('./resolve-styles.js');
var printStyles = require('./print-styles.js');

var copyProperties = function (source, target) {
  Object.getOwnPropertyNames(source).forEach(key => {
    var ignoreKeys = ['type', 'arguments', 'callee', 'caller', 'length', 'name', 'prototype'];
    if (ignoreKeys.indexOf(key) < 0 && !target.hasOwnProperty(key)) {
      var descriptor = Object.getOwnPropertyDescriptor(source, key);
      Object.defineProperty(target, key, descriptor);
    }
  });
};

var enhanceWithRadium = function (ComposedComponent: constructor): constructor {
  class RadiumEnhancer extends ComposedComponent {
    _radiumMediaQueryListenersByQuery: {[query: string]: {remove: () => void}};
    _radiumMouseUpListener: {remove: () => void};

    constructor () {
      super(...arguments);

      this.state = this.state || {};
      this.state._radiumStyleState = {};

      if (RadiumEnhancer.printStyleClass) {
        this.printStyleClass = RadiumEnhancer.printStyleClass;
      }
    }

    render () {
      var renderedElement = super.render();
      return resolveStyles(this, renderedElement);
    }

    componentWillUnmount () {
      if (super.componentWillUnmount) {
        super.componentWillUnmount();
      }

      if (this._radiumMouseUpListener) {
        this._radiumMouseUpListener.remove();
      }

      if (this._radiumMediaQueryListenersByQuery) {
        Object.keys(this._radiumMediaQueryListenersByQuery).forEach(
          function (query) {
            this._radiumMediaQueryListenersByQuery[query].remove();
          },
          this
        );
      }
    }
  }

  // Class inheritance uses Object.create and because of __proto__ issues
  // with IE <10 any static properties of the superclass aren't inherited and
  // so need to be manually populated.
  // See http://babeljs.io/docs/advanced/caveats/#classes-10-and-below-
  copyProperties(ComposedComponent, RadiumEnhancer);

  // This also fixes React Hot Loader by exposing the original components top level
  // prototype methods on the Radium enhanced prototype as discussed in #219.
  copyProperties(ComposedComponent.prototype, RadiumEnhancer.prototype);

  RadiumEnhancer.displayName =
    ComposedComponent.displayName ||
    ComposedComponent.name ||
    'Component';

  RadiumEnhancer.printStyleClass = printStyles.addPrintStyles(RadiumEnhancer);

  return RadiumEnhancer;
};

module.exports = enhanceWithRadium;
<|endoftext|>


<commit_before>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redexutil/LICENSE

// a more explicit promisification for redis client

// also see more automated attempt using es6-promisify:
// https://github.com/evanx/redex/blob/master/lib/redisPromisified.js

import redis from 'redis';

import Files from './Files';
import Loggers from './Loggers';

const logger = Loggers.create(module.filename, 'info');

const state = {
   count: 0,
   clients: new Set()
};

function createClient(options) {
   state.count++;
   let redisClient = redis.createClient(options || {});
   state.clients.add(redisClient);
   redisClient.on('error', err => {
      logger.error('redis error:', err);
   });
   return redisClient;
}

function createCallback(resolve, reject) {
   return (err, reply) => {
      if (err) {
         logger.debug('redis reject error:', err);
         reject(err);
      } else {
         logger.debug('redis resolve:', reply);
         resolve(reply);
      }
   };
}

function createPromise(fn) {
   return new Promise((resolve, reject) => fn(createCallback(resolve, reject)));
}

export default class Redis {

   // @param client
   // client maybe null e.g. if constructed with empty options object i.e. {}
   // if no options, then client is created

   constructor(options) {
      if (options) {
         if (lodash.isString(options)) {
            this.source = Files.basename(options);
            this.client = createClient();
            logger.info('construct', state.count, this.source);
         } else if (options === {}) {
            logger.info('construct defer');
         } else if (options.client) {
            this.client = options.client;
            logger.info('construct wrapper');
         } else if (options.source) {
            this.source = Files.basename(options.source);
            this.client = createClient(options);
            logger.info('construct', state.count, this.source);
         } else if (options.return_buffers || options.dbNumber) {
            this.client = createClient(options);
         } else {
            throw 'Invalid options: ' + options.toString();
         }
      } else {
         this.client = createClient();
         logger.info('construct', state.count);
      }
      if (this.client) {
         this.init(options);
      }
   }

   init(options) {
      if (!this.client) {
         this.client = createClient(options);
      }
      if (Redis.dbNumber) { // use alternative database for all connections
         this.select(Redis.dbNumber);
      } else if (options && options.dbNumber) {
         this.select(options.dbNumber);
      }
   }

   select(dbNumber) {
      return createPromise(cb => this.client.select(dbNumber, cb));
   }

   end() {
      if (this.client) {
         if (state.clients.size > 0) {
            state.clients.delete(this.client);
            logger.info('end', state.clients.size, this.source);
         } else {
            logger.error('end');
         }
         this.client.end();
         this.client = null;
      }
   }

   time() {
      return createPromise(cb => this.client.time(cb));
   }

   timeSeconds() {
      return this.time().then(time => {
         return parseInt(time[0]);
      });
   }

   del(key) {
      return createPromise(cb => this.client.del(key, cb));
   }

   get(key) {
      return createPromise(cb => this.client.get(key, cb));
   }

   exists(key) {
      return createPromise(cb => this.client.exists(key, cb));
   }

   expire(key, seconds) {
      return createPromise(cb => this.client.expire(key, seconds, cb));
   }

   mget(keys) {
      return createPromise(cb => this.client.mget(keys, cb));
   }

   set(key, value) {
      return createPromise(cb => this.client.set(key, value, cb));
   }

   sadd(key, member) {
      //logger.debug('sadd', key, member);
      return createPromise(cb => this.client.sadd(key, member, cb));
   }

   sismember(key, member) {
      return createPromise(cb => this.client.sismember(key, member, cb));
   }

   smembers(key, member) {
      return createPromise(cb => this.client.smembers(key, cb));
   }

   srem(key, member) {
      return createPromise(cb => this.client.srem(key, member, cb));
   }

   scard(key) {
      return createPromise(cb => this.client.scard(key, cb));
   }

   hdel(key, field) {
      return createPromise(cb => this.client.hdel(key, field, cb));
   }

   hget(key, field) {
      return createPromise(cb => this.client.hget(key, field, cb));
   }

   hgetall(key) {
      return createPromise(cb => this.client.hgetall(key, cb));
   }

   hmset(key, value) {
      return createPromise(cb => this.client.hmset(key, value, cb));
   }

   hset(key, field, value) {
      return createPromise(cb => this.client.hset(key, field, value, cb));
   }

   lindex(key, index) {
      return createPromise(cb => this.client.lindex(key, index, cb));
   }

   linsert(key, position, pivot, value) {
      return createPromise(cb => this.client.linsert(key, position, pivot, value, cb));
   }

   lrem(key, count, value) {
      return createPromise(cb => this.client.lrem(key, count, value, cb));
   }

   lset(key, index, value) {
      return createPromise(cb => this.client.lset(key, index, value, cb));
   }

   llen(key) {
      return createPromise(cb => this.client.llen(key, cb));
   }

   ltrim(key, start, stop) {
      return createPromise(cb => this.client.ltrim(key, start, stop, cb));
   }

   lrange(key, start, stop) {
      return createPromise(cb => this.client.lrange(key, start, stop, cb));
   }

   lpush(key, value) {
      return createPromise(cb => this.client.lpush(key, value, cb));
   }

   rpush(key, value) {
      return createPromise(cb => this.client.rpush(key, value, cb));
   }

   lpop(key) {
      return createPromise(cb => this.client.lpop(key, cb));
   }

   rpop(key) {
      return createPromise(cb => this.client.rpop(key, cb));
   }

   blpop(key, timeout) {
      return createPromise(cb => this.client.blpop(key, timeout, cb));
   }

   brpop(key, timeout) {
      return createPromise(cb => this.client.brpop(key, timeout, cb));
   }

   rpoplpush(source, destination) {
      return createPromise(cb => this.client.rpoplpush(source, destination, cb));
   }

   brpoplpush(source, destination, timeout) {
      return createPromise(cb => this.client.brpoplpush(source, destination, timeout, cb));
   }

   zrange(key, start, stop) {
      return createPromise(cb => this.client.zrange(key, start, stop, cb));
   }

   zrem(key, member) {
      return createPromise(cb => this.client.zrem(key, member, cb));
   }

   zrevrange(key, start, stop) {
      return createPromise(cb => this.client.zrevrange(key, start, stop, cb));
   }

   // TODO all the rest, see https://github.com/mranney/node_redis/blob/master/lib/commands.js

   multi() {
      let multi = this.client.multi();
      multi.execCallback = multi.exec.bind(multi); // TODO
      multi.exec = function() {
         return createPromise(cb => multi.execCallback(cb));
      };
      return multi;
   }
}

// see test: https://github.com/evanx/redex/blob/master/test/redisPromised.js
<commit_msg>import lodash in Redis<commit_after>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redexutil/LICENSE

// a more explicit promisification for redis client

// also see more automated attempt using es6-promisify:
// https://github.com/evanx/redex/blob/master/lib/redisPromisified.js

import lodash from 'lodash';
import redis from 'redis';

import Files from './Files';
import Loggers from './Loggers';

const logger = Loggers.create(module.filename, 'info');

const state = {
   count: 0,
   clients: new Set()
};

function createClient(options) {
   state.count++;
   let redisClient = redis.createClient(options || {});
   state.clients.add(redisClient);
   redisClient.on('error', err => {
      logger.error('redis error:', err);
   });
   return redisClient;
}

function createCallback(resolve, reject) {
   return (err, reply) => {
      if (err) {
         logger.debug('redis reject error:', err);
         reject(err);
      } else {
         logger.debug('redis resolve:', reply);
         resolve(reply);
      }
   };
}

function createPromise(fn) {
   return new Promise((resolve, reject) => fn(createCallback(resolve, reject)));
}

export default class Redis {

   // @param client
   // client maybe null e.g. if constructed with empty options object i.e. {}
   // if no options, then client is created

   constructor(options) {
      if (options) {
         if (lodash.isString(options)) {
            this.source = Files.basename(options);
            this.client = createClient();
            logger.info('construct', state.count, this.source);
         } else if (options === {}) {
            logger.info('construct defer');
         } else if (options.client) {
            this.client = options.client;
            logger.info('construct wrapper');
         } else if (options.source) {
            this.source = Files.basename(options.source);
            this.client = createClient(options);
            logger.info('construct', state.count, this.source);
         } else if (options.return_buffers || options.dbNumber) {
            this.client = createClient(options);
         } else {
            throw 'Invalid options: ' + options.toString();
         }
      } else {
         this.client = createClient();
         logger.info('construct', state.count);
      }
      if (this.client) {
         this.init(options);
      }
   }

   init(options) {
      if (!this.client) {
         this.client = createClient(options);
      }
      if (Redis.dbNumber) { // use alternative database for all connections
         this.select(Redis.dbNumber);
      } else if (options && options.dbNumber) {
         this.select(options.dbNumber);
      }
   }

   select(dbNumber) {
      return createPromise(cb => this.client.select(dbNumber, cb));
   }

   end() {
      if (this.client) {
         if (state.clients.size > 0) {
            state.clients.delete(this.client);
            logger.info('end', state.clients.size, this.source);
         } else {
            logger.error('end');
         }
         this.client.end();
         this.client = null;
      }
   }

   time() {
      return createPromise(cb => this.client.time(cb));
   }

   timeSeconds() {
      return this.time().then(time => {
         return parseInt(time[0]);
      });
   }

   del(key) {
      return createPromise(cb => this.client.del(key, cb));
   }

   get(key) {
      return createPromise(cb => this.client.get(key, cb));
   }

   exists(key) {
      return createPromise(cb => this.client.exists(key, cb));
   }

   expire(key, seconds) {
      return createPromise(cb => this.client.expire(key, seconds, cb));
   }

   mget(keys) {
      return createPromise(cb => this.client.mget(keys, cb));
   }

   set(key, value) {
      return createPromise(cb => this.client.set(key, value, cb));
   }

   sadd(key, member) {
      //logger.debug('sadd', key, member);
      return createPromise(cb => this.client.sadd(key, member, cb));
   }

   sismember(key, member) {
      return createPromise(cb => this.client.sismember(key, member, cb));
   }

   smembers(key, member) {
      return createPromise(cb => this.client.smembers(key, cb));
   }

   srem(key, member) {
      return createPromise(cb => this.client.srem(key, member, cb));
   }

   scard(key) {
      return createPromise(cb => this.client.scard(key, cb));
   }

   hdel(key, field) {
      return createPromise(cb => this.client.hdel(key, field, cb));
   }

   hget(key, field) {
      return createPromise(cb => this.client.hget(key, field, cb));
   }

   hgetall(key) {
      return createPromise(cb => this.client.hgetall(key, cb));
   }

   hmset(key, value) {
      return createPromise(cb => this.client.hmset(key, value, cb));
   }

   hset(key, field, value) {
      return createPromise(cb => this.client.hset(key, field, value, cb));
   }

   lindex(key, index) {
      return createPromise(cb => this.client.lindex(key, index, cb));
   }

   linsert(key, position, pivot, value) {
      return createPromise(cb => this.client.linsert(key, position, pivot, value, cb));
   }

   lrem(key, count, value) {
      return createPromise(cb => this.client.lrem(key, count, value, cb));
   }

   lset(key, index, value) {
      return createPromise(cb => this.client.lset(key, index, value, cb));
   }

   llen(key) {
      return createPromise(cb => this.client.llen(key, cb));
   }

   ltrim(key, start, stop) {
      return createPromise(cb => this.client.ltrim(key, start, stop, cb));
   }

   lrange(key, start, stop) {
      return createPromise(cb => this.client.lrange(key, start, stop, cb));
   }

   lpush(key, value) {
      return createPromise(cb => this.client.lpush(key, value, cb));
   }

   rpush(key, value) {
      return createPromise(cb => this.client.rpush(key, value, cb));
   }

   lpop(key) {
      return createPromise(cb => this.client.lpop(key, cb));
   }

   rpop(key) {
      return createPromise(cb => this.client.rpop(key, cb));
   }

   blpop(key, timeout) {
      return createPromise(cb => this.client.blpop(key, timeout, cb));
   }

   brpop(key, timeout) {
      return createPromise(cb => this.client.brpop(key, timeout, cb));
   }

   rpoplpush(source, destination) {
      return createPromise(cb => this.client.rpoplpush(source, destination, cb));
   }

   brpoplpush(source, destination, timeout) {
      return createPromise(cb => this.client.brpoplpush(source, destination, timeout, cb));
   }

   zrange(key, start, stop) {
      return createPromise(cb => this.client.zrange(key, start, stop, cb));
   }

   zrem(key, member) {
      return createPromise(cb => this.client.zrem(key, member, cb));
   }

   zrevrange(key, start, stop) {
      return createPromise(cb => this.client.zrevrange(key, start, stop, cb));
   }

   // TODO all the rest, see https://github.com/mranney/node_redis/blob/master/lib/commands.js

   multi() {
      let multi = this.client.multi();
      multi.execCallback = multi.exec.bind(multi); // TODO
      multi.exec = function() {
         return createPromise(cb => multi.execCallback(cb));
      };
      return multi;
   }
}

// see test: https://github.com/evanx/redex/blob/master/test/redisPromised.js
<|endoftext|>


<commit_before>const metaanalyses = require('./metaanalyses');
const papers = require('./papers');
const users = require('./users');

/* closed beta
 *
 *
 *    ####  #       ####   ####  ###### #####     #####  ###### #####   ##
 *   #    # #      #    # #      #      #    #    #    # #        #    #  #
 *   #      #      #    #  ####  #####  #    #    #####  #####    #   #    #
 *   #      #      #    #      # #      #    #    #    # #        #   ######
 *   #    # #      #    # #    # #      #    #    #    # #        #   #    #
 *    ####  ######  ####   ####  ###### #####     #####  ######   #   #    #
 *
 *
 */

function setupClosedBeta() {
  // a hash keyed on invite codes for closed beta users
  module.exports.betaCodes = { 'app-engine': {} };

  // // load the invitation codes from a file for now
  // // every line has an invite code and after # possibly a comment
  // // to generate an invite, there are instructions in the README
  // // todo load the codes from the data store and have a management interface, update the README
  // (function () {
  //   let invites;
  //   try {
  //     invites = fs.readFileSync('./invites.txt', 'utf8');
  //   } catch (e) {
  //     // let it crash
  //     throw new Error('BETA: need the file ./invites.txt to allow anybody in the server');
  //   }
  //   const lines = invites.split(/\n/);
  //   lines.forEach((line) => {
  //     const code = line.split('#')[0].trim();
  //     if (code) module.exports.betaCodes[code] = {};
  //   });
  //   if (Object.keys(module.exports.betaCodes).length === 0) {
  //     throw new Error('BETA: need invite codes in ./invites.txt to allow anybody in the server');
  //   }
  //   console.log(`BETA: got ${Object.keys(module.exports.betaCodes).length} invites`);
  // }());

  // // when we touch a beta code (someone uses it in a request), store:
  // //   last access (trigger a save if more than 24h after the last one)
  // //   logged-in email address if available (triggers a save if a new address there)
  // //   access count per email address per day for the last 7 days
  module.exports.touchBetaCode = (code, email) => void email;
}

module.exports = {
  metaanalyses,
  papers,
  users,
}<commit_msg>:art: exporting shared file<commit_after>const metaanalyses = require('./metaanalyses');
const papers = require('./papers');
const users = require('./users');
const shared = require('./shared');

/* closed beta
 *
 *
 *    ####  #       ####   ####  ###### #####     #####  ###### #####   ##
 *   #    # #      #    # #      #      #    #    #    # #        #    #  #
 *   #      #      #    #  ####  #####  #    #    #####  #####    #   #    #
 *   #      #      #    #      # #      #    #    #    # #        #   ######
 *   #    # #      #    # #    # #      #    #    #    # #        #   #    #
 *    ####  ######  ####   ####  ###### #####     #####  ######   #   #    #
 *
 *
 */

function setupClosedBeta() {
  // a hash keyed on invite codes for closed beta users
  module.exports.betaCodes = { 'app-engine': {} };

  // // load the invitation codes from a file for now
  // // every line has an invite code and after # possibly a comment
  // // to generate an invite, there are instructions in the README
  // // todo load the codes from the data store and have a management interface, update the README
  // (function () {
  //   let invites;
  //   try {
  //     invites = fs.readFileSync('./invites.txt', 'utf8');
  //   } catch (e) {
  //     // let it crash
  //     throw new Error('BETA: need the file ./invites.txt to allow anybody in the server');
  //   }
  //   const lines = invites.split(/\n/);
  //   lines.forEach((line) => {
  //     const code = line.split('#')[0].trim();
  //     if (code) module.exports.betaCodes[code] = {};
  //   });
  //   if (Object.keys(module.exports.betaCodes).length === 0) {
  //     throw new Error('BETA: need invite codes in ./invites.txt to allow anybody in the server');
  //   }
  //   console.log(`BETA: got ${Object.keys(module.exports.betaCodes).length} invites`);
  // }());

  // // when we touch a beta code (someone uses it in a request), store:
  // //   last access (trigger a save if more than 24h after the last one)
  // //   logged-in email address if available (triggers a save if a new address there)
  // //   access count per email address per day for the last 7 days
  module.exports.touchBetaCode = (code, email) => void email;
}

module.exports = {
  metaanalyses,
  papers,
  users,
  shared,
};
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import List from 'material-ui/List';
import ListItem from 'material-ui/List/ListItem';
import Checkbox from 'material-ui/Checkbox';
import RaisedButton from 'material-ui/RaisedButton';
import {deepOrange500} from 'material-ui/styles/colors';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import { browserHistory } from 'react-router';

const styles = {
  container: {
  },
};

const muiTheme = getMuiTheme({
  palette: {
    accent1Color: deepOrange500,
  },
});

class InviteUsers extends Component {
  constructor(props, context) {
      super(props, context);

    this.hasSelectedUsers = this.hasSelectedUsers.bind(this);
    this.handleInviteUsers = this.handleInviteUsers.bind(this);
    this.handleSelectedUserChange = this.handleSelectedUserChange.bind(this);
    this.getAvailableUsers = this.getAvailableUsers.bind(this);

    this.state = {
      selectedUsers: [],
        availableUsers: [
            {name: 'John', id: 1},
            {name: 'Lola', id: 2},
            {name: 'Matt', id: 3}
        ]
    };
  }

    componentDidMount() {
        //TODO: get the users here
        fetch('http://dev03.contentsexpress.lan/Claimsws/api/Lookup/LookupTypes/V1').then(function(response) {
            return response.json();
        }).then(function(j) {
            console.log(j);
        });
    }

    getAvailableUsers = () => {
        return this.state.availableUsers;
    }
    hasSelectedUsers = () => {
        return this.state.selectedUsers.length > 0;
    }

    handleInviteUsers = () => {
        let selectedUsers = this.state.selectedUsers;
        // validate the date
        if (selectedUsers.length === 0) {
          alert('No selected users');
        }
        this.props.router.push('/swapcreated');
    }

    handleSelectedUserChange = (e, checked) => {
        let userId = e.target.id,
            selectedUsers = this.state.selectedUsers.slice();

        if (checked) {
            selectedUsers.push(userId);
        } else {
            let idx = selectedUsers.indexOf(userId);
            selectedUsers.splice(idx, 1);
        }

        this.setState({
            selectedUsers: selectedUsers
        });
    }

  render() {

    return (
      <MuiThemeProvider muiTheme={muiTheme}>

Invite Users to Beer Swap

            <InviteList users={this.getAvailableUsers()} handleSelectedUserChange={this.handleSelectedUserChange} />
            <InviteUsersButton handleInviteUsers={this.handleInviteUsers} hasSelectedUsers={this.hasSelectedUsers}/>

      </MuiThemeProvider>
    );
  }
}

class InviteList extends React.Component {
    constructor(props, context) {
        super(props, context);
        this.users = props.users;
    }

    render() {
        const users = this.users.map((user) => {
            return (
                <ListItem key={user.id}
                    leftCheckbox={<Checkbox id={user.id} onCheck={this.props.handleSelectedUserChange} />}
                    primaryText={user.name}
                />
            );
        });

        return (
            <List>
                {users}
            </List>
        );
    }
}

class InviteUsersButton extends React.Component {
    render() {
        return (
            <RaisedButton label="Invite Selected Users"
                          secondary={true}
                          onTouchTap={this.props.handleInviteUsers}
                          disabled={!this.props.hasSelectedUsers()}/>
        );
    }
}

export default InviteUsers;
<commit_msg>Getting real users<commit_after>import React, {Component} from 'react';
import List from 'material-ui/List';
import ListItem from 'material-ui/List/ListItem';
import Checkbox from 'material-ui/Checkbox';
import RaisedButton from 'material-ui/RaisedButton';
import {deepOrange500} from 'material-ui/styles/colors';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';

const styles = {
  container: {
  },
};

const muiTheme = getMuiTheme({
  palette: {
    accent1Color: deepOrange500,
  },
});

class InviteUsers extends Component {
  constructor(props, context) {
      super(props, context);

    this.hasSelectedUsers = this.hasSelectedUsers.bind(this);
    this.handleInviteUsers = this.handleInviteUsers.bind(this);
    this.handleSelectedUserChange = this.handleSelectedUserChange.bind(this);
    this.getAvailableUsers = this.getAvailableUsers.bind(this);

    this.state = {
      selectedUsers: [],
        availableUsers: []
    };
  }

    componentDidMount() {
        let me = this;
        fetch('http://beerswap.enservio.lan/BeerWS/api/User/V1').then(function(response) {
            return response.json();
        }).then(setUsers);

        function setUsers(users) {
            me.setState({
                availableUsers: users
            });
        }
    }

    getAvailableUsers = () => {
        return this.state.availableUsers;
    }
    hasSelectedUsers = () => {
        return this.state.selectedUsers.length > 0;
    }

    handleInviteUsers = () => {
        let selectedUsers = this.state.selectedUsers;
        // validate the date
        if (selectedUsers.length === 0) {
          alert('No selected users');
        }
        this.props.router.push('/swapcreated');
    }

    handleSelectedUserChange = (e, checked) => {
        let userId = e.target.id,
            selectedUsers = this.state.selectedUsers.slice();

        if (checked) {
            selectedUsers.push(userId);
        } else {
            let idx = selectedUsers.indexOf(userId);
            selectedUsers.splice(idx, 1);
        }

        this.setState({
            selectedUsers: selectedUsers
        });
    }

  render() {

    return (
      <MuiThemeProvider muiTheme={muiTheme}>

Invite Users to Beer Swap

            <InviteList users={this.getAvailableUsers()} handleSelectedUserChange={this.handleSelectedUserChange} />
            <InviteUsersButton handleInviteUsers={this.handleInviteUsers} hasSelectedUsers={this.hasSelectedUsers}/>

      </MuiThemeProvider>
    );
  }
}

class InviteList extends React.Component {
    constructor(props, context) {
        super(props, context);
        this.props = props;
    }

    render() {
        const users = this.props.users.map((user) => {
            return (
                <ListItem key={user.UserId}
                    leftCheckbox={<Checkbox id={user.UserId} onCheck={this.props.handleSelectedUserChange} />}
                    primaryText={user.FirstName + ' ' + user.LastName}
                />
            );
        });

        return (
            <List>
                {users}
            </List>
        );
    }
}

class InviteUsersButton extends React.Component {
    render() {
        return (
            <RaisedButton label="Invite Selected Users"
                          secondary={true}
                          onTouchTap={this.props.handleInviteUsers}
                          disabled={!this.props.hasSelectedUsers()}/>
        );
    }
}

export default InviteUsers;
<|endoftext|>


<commit_before>/**
 * Created by michael on 07/09/15.
 */

var Promise = require('bluebird');

function FightController(app,player1,player2){
    this.app = app;
    this.player1 = player1;
    this.player2 = player2;

    this.readyCount = 0;

    this.activePlayer = {
        connection: player1,
        life: 50,
        defending: false
    };

    this.pausedPlayer = {
        connection: player2,
        life: 50,
        defending: false
    };
}

FightController.prototype.start = function(){
    return Promise.all([
        this.initPlayer(this.player1,this.player2),
        this.initPlayer(this.player2,this.player1)
    ]);
};

FightController.prototype.stop = function(){
    return Promise.all([
        this.deInitPlayer(this.player1),
        this.deInitPlayer(this.player2)
    ]);
};

FightController.prototype.deInitPlayer = function(player){
    return player.stopFight();
};

FightController.prototype.initPlayer = function(player,enemy) {
    var self = this;
    player.fight = this;

    return enemy.user.robot().fetch({require: true}).then(function(robot){

        return player.socket.emit('requestFightResult',{
            status: 'ACCEPT',
            username: enemy.user.get('username'),
            robot: robot.toJSON({shallow: true})
        });
    });
};

FightController.prototype.onPlayerReady = function(){
    this.readyCount++;

    if(this.readyCount >= 2){
        this.activePlayer.connection.socket.emit('fightCommand',{
            command: 'active'
        })
    }
};

FightController.prototype.parseCommand = function(data){
    var player = data.who;

    switch(data.command){
        case 'ready':
            this.onPlayerReady();
            return;
            break;
        case 'abort':
            this.app.stopFight(player);
            return;
    }

    if(!this.activePlayer.connection == player || this.readyCount < 2){
        return;
    }

    switch(data.command){
        case 'attack':
            this.attack();
            break;
        case 'defend':
            this.defend();
            break;
    }

};

FightController.prototype.endRound = function(){
    var pause = this.activePlayer;
    this.activePlayer = this.pausedPlayer;
    this.pausedPlayer = pause;

    this.pausedPlayer.connection.socket.emit('fightCommand',{
        command: 'wait'
    });
};

FightController.prototype.attack = function(){
    var self = this;

    return Promise.all([
        this.activePlayer.connection.user.robot().fetch({require: true, withRelated: ['head','body','arms','legs']}),
        this.pausedPlayer.connection.user.robot().fetch({require: true, withRelated: ['head','body','arms','legs']})
    ]).then(function(robots){
        var attackRobot = robots[0].getValues();
        var defenseRobot = robots[1].getValues();

        if(self.pausedPlayer.defending){
            self.pausedPlayer.defending = false;
            defenseRobot.defense *= 2;
        }

        var damage = attackRobot.attack - ((attackRobot.attack/100) * defenseRobot.defense);

        if(damage < 0){
            damage = 0;
        }

        if(attackRobot.agility > defenseRobot.agility){
            if(Math.floor(Math.random() * 2) == 0) {
                damage *= 2;
            }
        }else if(attackRobot.agility < defenseRobot.agility){
            if(Math.floor(Math.random() * 2) == 0){
                damage = 0;
            }
        }

        damage = Math.floor(damage);
        self.pausedPlayer.life -= damage;
        if(self.pausedPlayer.life <= 0){
            self.pausedPlayer.life = 0;
        }

        self.pausedPlayer.connection.socket.emit('fightCommand',{
            command: 'enemyAttack',
            param: {
                life: self.pausedPlayer.life
            }
        });

        self.activePlayer.connection.socket.emit('fightCommand',{
            command: 'updateEnemy',
            param: {
                life: self.pausedPlayer.life
            }
        });

        self.endRound();

        if(self.pausedPlayer.life == 0){
            self.app.stopFight(self.pausedPlayer.connection);
        }

    });

};

FightController.prototype.defend = function(){
    this.activePlayer.defending = true;
    this.endRound();
};

module.exports = FightController;<commit_msg>fehlende aktivierung des anderen spielers<commit_after>/**
 * Created by michael on 07/09/15.
 */

var Promise = require('bluebird');

function FightController(app,player1,player2){
    this.app = app;
    this.player1 = player1;
    this.player2 = player2;

    this.readyCount = 0;

    this.activePlayer = {
        connection: player1,
        life: 50,
        defending: false
    };

    this.pausedPlayer = {
        connection: player2,
        life: 50,
        defending: false
    };
}

FightController.prototype.start = function(){
    return Promise.all([
        this.initPlayer(this.player1,this.player2),
        this.initPlayer(this.player2,this.player1)
    ]);
};

FightController.prototype.stop = function(){
    return Promise.all([
        this.deInitPlayer(this.player1),
        this.deInitPlayer(this.player2)
    ]);
};

FightController.prototype.deInitPlayer = function(player){
    return player.stopFight();
};

FightController.prototype.initPlayer = function(player,enemy) {
    var self = this;
    player.fight = this;

    return enemy.user.robot().fetch({require: true}).then(function(robot){

        return player.socket.emit('requestFightResult',{
            status: 'ACCEPT',
            username: enemy.user.get('username'),
            robot: robot.toJSON({shallow: true})
        });
    });
};

FightController.prototype.onPlayerReady = function(){
    this.readyCount++;

    if(this.readyCount >= 2){
        this.activePlayer.connection.socket.emit('fightCommand',{
            command: 'active'
        })
    }
};

FightController.prototype.parseCommand = function(data){
    var player = data.who;

    switch(data.command){
        case 'ready':
            this.onPlayerReady();
            return;
            break;
        case 'abort':
            this.app.stopFight(player);
            return;
    }

    if(!this.activePlayer.connection == player || this.readyCount < 2){
        return;
    }

    switch(data.command){
        case 'attack':
            this.attack();
            break;
        case 'defend':
            this.defend();
            break;
    }

};

FightController.prototype.endRound = function(){
    var pause = this.activePlayer;
    this.activePlayer = this.pausedPlayer;
    this.pausedPlayer = pause;

    this.pausedPlayer.connection.socket.emit('fightCommand',{
        command: 'wait'
    });
};

FightController.prototype.attack = function(){
    var self = this;

    return Promise.all([
        this.activePlayer.connection.user.robot().fetch({require: true, withRelated: ['head','body','arms','legs']}),
        this.pausedPlayer.connection.user.robot().fetch({require: true, withRelated: ['head','body','arms','legs']})
    ]).then(function(robots){
        var attackRobot = robots[0].getValues();
        var defenseRobot = robots[1].getValues();

        if(self.pausedPlayer.defending){
            self.pausedPlayer.defending = false;
            defenseRobot.defense *= 2;
        }

        var damage = attackRobot.attack - ((attackRobot.attack/100) * defenseRobot.defense);

        if(damage < 0){
            damage = 0;
        }

        if(attackRobot.agility > defenseRobot.agility){
            if(Math.floor(Math.random() * 2) == 0) {
                damage *= 2;
            }
        }else if(attackRobot.agility < defenseRobot.agility){
            if(Math.floor(Math.random() * 2) == 0){
                damage = 0;
            }
        }

        damage = Math.floor(damage);
        self.pausedPlayer.life -= damage;
        if(self.pausedPlayer.life <= 0){
            self.pausedPlayer.life = 0;
        }

        self.pausedPlayer.connection.socket.emit('fightCommand',{
            command: 'enemyAttack',
            param: {
                life: self.pausedPlayer.life
            }
        });

        self.activePlayer.connection.socket.emit('fightCommand',{
            command: 'updateEnemy',
            param: {
                life: self.pausedPlayer.life
            }
        });

        self.endRound();

        if(self.pausedPlayer.life == 0){
            self.app.stopFight(self.pausedPlayer.connection);
        }

    });

};

FightController.prototype.defend = function(){
    this.activePlayer.defending = true;
    this.endRound();
    this.activePlayer.connection.socket.emit('fightCommand',{
        command: 'active'
    })
};

module.exports = FightController;<|endoftext|>


<commit_before>define(['jquery', 'underscore', 'backbone',
	'text!./app/views/templates/search-form.html',
	'text!./app/views/templates/search-empty.html',
	'text!./app/views/templates/search-listing.html',
	'models'], function($, _, Backbone, searchFormTemplate, emptySearchTemplate, searchListingTemplate, Models) {
	var Views = {};

	Views.SearchView = Backbone.View.extend({
		template: _.template(searchListingTemplate),

		events: {
			"click button#btn-pledge": "pledgeClick"
		},

		pledgeClick: function() {

		},

		initialize: function() {
			this.listenTo(this.model, "change", this.render);
			this.id = "search-" + this.model.attributes.id;
		},

		render: function() {
			this.$el.html(this.template(this.model.attributes));
			return this;
		}
	});

	Views.SearchListing = Backbone.View.extend({
		initialize: function() {
			this.listenTo(this.collection, 'add', this.collectionAdded);
			this.listenTo(this.collection, 'change', this.collectionChanged);
			this.listenTo(this.collection, 'remove', this.collectionRemoved);

			this.childViews = [];

			this._addAllModels();
		},

		render: function() {
			var fragment = document.createDocumentFragment();

			if (this.childViews.length > 0) {
				_(this.childViews).each(function(currentView) {
					fragment.appendChild(currentView.render().el);
				});
			} else {
				$(emptySearchTemplate).appendTo(fragment);
			}

			this.$('.item-listing').html(fragment);
			return this;
		},

		collectionAdded: function(item) {
			this._addViewForModel(item);
			this.render();
		},

		collectionRemoved: function(item) {
			this.childViews = this.childViews.filter(function(view) {
				return view.model.id !== item.id;
			});
			this.render();
		},

		collectionChanged: function() {
			this.childViews = [];
			this._addAllModels();
		},

		_addViewForModel: function(item) {
			this.childViews.push(new Views.SearchView({
				model: item
			}));
		},

		_addAllModels: function() {
			this.collection.each(function(item) {
				_addViewForModel(item);
			});
			this.render();
		}
	});

	Views.SearchForm = Backbone.View.extend({
		template: _.template(searchFormTemplate),

		events: {
			"click a#btn-search": "searchClick"
		},

		searchClick: function() {
			var search = $('#txt-search').val();
			this.searchCollection.url = '/service/products/search/' + escape(search);
			this.searchCollection.fetch({
			    success: function(results) {
        			$('#lbl-search').text(search);
        			$('#search-results').show();
			    }
			});
			this.searchListingView.render();
		},

		initialize: function() {
			this.render();
			this.searchCollection = new Models.SearchResults();
			this.searchListingView = new Views.SearchListing({
				collection: this.searchCollection,
				el: '#search-results',
				id: 'search-results'
			});
		},

		render: function() {
			this.$el.html(this.template());
			return this;
		}
	});

	return Views;
});<commit_msg>search on enter key<commit_after>define(['jquery', 'underscore', 'backbone',
	'text!./app/views/templates/search-form.html',
	'text!./app/views/templates/search-empty.html',
	'text!./app/views/templates/search-listing.html',
	'models'], function($, _, Backbone, searchFormTemplate, emptySearchTemplate, searchListingTemplate, Models) {
	var Views = {};

	Views.SearchView = Backbone.View.extend({
		template: _.template(searchListingTemplate),

		events: {
			"click button#btn-pledge": "pledgeClick"
		},

		pledgeClick: function() {

		},

		initialize: function() {
			this.listenTo(this.model, "change", this.render);
			this.id = "search-" + this.model.attributes.id;
		},

		render: function() {
			this.$el.html(this.template(this.model.attributes));
			return this;
		}
	});

	Views.SearchListing = Backbone.View.extend({
		initialize: function() {
			this.listenTo(this.collection, 'add', this.collectionAdded);
			this.listenTo(this.collection, 'change', this.collectionChanged);
			this.listenTo(this.collection, 'remove', this.collectionRemoved);

			this.childViews = [];

			this._addAllModels();
		},

		render: function() {
			var fragment = document.createDocumentFragment();

			if (this.childViews.length > 0) {
				_(this.childViews).each(function(currentView) {
					fragment.appendChild(currentView.render().el);
				});
			} else {
				$(emptySearchTemplate).appendTo(fragment);
			}

			this.$('.item-listing').html(fragment);
			return this;
		},

		collectionAdded: function(item) {
			this._addViewForModel(item);
			this.render();
		},

		collectionRemoved: function(item) {
			this.childViews = this.childViews.filter(function(view) {
				return view.model.id !== item.id;
			});
			this.render();
		},

		collectionChanged: function() {
			this.childViews = [];
			this._addAllModels();
		},

		_addViewForModel: function(item) {
			this.childViews.push(new Views.SearchView({
				model: item
			}));
		},

		_addAllModels: function() {
			this.collection.each(function(item) {
				_addViewForModel(item);
			});
			this.render();
		}
	});

	Views.SearchForm = Backbone.View.extend({
		template: _.template(searchFormTemplate),

		events: {
			"click a#btn-search": "searchClick",
            "keypress input[type=text]": "keypress"
		},

        keypress: function(e) {
            switch (e.keyCode) {
                case 13:
                searchClick();
            }
        }

		searchClick: function() {
			var search = $('#txt-search').val();
			this.searchCollection.url = '/service/products/search/' + escape(search);
			this.searchCollection.fetch({
			    success: function(results) {
        			$('#lbl-search').text(search);
        			$('#search-results').show();
			    }
			});
			this.searchListingView.render();
		},

		initialize: function() {
			this.render();
			this.searchCollection = new Models.SearchResults();
			this.searchListingView = new Views.SearchListing({
				collection: this.searchCollection,
				el: '#search-results',
				id: 'search-results'
			});
		},

		render: function() {
			this.$el.html(this.template());
			return this;
		}
	});

	return Views;
});<|endoftext|>


<commit_before>/*
 * Copyright 2018 Google Inc. All Rights Reserved.
 * 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 {
  BackSide,
  BoxBufferGeometry,
  CubeCamera,
  EventDispatcher,
  FloatType,
  Group,
  LinearToneMapping,
  LinearMipMapLinearFilter,
  Mesh,
  MeshBasicMaterial,
  MeshStandardMaterial,
  PointLight,
  Scene
} from 'three';

export default class EnvironmentMapGenerator extends EventDispatcher {
  constructor(renderer) {
    super();
    this.renderer = renderer;
    this.scene = new Scene();

    // Scene

    const geometry = new BoxBufferGeometry();

    const material1 = new MeshStandardMaterial({roughness: 1, metalness: 0, side: BackSide});
    const material2 = new MeshStandardMaterial({roughness: 1, metalness: 0});
    const material3 = new MeshBasicMaterial();
    material3.color.setRGB(10,10,10);

    //

    const light = new PointLight(0xffffff,50,30);
    light.position.set(-0.010, 15.934, 0.284);
    this.scene.add(light);

    const room = new Mesh(geometry,material1);
    room.position.set(-0.757, 13.219, 0.717);
    room.scale.set(31.713, 28.305, 28.591);
    this.scene.add(room);

    const box1 = new Mesh(geometry,material2);
    box1.position.set(-10.906, 2.009, 1.846);
    box1.rotation.set(0,-0.195,0);
    box1.scale.set(2.328, 7.905, 4.651);
    this.scene.add(box1);

    const box2 = new Mesh(geometry,material2);
    box2.position.set(-5.607, -0.754, -0.758);
    box2.rotation.set(0,0.994,0);
    box2.scale.set(1.970, 1.534, 3.955);
    this.scene.add(box2);

    const box3 = new Mesh(geometry,material2);
    box3.position.set(6.167, 0.857, 7.803);
    box3.rotation.set(0,0.561,0);
    box3.scale.set(3.927, 6.285, 3.687);
    this.scene.add(box3);

    const box4 = new Mesh(geometry,material2);
    box4.position.set(-2.017, 0.018, 6.124);
    box4.rotation.set(0,0.333,0);
    box4.scale.set(2.002, 4.566, 2.064);
    this.scene.add(box4);

    const box5 = new Mesh(geometry,material2);
    box5.position.set(2.291, -0.756, -2.621);
    box5.rotation.set(0,-0.286,0);
    box5.scale.set(1.546, 1.552, 1.496);
    this.scene.add(box5);

    const box6 = new Mesh(geometry,material2);
    box6.position.set(-2.193, -0.369, -5.547);
    box6.rotation.set(0,0.516,0);
    box6.scale.set(3.875, 3.487, 2.986);
    this.scene.add(box6);

    const light1 = new Mesh(geometry,material3);
    light1.position.set(-16.116, 12.757, 7.208);
    light1.scale.set(0.1, 2.428, 3.739);
    this.scene.add(light1);

    const light2 = new Mesh(geometry,material3);
    light2.position.set(-16.109, 16.021, -7.207);
    light2.scale.set(0.1, 2.425, 3.751);
    this.scene.add(light2);

    const light3 = new Mesh(geometry,material3);
    light3.position.set(13.904, 10.198, -1.832);
    light3.scale.set(0.15, 4.265, 6.331);
    this.scene.add(light3);

    const light4 = new Mesh(geometry,material3);
    light4.position.set(-0.462, 8.409, 14.520);
    light4.scale.set(5.78, 6.341, 0.088);
    this.scene.add(light4);

    const light5 = new Mesh(geometry,material3);
    light5.position.set(4.235, 13.486, -12.541);
    light5.scale.set(4.52, 2.885, 0.1);
    this.scene.add(light5);

    this.camera = new CubeCamera(0.1, 100, 256);
    this.camera.renderTarget.texture.type = FloatType;
    this.camera.renderTarget.texture.minFilter = LinearMipMapLinearFilter;
    this.camera.renderTarget.texture.generateMipmaps = true;

  }

  /**
   * Generate an environment map for a room.
   *
   * @param {number} mapSize
   */
  generate() {
    this.camera.clear(this.renderer);

    var gammaOutput = this.renderer.gammaOutput;
    var toneMapping = this.renderer.toneMapping;
    var toneMappingExposure = this.renderer.toneMappingExposure;

    this.renderer.toneMapping = LinearToneMapping;
    this.renderer.toneMappingExposure = 1.0;
    this.renderer.gammaOutput = false;

    this.camera.update(this.renderer, this.scene);

    this.renderer.toneMapping = toneMapping;
    this.renderer.toneMappingExposure = toneMappingExposure;
    this.renderer.gammaOutput = gammaOutput;

    return this.camera.renderTarget.texture;
  }

  dispose() {
    this.camera.renderTarget.dispose();
  }
}
<commit_msg>Refine lightroom generation<commit_after>/*
 * Copyright 2018 Google Inc. All Rights Reserved.
 * 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 {BackSide, BoxBufferGeometry, CubeCamera, EventDispatcher, FloatType, Group, LinearMipMapLinearFilter, LinearToneMapping, Matrix4, Mesh, MeshBasicMaterial, MeshStandardMaterial, Object3D, PointLight, Scene} from 'three';

const $getLightMaterial = Symbol('getLightMaterial');

/**
 * This class is intended to implement helper methods on top of Scene for
 * constructing a "lightroom" in the spirit of a satisfying, neutral default
 * studio lighting scenario.
 */
class Lightroom extends Scene {
  /**
   * This ratio is intended to approximate an averaging of the intensity over
   * the area of a given light. This ratio has been emperically derived, and
   * could probably benefit from additional massaging. However, it would be
   * better if we worked on figuring out how to blur the environment map first.
   */
  static get areaLightIntensityRatio() {
    return 1.0 / 2.25;
  }

  constructor() {
    super();

    const size = this.size = 40;
    this.geometry = new BoxBufferGeometry();

    this.furnishingMaterial =
        new MeshStandardMaterial({roughness: 1, metalness: 0});
    this.lightMaterials = new Map();

    const roomMaterial = this.furnishingMaterial.clone();
    roomMaterial.side = BackSide;

    this.room = new Mesh(this.geometry, roomMaterial);

    this.room.position.set(0, size / 2.0, 0);
    this.room.scale.multiplyScalar(size);

    this.dolly = new Object3D();
    this.dolly.position.set(0, size / 2.0, 0);

    const lightOffset = size * 0.15;
    const roomMargin = size * -0.05;
    const halfSize = size / 2.0;

    this.mainLight =
        new PointLight(0xffffff, size * 10.0, size - roomMargin, 1.75);
    this.mainLight.position.set(0.0, halfSize + lightOffset, 0.0);

    this.floorLight = new PointLight(0xffffff, size, size, 2.0);
    this.floorLight.position.set(0.0, lightOffset, 0.0);

    this.room.add(this.dolly);

    this.add(this.mainLight);
    this.add(this.floorLight);
    this.add(this.room);

    window.lightroom = this;
  }

  /**
   * Add a "furnishing", which is basically a box sitting somewhere in the room
   */
  addFurnishing(x, z, rotation, width, height, depth) {
    const {size} = this;
    const halfSize = size / 2.0;
    const furnishing = new Mesh(this.geometry, this.furnishingMaterial);

    furnishing.scale.set(size * width, size * height, size * depth);
    furnishing.rotation.set(0, rotation, 0);
    furnishing.position.set(x * halfSize, size * height / 2.0, z * halfSize);

    this.add(furnishing);
  }

  /**
   * Add a light to the wall of the room. Specify the x and y coordinates on
   * a 2D plane in [-1,1] on both axes, and use the "facing" direction to place
   * the light on a particular wall.
   */
  addWallAreaLight(x, y, width, height, facing, intensity) {
    intensity *= Lightroom.areaLightIntensityRatio;

    const lightBox =
        new Mesh(this.geometry, this[$getLightMaterial](intensity));
    const {dolly, size} = this;
    const halfSize = size / 2.0;

    lightBox.position.set(
        x * halfSize, (y - height / 2.0) * halfSize, -1.0 * halfSize + 1.0);
    lightBox.scale.set(size * width, size * height, 0.1);

    dolly.rotation.set(0, 0, 0);
    dolly.add(lightBox);

    switch (facing) {
      case '-z':
        dolly.rotation.y = Math.PI;
        break;
      case '+x':
        dolly.rotation.y = Math.PI / -2.0;
        break;
      case '-x':
        dolly.rotation.y = Math.PI / 2.0;
        break;
    }

    dolly.updateMatrixWorld(true);
    lightBox.updateMatrixWorld(true);
    lightBox.matrix.identity();
    lightBox.applyMatrix(lightBox.matrixWorld);

    this.add(lightBox);
  }

  [$getLightMaterial](intensity) {
    if (!this.lightMaterials.has(intensity)) {
      const material = new MeshBasicMaterial();
      material.color.setRGB(intensity, intensity, intensity);
      this.lightMaterials.set(intensity, material);
    }

    return this.lightMaterials.get(intensity);
  }
}

const rendererTextureCache = new Map();

export default class EnvironmentMapGenerator extends EventDispatcher {
  constructor(renderer) {
    super();

    this.renderer = renderer;

    this.scene = new Lightroom();

    // NOTE(cdata): Intensities here are mostly sampled from a relevant
    // environment map that we are trying to match closely to
    this.scene.addWallAreaLight(-0.15, -0.1, 0.325, 0.25, '+z', 15.0);
    this.scene.addWallAreaLight(0.55, 0.275, 0.2, 0.175, '-z', 30.0);
    this.scene.addWallAreaLight(-0.55, 0.05, 0.2, 0.175, '-z', 25.0);
    // NOTE(cdata): Intensity of this light was originally ~50
    this.scene.addWallAreaLight(0, -0.3, 0.25, 0.25, '+x', 30.0);
    this.scene.addWallAreaLight(0.25, -0.125, 0.15, 0.15, '-x', 13.0);

    this.scene.addFurnishing(0.1, 0.6, Math.PI / -32.0, 0.1, 0.175, 0.1);
    this.scene.addFurnishing(-0.025, 0.3, Math.PI / -6.0, 0.05, 0.02, 0.1);
    this.scene.addFurnishing(0.375, 0.1, Math.PI / 12.0, 0.08, 0.08, 0.06);
    this.scene.addFurnishing(-0.25, 0.1, Math.PI / 8.0, 0.07, 0.05, 0.08);
    this.scene.addFurnishing(0.45, -0.35, Math.PI / 6.0, 0.12, 0.12, 0.1);
    this.scene.addFurnishing(-0.125, -0.1, Math.PI / -16.0, 0.04, 0.02, 0.04);

    this.scene.position.set(-0, -4, 0);

    this.camera = new CubeCamera(0.1, 100, 256);
    this.camera.renderTarget.texture.type = FloatType;
    this.camera.renderTarget.texture.minFilter = LinearMipMapLinearFilter;
    this.camera.renderTarget.texture.generateMipmaps = true;
  }

  /**
   * Generate an environment map for a room.
   *
   * @param {number} mapSize
   */
  generate() {
    if (!rendererTextureCache.has(this.renderer)) {
      this.camera.clear(this.renderer);

      var gammaOutput = this.renderer.gammaOutput;
      var toneMapping = this.renderer.toneMapping;
      var toneMappingExposure = this.renderer.toneMappingExposure;

      this.renderer.toneMapping = LinearToneMapping;
      this.renderer.toneMappingExposure = 1.0;
      this.renderer.gammaOutput = false;

      this.camera.update(this.renderer, this.scene);

      this.renderer.toneMapping = toneMapping;
      this.renderer.toneMappingExposure = toneMappingExposure;
      this.renderer.gammaOutput = gammaOutput;

      rendererTextureCache.set(this.renderer, this.camera.renderTarget.texture);
    }

    return rendererTextureCache.get(this.renderer);
  }

  dispose() {
    this.camera.renderTarget.dispose();
  }
}
<|endoftext|>


<commit_before>/* @flow */

var resolveStyles = require('./resolve-styles.js');
var printStyles = require('./print-styles.js');

var enhanceWithRadium = function (ComposedComponent: constructor): constructor {
  class RadiumEnhancer extends ComposedComponent {
    _radiumMediaQueryListenersByQuery: {[query: string]: {remove: () => void}};
    _radiumMouseUpListener: {remove: () => void};

    constructor () {
      super(...arguments);

      this.state = this.state || {};
      this.state._radiumStyleState = {};

      if (RadiumEnhancer.printStyleClass) {
        this.printStyleClass = RadiumEnhancer.printStyleClass;
      }
    }

    render () {
      var renderedElement = super.render();
      return resolveStyles(this, renderedElement);
    }

    componentWillUnmount () {
      if (super.componentWillUnmount) {
        super.componentWillUnmount();
      }

      if (this._radiumMouseUpListener) {
        this._radiumMouseUpListener.remove();
      }

      if (this._radiumMediaQueryListenersByQuery) {
        Object.keys(this._radiumMediaQueryListenersByQuery).forEach(
          function (query) {
            this._radiumMediaQueryListenersByQuery[query].remove();
          },
          this
        );
      }
    }
  }

  // Class inheritance uses Object.create and because of __proto__ issues
  // with IE <10 any static properties of the superclass aren't inherited and
  // so need to be manually populated
  // See http://babeljs.io/docs/advanced/caveats/#classes-10-and-below-
  var staticKeys = [
    'defaultProps',
    'propTypes',
    'contextTypes',
    'childContextTypes'
  ];

  staticKeys.forEach((key) => {
    if (ComposedComponent.hasOwnProperty(key)) {
      RadiumEnhancer[key] = ComposedComponent[key];
    }
  });

  if (process.env.NODE_ENV !== 'production') {
    // This fixes React Hot Loader by exposing the original components top level
    // prototype methods on the Radium enhanced prototype as discussed in #219.
    Object.keys(ComposedComponent.prototype).forEach(key => {
      if (!RadiumEnhancer.prototype.hasOwnProperty(key)) {
        RadiumEnhancer.prototype[key] = ComposedComponent.prototype[key];
      }
    });
  }

  RadiumEnhancer.displayName =
    ComposedComponent.displayName ||
    ComposedComponent.name ||
    'Component';

  RadiumEnhancer.printStyleClass = printStyles.addPrintStyles(RadiumEnhancer);

  return RadiumEnhancer;
};

module.exports = enhanceWithRadium;
<commit_msg>Prevents errors from getters that do not have setters.<commit_after>/* @flow */

var resolveStyles = require('./resolve-styles.js');
var printStyles = require('./print-styles.js');

var enhanceWithRadium = function (ComposedComponent: constructor): constructor {
  class RadiumEnhancer extends ComposedComponent {
    _radiumMediaQueryListenersByQuery: {[query: string]: {remove: () => void}};
    _radiumMouseUpListener: {remove: () => void};

    constructor () {
      super(...arguments);

      this.state = this.state || {};
      this.state._radiumStyleState = {};

      if (RadiumEnhancer.printStyleClass) {
        this.printStyleClass = RadiumEnhancer.printStyleClass;
      }
    }

    render () {
      var renderedElement = super.render();
      return resolveStyles(this, renderedElement);
    }

    componentWillUnmount () {
      if (super.componentWillUnmount) {
        super.componentWillUnmount();
      }

      if (this._radiumMouseUpListener) {
        this._radiumMouseUpListener.remove();
      }

      if (this._radiumMediaQueryListenersByQuery) {
        Object.keys(this._radiumMediaQueryListenersByQuery).forEach(
          function (query) {
            this._radiumMediaQueryListenersByQuery[query].remove();
          },
          this
        );
      }
    }
  }

  // Class inheritance uses Object.create and because of __proto__ issues
  // with IE <10 any static properties of the superclass aren't inherited and
  // so need to be manually populated
  // See http://babeljs.io/docs/advanced/caveats/#classes-10-and-below-
  var staticKeys = [
    'defaultProps',
    'propTypes',
    'contextTypes',
    'childContextTypes'
  ];

  staticKeys.forEach((key) => {
    if (ComposedComponent.hasOwnProperty(key)) {
      RadiumEnhancer[key] = ComposedComponent[key];
    }
  });

  if (process.env.NODE_ENV !== 'production') {
    // This fixes React Hot Loader by exposing the original components top level
    // prototype methods on the Radium enhanced prototype as discussed in #219.
    Object.keys(ComposedComponent.prototype).forEach(key => {
      if (!RadiumEnhancer.prototype.hasOwnProperty(key)) {
        var descriptor = Object.getOwnPropertyDescriptor(ComposedComponent.prototype, key);
        Object.defineProperty(RadiumEnhancer.prototype, key, descriptor);
      }
    });
  }

  RadiumEnhancer.displayName =
    ComposedComponent.displayName ||
    ComposedComponent.name ||
    'Component';

  RadiumEnhancer.printStyleClass = printStyles.addPrintStyles(RadiumEnhancer);

  return RadiumEnhancer;
};

module.exports = enhanceWithRadium;
<|endoftext|>


<commit_before>import gql from 'src/lib/gql';
import ga from 'src/lib/ga';
import { t } from 'ttag';
import {
  getArticleURL,
  UPVOTE_PREFIX,
  DOWNVOTE_PREFIX,
} from 'src/lib/sharedUtils';
import {
  createTypeWords,
  ellipsis,
  ManipulationError,
  FLEX_MESSAGE_ALT_TEXT,
} from './utils';

/**
 * @param {{vote: FeedbackVote, articleId: String, replyId: String, comment: String}} variables
 * @param {object} search
 * @returns {Promise}
 */
const updateFeedback = gql`
  mutation UpdateFeedback(
    $vote: FeedbackVote!
    $articleId: String!
    $replyId: String!
    $comment: String
  ) {
    CreateOrUpdateArticleReplyFeedback(
      vote: $vote
      articleId: $articleId
      replyId: $replyId
      comment: $comment
    ) {
      reply {
        type
      }
      feedbackCount
    }
  }
`;

export default async function askingReplyFeedback(params) {
  let { data, state, event, issuedAt, userId, replies, isSkipUser } = params;

  if (!data.selectedReplyId) {
    throw new Error('selectedReply not set in data');
  }

  if (event.input.startsWith(UPVOTE_PREFIX)) {
    const { data: updateData, errors } = await updateFeedback(
      {
        articleId: data.selectedArticleId,
        replyId: data.selectedReplyId,
        vote: 'UPVOTE',
        comment: event.input.slice(UPVOTE_PREFIX.length),
      },
      { userId }
    );

    if (errors) {
      throw ManipulationError(t`Cannot record your feedback. Try again later?`);
    }

    const articleText = ellipsis(data.selectedArticleText, 15);
    const replyType = createTypeWords(
      updateData.CreateOrUpdateArticleReplyFeedback.reply.type
    ).toLowerCase();
    const articleUrl = getArticleURL(data.selectedArticleId);
    const sharedText = t`Someone says the message “${articleText}” ${replyType}.\n\nPlease refer to ${articleUrl} for more information, replies and references.`;

    const otherFeedbackCount =
      updateData.CreateOrUpdateArticleReplyFeedback.feedbackCount - 1;
    const callToAction = t`Don't forget to forward the messages above to others and share with them!`;

    replies = [
      {
        type: 'text',
        text:
          otherFeedbackCount > 0
            ? t`We've received feedback from you and ${otherFeedbackCount} other users!`
            : t`Thanks. You're the first one who gave feedback on this reply!`,
      },
      {
        type: 'flex',
        altText: callToAction + '\n' + FLEX_MESSAGE_ALT_TEXT,
        contents: {
          type: 'bubble',
          body: {
            type: 'box',
            layout: 'vertical',
            spacing: 'md',
            paddingAll: 'lg',
            contents: [
              {
                type: 'text',
                wrap: true,
                text: callToAction,
              },
            ],
          },
          footer: {
            type: 'box',
            layout: 'vertical',
            spacing: 'sm',
            contents: [
              {
                type: 'button',
                style: 'primary',
                color: '#ffb600',
                action: {
                  type: 'uri',
                  label: t`Share to friends`,
                  uri: `https://line.me/R/msg/text/?${encodeURI(sharedText)}`,
                },
              },
              {
                type: 'button',
                style: 'link',
                color: '#ffb600',
                action: {
                  type: 'uri',
                  label: t`Submit new reply`,
                  uri: getArticleURL(data.selectedArticleId),
                },
              },
            ],
          },
        },
      },
    ];
  } else if (event.input.startsWith(DOWNVOTE_PREFIX)) {
    const { data: updateData, errors } = await updateFeedback(
      {
        articleId: data.selectedArticleId,
        replyId: data.selectedReplyId,
        vote: 'DOWNVOTE',
        comment: event.input.slice(DOWNVOTE_PREFIX.length),
      },
      { userId }
    );

    if (errors) {
      throw ManipulationError(t`Cannot record your feedback. Try again later?`);
    }

    const articleUrl = getArticleURL(data.selectedArticleId);
    const otherFeedbackCount =
      updateData.CreateOrUpdateArticleReplyFeedback.feedbackCount - 1;

    replies = [
      {
        type: 'text',
        text:
          otherFeedbackCount > 0
            ? t`We've received feedback from you and ${otherFeedbackCount} other users!`
            : t`Thanks. You're the first one who gave feedback on this reply!`,
      },
      {
        type: 'text',
        text: `💁 ${t`If you have a better reply, feel free to submit it to ${articleUrl} .`}`,
      },
    ];
  } else {
    throw new ManipulationError(
      t`Please press the latest button to provide feedback to reply.`
    );
  }

  const visitor = ga(userId, state, data.selectedArticleText);

  // Track when user give feedback.
  visitor.event({
    ec: 'UserInput',
    ea: 'Feedback-Vote',
    el: `${data.selectedArticleId}/${data.selectedReplyId}`,
  });

  visitor.send();

  return { data, state, event, issuedAt, userId, replies, isSkipUser };
}
<commit_msg>[askingReplyFeedback] simplify error handling<commit_after>import gql from 'src/lib/gql';
import ga from 'src/lib/ga';
import { t } from 'ttag';
import {
  getArticleURL,
  UPVOTE_PREFIX,
  DOWNVOTE_PREFIX,
} from 'src/lib/sharedUtils';
import {
  createTypeWords,
  ellipsis,
  ManipulationError,
  FLEX_MESSAGE_ALT_TEXT,
} from './utils';

/**
 * @param {{vote: FeedbackVote, articleId: String, replyId: String, comment: String}} variables
 * @param {object} search
 * @returns {Promise<{reply: Object, feedbackCount: Number}>}
 */
async function updateFeedback(variables, search) {
  const { data, errors } = await gql`
    mutation UpdateFeedback(
      $vote: FeedbackVote!
      $articleId: String!
      $replyId: String!
      $comment: String
    ) {
      CreateOrUpdateArticleReplyFeedback(
        vote: $vote
        articleId: $articleId
        replyId: $replyId
        comment: $comment
      ) {
        reply {
          type
        }
        feedbackCount
      }
    }
  `(variables, search);

  if (errors) {
    throw ManipulationError(t`Cannot record your feedback. Try again later?`);
  }

  return data.CreateOrUpdateArticleReplyFeedback;
}

export default async function askingReplyFeedback(params) {
  let { data, state, event, issuedAt, userId, replies, isSkipUser } = params;

  if (!data.selectedReplyId) {
    throw new Error('selectedReply not set in data');
  }

  if (event.input.startsWith(UPVOTE_PREFIX)) {
    const updatedArticleReply = await updateFeedback(
      {
        articleId: data.selectedArticleId,
        replyId: data.selectedReplyId,
        vote: 'UPVOTE',
        comment: event.input.slice(UPVOTE_PREFIX.length),
      },
      { userId }
    );

    const articleText = ellipsis(data.selectedArticleText, 15);
    const replyType = createTypeWords(
      updatedArticleReply.reply.type
    ).toLowerCase();
    const articleUrl = getArticleURL(data.selectedArticleId);
    const sharedText = t`Someone says the message “${articleText}” ${replyType}.\n\nPlease refer to ${articleUrl} for more information, replies and references.`;

    const otherFeedbackCount = updatedArticleReply.feedbackCount - 1;
    const callToAction = t`Don't forget to forward the messages above to others and share with them!`;

    replies = [
      {
        type: 'text',
        text:
          otherFeedbackCount > 0
            ? t`We've received feedback from you and ${otherFeedbackCount} other users!`
            : t`Thanks. You're the first one who gave feedback on this reply!`,
      },
      {
        type: 'flex',
        altText: callToAction + '\n' + FLEX_MESSAGE_ALT_TEXT,
        contents: {
          type: 'bubble',
          body: {
            type: 'box',
            layout: 'vertical',
            spacing: 'md',
            paddingAll: 'lg',
            contents: [
              {
                type: 'text',
                wrap: true,
                text: callToAction,
              },
            ],
          },
          footer: {
            type: 'box',
            layout: 'vertical',
            spacing: 'sm',
            contents: [
              {
                type: 'button',
                style: 'primary',
                color: '#ffb600',
                action: {
                  type: 'uri',
                  label: t`Share to friends`,
                  uri: `https://line.me/R/msg/text/?${encodeURI(sharedText)}`,
                },
              },
              {
                type: 'button',
                style: 'link',
                color: '#ffb600',
                action: {
                  type: 'uri',
                  label: t`Submit new reply`,
                  uri: getArticleURL(data.selectedArticleId),
                },
              },
            ],
          },
        },
      },
    ];
  } else if (event.input.startsWith(DOWNVOTE_PREFIX)) {
    const updatedArticleReply = await updateFeedback(
      {
        articleId: data.selectedArticleId,
        replyId: data.selectedReplyId,
        vote: 'DOWNVOTE',
        comment: event.input.slice(DOWNVOTE_PREFIX.length),
      },
      { userId }
    );

    const articleUrl = getArticleURL(data.selectedArticleId);
    const otherFeedbackCount = updatedArticleReply.feedbackCount - 1;

    replies = [
      {
        type: 'text',
        text:
          otherFeedbackCount > 0
            ? t`We've received feedback from you and ${otherFeedbackCount} other users!`
            : t`Thanks. You're the first one who gave feedback on this reply!`,
      },
      {
        type: 'text',
        text: `💁 ${t`If you have a better reply, feel free to submit it to ${articleUrl} .`}`,
      },
    ];
  } else {
    throw new ManipulationError(
      t`Please press the latest button to provide feedback to reply.`
    );
  }

  const visitor = ga(userId, state, data.selectedArticleText);

  // Track when user give feedback.
  visitor.event({
    ec: 'UserInput',
    ea: 'Feedback-Vote',
    el: `${data.selectedArticleId}/${data.selectedReplyId}`,
  });

  visitor.send();

  return { data, state, event, issuedAt, userId, replies, isSkipUser };
}
<|endoftext|>


<commit_before>import mapValues from 'lodash/mapValues';

export const FilterState = {
  DO_NOT_FILTER: 'DO_NOT_FILTER',
  BLACKLIST_SPECIFIC: 'BLACKLIST_SPECIFIC',
  WHITELIST_SPECIFIC: 'WHITELIST_SPECIFIC'
};

export function getLocalFilter(config) {
  if (config.actionsBlacklist || config.actionsWhitelist) {
    return {
      whitelist: config.actionsWhitelist && config.actionsWhitelist.join('|'),
      blacklist: config.actionsBlacklist && config.actionsBlacklist.join('|')
    };
  }
  return undefined;
}

export function isFiltered(action, localFilter) {
  if (
    !localFilter && window.devToolsOptions.filter === FilterState.DO_NOT_FILTER ||
    typeof action.type.match !== 'function'
  ) return false;

  const { whitelist, blacklist } = localFilter || window.devToolsOptions;
  return (
    whitelist && !action.type.match(whitelist) ||
    blacklist && action.type.match(blacklist)
  );
}

function filterActions(actionsById, actionSanitizer) {
  if (!actionSanitizer) return actionsById;
  return mapValues(actionsById, (action, id) => (
    { ...action, action: actionSanitizer(action.action, id) }
  ));
}

function filterStates(computedStates, stateSanitizer) {
  if (!stateSanitizer) return computedStates;
  return computedStates.map((state, idx) => (
    { ...state, state: stateSanitizer(state.state, idx) }
  ));
}

export function filterState(state, type, localFilter, stateSanitizer, actionSanitizer, nextActionId, predicate) {
  if (type === 'ACTION') return !stateSanitizer ? state : stateSanitizer(state, nextActionId - 1);
  else if (type !== 'STATE') return state;

  if (predicate || localFilter || window.devToolsOptions.filter !== FilterState.DO_NOT_FILTER) {
    const filteredStagedActionIds = [];
    const filteredComputedStates = [];
    const sanitizedActionsById = actionSanitizer && {};
    const { actionsById } = state;
    const { computedStates } = state;

    state.stagedActionIds.forEach((id, idx) => {
      const liftedAction = actionsById[id];
      const currAction = liftedAction.action;
      const liftedState = computedStates[idx];
      const currState = liftedState.state;
      if (idx) {
        if (predicate && !predicate(currState, currAction)) return;
        if (isFiltered(currAction, localFilter)) return;
      }

      filteredStagedActionIds.push(id);
      filteredComputedStates.push(
        stateSanitizer ? { ...liftedState, state: stateSanitizer(currState, idx) } : liftedState
      );
      if (actionSanitizer) {
        sanitizedActionsById[id] = {
          ...liftedAction, action: actionSanitizer(currAction, id)
        };
      }
    });

    return {
      ...state,
      actionsById: sanitizedActionsById || actionsById,
      stagedActionIds: filteredStagedActionIds,
      computedStates: filteredComputedStates
    };
  }

  if (!stateSanitizer && !actionSanitizer) return state;
  return {
    ...state,
    actionsById: filterActions(state.actionsById, actionSanitizer),
    computedStates: filterStates(state.computedStates, stateSanitizer)
  };
}

export function startingFrom(
  sendingActionId, state, localFilter, stateSanitizer, actionSanitizer, predicate
) {
  const stagedActionIds = state.stagedActionIds;
  if (sendingActionId <= stagedActionIds[1]) return state;
  const index = stagedActionIds.indexOf(sendingActionId);
  if (index === -1) return state;

  const shouldFilter = predicate || localFilter ||
    window.devToolsOptions.filter !== FilterState.DO_NOT_FILTER;
  const filteredStagedActionIds = shouldFilter ? [0] : stagedActionIds;
  const actionsById = state.actionsById;
  const computedStates = state.computedStates;
  const newActionsById = {};
  const newComputedStates = [];
  let key;
  let currAction;
  let currState;

  for (let i = shouldFilter ? 1 : index; i < stagedActionIds.length; i++) {
    key = stagedActionIds[i];
    currAction = actionsById[key];
    currState = computedStates[i];

    if (shouldFilter) {
      if (
        predicate && !predicate(currState.state, currAction.action) ||
        isFiltered(currAction.action, localFilter)
      ) continue;
      filteredStagedActionIds.push(key);
      if (i < index) continue;
    }

    newActionsById[key] = !actionSanitizer ? currAction :
      { ...currAction, action: actionSanitizer(currAction.action, key) };
    newComputedStates.push(
      !stateSanitizer ? currState : { ...currState, state: stateSanitizer(currState.state, i) }
    );
  }

  if (newComputedStates.length === 0) return undefined;

  return {
    actionsById: newActionsById,
    computedStates: newComputedStates,
    stagedActionIds: filteredStagedActionIds,
    currentStateIndex: state.currentStateIndex,
    nextActionId: state.nextActionId
  };
}
<commit_msg>Prevent accessing `window.devToolsOptions` when not specified<commit_after>import mapValues from 'lodash/mapValues';

export const FilterState = {
  DO_NOT_FILTER: 'DO_NOT_FILTER',
  BLACKLIST_SPECIFIC: 'BLACKLIST_SPECIFIC',
  WHITELIST_SPECIFIC: 'WHITELIST_SPECIFIC'
};

export function getLocalFilter(config) {
  if (config.actionsBlacklist || config.actionsWhitelist) {
    return {
      whitelist: config.actionsWhitelist && config.actionsWhitelist.join('|'),
      blacklist: config.actionsBlacklist && config.actionsBlacklist.join('|')
    };
  }
  return undefined;
}

export function isFiltered(action, localFilter) {
  if (
    !localFilter || window.devToolsOptions &&
    window.devToolsOptions.filter === FilterState.DO_NOT_FILTER ||
    typeof action.type.match !== 'function'
  ) return false;

  const { whitelist, blacklist } = localFilter || window.devToolsOptions;
  return (
    whitelist && !action.type.match(whitelist) ||
    blacklist && action.type.match(blacklist)
  );
}

function filterActions(actionsById, actionSanitizer) {
  if (!actionSanitizer) return actionsById;
  return mapValues(actionsById, (action, id) => (
    { ...action, action: actionSanitizer(action.action, id) }
  ));
}

function filterStates(computedStates, stateSanitizer) {
  if (!stateSanitizer) return computedStates;
  return computedStates.map((state, idx) => (
    { ...state, state: stateSanitizer(state.state, idx) }
  ));
}

export function filterState(state, type, localFilter, stateSanitizer, actionSanitizer, nextActionId, predicate) {
  if (type === 'ACTION') return !stateSanitizer ? state : stateSanitizer(state, nextActionId - 1);
  else if (type !== 'STATE') return state;

  if (
    predicate || localFilter || window.devToolsOptions &&
    window.devToolsOptions.filter !== FilterState.DO_NOT_FILTER
  ) {
    const filteredStagedActionIds = [];
    const filteredComputedStates = [];
    const sanitizedActionsById = actionSanitizer && {};
    const { actionsById } = state;
    const { computedStates } = state;

    state.stagedActionIds.forEach((id, idx) => {
      const liftedAction = actionsById[id];
      const currAction = liftedAction.action;
      const liftedState = computedStates[idx];
      const currState = liftedState.state;
      if (idx) {
        if (predicate && !predicate(currState, currAction)) return;
        if (isFiltered(currAction, localFilter)) return;
      }

      filteredStagedActionIds.push(id);
      filteredComputedStates.push(
        stateSanitizer ? { ...liftedState, state: stateSanitizer(currState, idx) } : liftedState
      );
      if (actionSanitizer) {
        sanitizedActionsById[id] = {
          ...liftedAction, action: actionSanitizer(currAction, id)
        };
      }
    });

    return {
      ...state,
      actionsById: sanitizedActionsById || actionsById,
      stagedActionIds: filteredStagedActionIds,
      computedStates: filteredComputedStates
    };
  }

  if (!stateSanitizer && !actionSanitizer) return state;
  return {
    ...state,
    actionsById: filterActions(state.actionsById, actionSanitizer),
    computedStates: filterStates(state.computedStates, stateSanitizer)
  };
}

export function startingFrom(
  sendingActionId, state, localFilter, stateSanitizer, actionSanitizer, predicate
) {
  const stagedActionIds = state.stagedActionIds;
  if (sendingActionId <= stagedActionIds[1]) return state;
  const index = stagedActionIds.indexOf(sendingActionId);
  if (index === -1) return state;

  const shouldFilter = predicate || localFilter ||
    window.devToolsOptions.filter !== FilterState.DO_NOT_FILTER;
  const filteredStagedActionIds = shouldFilter ? [0] : stagedActionIds;
  const actionsById = state.actionsById;
  const computedStates = state.computedStates;
  const newActionsById = {};
  const newComputedStates = [];
  let key;
  let currAction;
  let currState;

  for (let i = shouldFilter ? 1 : index; i < stagedActionIds.length; i++) {
    key = stagedActionIds[i];
    currAction = actionsById[key];
    currState = computedStates[i];

    if (shouldFilter) {
      if (
        predicate && !predicate(currState.state, currAction.action) ||
        isFiltered(currAction.action, localFilter)
      ) continue;
      filteredStagedActionIds.push(key);
      if (i < index) continue;
    }

    newActionsById[key] = !actionSanitizer ? currAction :
      { ...currAction, action: actionSanitizer(currAction.action, key) };
    newComputedStates.push(
      !stateSanitizer ? currState : { ...currState, state: stateSanitizer(currState.state, i) }
    );
  }

  if (newComputedStates.length === 0) return undefined;

  return {
    actionsById: newActionsById,
    computedStates: newComputedStates,
    stagedActionIds: filteredStagedActionIds,
    currentStateIndex: state.currentStateIndex,
    nextActionId: state.nextActionId
  };
}
<|endoftext|>