<commit_before>// ┌────────────────────────────────────────────────────────────────────┐ \\
// │ dhmap - HTML5/JS network layouts                                   │ \\
// ├────────────────────────────────────────────────────────────────────┤ \\
// │ Copyright © 2014 Dreamhack Tech                                    │ \\
// │ Copyright © 2014 Niklas Lindblad <niklas@lindblad.info>            │ \\
// ├────────────────────────────────────────────────────────────────────┤ \\
// │ Licensed under the MIT license.                                    │ \\
// └────────────────────────────────────────────────────────────────────┘ \\

var dhmap = {};

(function () {
  var scaling = 3;
  var switches = {};
  var paper = null;
  var canvasObjects = {};
  var offsetX = 0;
  var offsetY = 0;
  var boundingX = 0;
  var boundingY = 0;
  var onclick = null;

  dhmap.colour = {
    'OK':      'rgb(137,245,108)',
    'CRITICAL':'rgb(255,0,0)',
    'WARNING': 'rgb(255,191,0)',
    'SPEED':   'rgb(223,0,255)',
    'STP':     'rgb(0,102,153)',
    'ERRORS':  'rgb(0,255,255)',
    'UNKNOWN': 'rgb(112,112,112)',
    'TABLE':   'rgb(242,242,242)'
  };

  // Draw a rectangle and save a reference to the object
  function renderRectangle(object, fillColor, isTable) {
      // Whether the object is horizontal or not, determines whether to swap
      // width/height to conform with RaphaelJS drawing
      var width = object.horizontal == 1 ? object.width : object.height;
      var height = object.horizontal == 1 ? object.height : object.width;

      // See if this will increase the bounding box
      boundingX = Math.max(object.x1 + width, boundingX);
      boundingY = Math.max(object.y1 + height, boundingY);

      // Scale according to the scaling factor defined at the top
      width = width * scaling;
      height = height * scaling;
      var x1 = (offsetX + object.x1) * scaling;
      var y1 = (offsetY + object.y1) * scaling;

      // Create the rectangle and fill it
      var rectangle = paper.rect(x1, y1, width, height);
      rectangle.attr({fill: fillColor});

      // Add a label
      if (isTable) {
        var labelOffsetX = 12;
        var labelOffsetY = 12;
      } else {
        var labelOffsetX = 12;
        var labelOffsetY = 40;
      }

      var shortName = object.name.split('.')[0].toUpperCase();
      rectangle.label = paper.text(rectangle.attr('x') + labelOffsetX, rectangle.attr('y') + labelOffsetY, shortName);
      if (!isTable) {
        rectangle.label.attr({"font-size": 16});
      }

      // For some objects it might be desirable to hide the label.
      // For those objects we add a mouse over to display it.
      if ( ! isTable ) {
        rectangle.label.hide();
        rectangle.mouseover(function() {
            this.animate({"fill-opacity": 0.8}, 500);
            this.label.show();
        });
        rectangle.mouseout(function() {
            this.label.hide();
        });
        rectangle.click(function() {
          onclick(object);
        });
      }

      // Add rectangle to list of all drawn objects
      canvasObjects[object.name] = rectangle;
  }

  // Draw a network switch. Defaults to amber colour
  function renderSwitch(object) {
      switches[object.name] = object;
      renderRectangle(object, dhmap.colour.UNKNOWN, false);
  }

  // Draw a table
  function renderTable(object) {
      renderRectangle(object, dhmap.colour.TABLE, true);
  }

  // Update colour of previously drawn switch
  function setSwitchColor(name, color) {
      if (canvasObjects[name].attrs.fill != color) {
          canvasObjects[name].attr({"fill": color})
      }
  }

  // Update the status of all switches previously drawn on screen
  dhmap.updateSwitches = function(statuses) {
      // Save state
      lastStatuses = statuses;
      for ( var name in switches ) {
          // If the switch is unknown, render it as amber
          if ( statuses[name] === undefined ) {
              setSwitchColor(name, dhmap.colour.UNKNOWN);
          } else {
              // A confirmed healthy switch is green, failed ones are red
              setSwitchColor(name, dhmap.colour[statuses[name]]);
          }
      }
  }

  // Which render method to use for each object type
  var renders= { 'switch': renderSwitch, 'table': renderTable };

  dhmap.init = function(objects, click_callback) {
    var canvas = document.getElementById('canvas');
    var menu = document.getElementById('menu');
    var header = document.getElementById('header');
    canvas.innerHTML = '';
    canvas.style.marginLeft = menu.clientWidth;

    // TODO(bluecmd): Calculate these automatically
    var width = window.innerWidth - menu.clientWidth - 2;
    var height = window.innerHeight - header.clientHeight - 2;

    if (width < 2000) {
      width = 2000;
    }
    if (height < 800) {
      height = 800;
    }

    canvas.style.width = width;
    canvas.style.height = height;

    menu.style.height = window.innerHeight - header.clientHeight;
    paper = Raphael(canvas);
    var zpd = new RaphaelZPD(paper, { zoom: true, pan: true, drag: false });
    zpd.gelem.setAttribute('transform', 'matrix(0.4214982092380523,0,0,0.4214982092380523,56.18161920675628,33.90790739210934)');

    onclick = click_callback;
    switches = {};
    canvasObjects = {};

    offsetX = 0;
    offsetY = 0;

    for ( var hall in objects ) {

      // Calculate new bounding box for this hall
      boundingX = 0;
      boundingY = 0;

      for ( var i in objects[hall] ) {
        renders[objects[hall][i]['class']](objects[hall][i]);
      }

      offsetX += boundingX + 20;
    }
  }

})();
<commit_msg>add hall bounding boxes and names<commit_after>// ┌────────────────────────────────────────────────────────────────────┐ \\
// │ dhmap - HTML5/JS network layouts                                   │ \\
// ├────────────────────────────────────────────────────────────────────┤ \\
// │ Copyright © 2014 Dreamhack Tech                                    │ \\
// │ Copyright © 2014 Niklas Lindblad <niklas@lindblad.info>            │ \\
// ├────────────────────────────────────────────────────────────────────┤ \\
// │ Licensed under the MIT license.                                    │ \\
// └────────────────────────────────────────────────────────────────────┘ \\

var dhmap = {};

(function () {
  var scaling = 3;
  var switches = {};
  var paper = null;
  var canvasObjects = {};
  var offsetX = 0;
  var offsetY = 0;
  var boundingX = 0;
  var boundingY = 0;
  var onclick = null;

  dhmap.colour = {
    'OK':      'rgb(137,245,108)',
    'CRITICAL':'rgb(255,0,0)',
    'WARNING': 'rgb(255,191,0)',
    'SPEED':   'rgb(223,0,255)',
    'STP':     'rgb(0,102,153)',
    'ERRORS':  'rgb(0,255,255)',
    'UNKNOWN': 'rgb(112,112,112)',
    'TABLE':   'rgba(242,242,242, 0.5)'
  };

  // Draw a rectangle and save a reference to the object
  function renderRectangle(object, fillColor, isTable, dry) {
      // Whether the object is horizontal or not, determines whether to swap
      // width/height to conform with RaphaelJS drawing
      var width = object.horizontal == 1 ? object.width : object.height;
      var height = object.horizontal == 1 ? object.height : object.width;

      // See if this will increase the bounding box
      boundingX = Math.max(object.x1 + width, boundingX);
      boundingY = Math.max(object.y1 + height, boundingY);

      // Scale according to the scaling factor defined at the top
      width = width * scaling;
      height = height * scaling;
      var x1 = (offsetX + object.x1) * scaling;
      var y1 = (offsetY + object.y1) * scaling;

      if (dry) {
        return;
      }

      // Create the rectangle and fill it
      var rectangle = paper.rect(x1, y1, width, height);
      rectangle.attr({fill: fillColor});

      // Add a label
      if (isTable) {
        var labelOffsetX = 12;
        var labelOffsetY = 12;
      } else {
        var labelOffsetX = 12;
        var labelOffsetY = 40;
      }

      var shortName = object.name.split('.')[0].toUpperCase();
      rectangle.label = paper.text(rectangle.attr('x') + labelOffsetX, rectangle.attr('y') + labelOffsetY, shortName);
      if (!isTable) {
        rectangle.label.attr({"font-size": 16});
      }

      // For some objects it might be desirable to hide the label.
      // For those objects we add a mouse over to display it.
      if ( ! isTable ) {
        rectangle.label.hide();
        rectangle.mouseover(function() {
            this.animate({"fill-opacity": 0.8}, 500);
            this.label.show();
        });
        rectangle.mouseout(function() {
            this.label.hide();
        });
        rectangle.click(function() {
          onclick(object);
        });
      }

      // Add rectangle to list of all drawn objects
      canvasObjects[object.name] = rectangle;
  }

  // Draw a network switch. Defaults to amber colour
  function renderSwitch(object, dry) {
      switches[object.name] = object;
      renderRectangle(object, dhmap.colour.UNKNOWN, false, dry);
  }

  // Draw a table
  function renderTable(object, dry) {
      renderRectangle(object, dhmap.colour.TABLE, true, dry);
  }

  // Update colour of previously drawn switch
  function setSwitchColor(name, color) {
      if (canvasObjects[name].attrs.fill != color) {
          canvasObjects[name].attr({"fill": color})
      }
  }

  // Update the status of all switches previously drawn on screen
  dhmap.updateSwitches = function(statuses) {
      // Save state
      lastStatuses = statuses;
      for ( var name in switches ) {
          // If the switch is unknown, render it as amber
          if ( statuses[name] === undefined ) {
              setSwitchColor(name, dhmap.colour.UNKNOWN);
          } else {
              // A confirmed healthy switch is green, failed ones are red
              setSwitchColor(name, dhmap.colour[statuses[name]]);
          }
      }
  }

  // Which render method to use for each object type
  var renders = { 'switch': renderSwitch, 'table': renderTable };

  dhmap.init = function(objects, click_callback) {
    var canvas = document.getElementById('canvas');
    var menu = document.getElementById('menu');
    var header = document.getElementById('header');
    canvas.innerHTML = '';
    canvas.style.marginLeft = menu.clientWidth;

    // TODO(bluecmd): Calculate these automatically
    var width = window.innerWidth - menu.clientWidth - 2;
    var height = window.innerHeight - header.clientHeight - 2;

    if (width < 2000) {
      width = 2000;
    }
    if (height < 800) {
      height = 800;
    }

    canvas.style.width = width;
    canvas.style.height = height;

    menu.style.height = window.innerHeight - header.clientHeight;
    paper = Raphael(canvas);
    var zpd = new RaphaelZPD(paper, { zoom: true, pan: true, drag: false });
    zpd.gelem.setAttribute('transform', 'matrix(0.4214982092380523,0,0,0.4214982092380523,56.18161920675628,33.90790739210934)');

    onclick = click_callback;
    switches = {};
    canvasObjects = {};

    offsetX = 0;
    offsetY = 0;

    var halls = Object.keys(objects).length;
    var hallidx = 0;
    for ( var hall in objects ) {

      // Calculate new bounding box for this hall
      // First run is a dry run for just calculating the bounding boxes
      boundingX = 0;
      boundingY = 0;

      for ( var i in objects[hall] ) {
        renders[objects[hall][i]['class']](objects[hall][i], true);
      }

      var hue = (hallidx/halls) * 360;
      console.log("hue " + hue);

      var hallRect = paper.rect(
          (offsetX - 15) * scaling,
          (offsetY - 15) * scaling,
          (boundingX + 30) * scaling,
          (boundingY + 30) * scaling);
      var labelOffsetX = (boundingX + 30) * scaling / 2;
      var labelOffsetY = -100;
      hallRect.attr({fill: 'hsla(' + hue + ',100%,50%,0.3)'});
      hallRect.label = paper.text(hallRect.attr('x') + labelOffsetX, hallRect.attr('y') + labelOffsetY, hall);
      hallRect.label.attr({'font-size': 144});
      hallRect.label.attr({'border': '1px solid red'});
      hallRect.label.attr({'fill': 'rgba(200, 200, 200, 0.7)'});

      // Re-do with real paint this time
      boundingX = 0;
      boundingY = 0;
      for ( var i in objects[hall] ) {
        renders[objects[hall][i]['class']](objects[hall][i], false);
      }

      offsetX += boundingX + 40;
      hallidx++;
    }
  }

})();
<|endoftext|>


<commit_before>/**
 * @author Camille Reynders
 * @version 0.2.0
 * @namespace
 */
var dijon = {
	/**
	 * framework version number
	 * @constant
	 * @type String
	 */
	VERSION : '0.5.0'
};//dijon

  //======================================//
 // dijon.System
//======================================//

/**
 * @class dijon.System
 * @constructor
*/
dijon.System = function(){
	/** @private */
	this._mappings = {};

	/** @private */
	this._outlets = [];

    this.strictInjections = true;
};//dijon.System

dijon.System.prototype = {

	/**
	 * @private
	 * @param {Class} clazz
	 */
	_createAndSetupInstance : function( key, clazz ){
		var instance = new clazz();
		this.injectInto( key, instance );
		if( "setup" in instance ) instance.setup.call( instance );
		return instance;
	},

	/**
	 * @private
	 * @param {Stirng} key
	 * @param {Boolean} overrideRules
	 * @return {Object}
	 */
	_retrieveFromCacheOrCreate : function( key, overrideRules ){
        if( overrideRules == undefined ) overrideRules = false;
        if( this._mappings.hasOwnProperty( key ) ){
            var config = this._mappings[ key ];
            var output = null;
            if( !overrideRules && config.isSingleton ){
                if( config.object == null  ){
                    config.object = this._createAndSetupInstance( key, config.clazz );
                }
                output = config.object;
            }else{
                if( config.clazz ) output = this._createAndSetupInstance( key, config.clazz );
            }
        }else{
            throw new Error( this.fqn + " is missing a rule for " + key );
        }
		return output
	},

	/**
	 * defines propertyName as an injection point for the class mapped to targetKey to be injected with an instance
	 * of the class mapped to sourceKey.
	 * @param {String} target the class the injection point is applied to.
	 * @param {String} outlet the name of the property used as an injection point.

	 * [!] MUST BE STRING
	 * @param {String} source the key to the value that will be injected
     * @see dijon.System#removeOutlet
	 */
	addOutlet : function( source, target, outlet ){
        if( target == undefined ) target = "global";
        if( outlet == undefined ) outlet = source;
        if( ! this._outlets.hasOwnProperty( target ) ) this._outlets[ target ] = {};
		this._outlets[ target ][ outlet ] = source
	},

	/**
	 * Create (if possible) or retrieve an instance of the class mapped to key
	 * @param {Object} key
	 * @return {Object}
	 */
	getInstance : function( key ){
		return this._retrieveFromCacheOrCreate( key );
	},

	/**
	 * When asked for an instance of the class whenAskedFor or object whenAskedFor inject the instance useValue.
	 * @param {String} key
	 * @param {Object} useValue
	 */
	mapValue : function( key, useValue ){
		this._mappings[ key ]= {
            clazz : null,
            object : useValue,
            isSingleton : true
		}
	},

	/**
	 * Does a rule exist to satsify such a request?
	 * @param {String} key
	 * @return {Boolean}
	 */
	hasMapping : function( key ){
		return this._mappings.hasOwnProperty( key );
	},

	/**
	 * When asked for an instance of the class whenAskedFor or for object whenAskedFor inject a new instance of instantiateClass.
	 * @param {String} key
	 * @param {Class} clazz
	 */
	mapClass : function( key, clazz ){
		this._mappings[ key ]= {
				clazz : clazz,
				object : null,
				isSingleton : false
        }
	},

    /**
     * When asked for an instance of the class whenAskedFor or object whenAskedFor inject an instance of useSingletonOf.
     * @param {String} key
     * @param {Class} clazz
     */
    mapSingleton : function( key, clazz ){
        this._mappings[ key ] = {
            clazz : clazz,
            object : null,
            isSingleton : true
        }
    },

	/**
	 * create an instance of the class mapped to keyOrClass and fulfill it's mapped dependencies

	 * WILL ALWAYS CREATE A NEW INSTANCE, even if keyOrClass was mapped otherwise or
	 * even when keyOrClass was not mapped.
	 * @param {Class} keyOrClass
	 * @return {Object}
	 */
	instantiate : function( key ){
		return this._retrieveFromCacheOrCreate( key, true );
	},

	/**
	 * Perform an injection into an object, satisfying all it's dependencies
	 * @param {Object} instance
	 */
	injectInto : function( key, instance ){
        var o = [ this._outlets[ 'global' ] ];
        if( this._outlets.hasOwnProperty( key ) ) o.push( this._outlets[ key ] );
        for( var i in o ){
            var l = o [ i ];
            for( var outlet in l ){
                var source = l[ outlet ];
                //must be "in" [!]
                if( ! this.strictInjections || outlet in instance ) instance[ outlet ] = this.getInstance( source );
            }
        }

        return instance;
	},

	/**
	 * Remove a rule from the System
	 * @param {String} key
	 */
	unmap : function( key ){
		delete this._mappings[ key ];
	},

	/**
	 * removes an injection point mapping for a given class mapped to key
	 * @param {Object} key
	 * @param {String} propertyName MUST BE STRING
	 * @see dijon.System#addOutlet
	 */
	removeOutlet : function( target, outlet ){
		delete this._outlets[ target ][ outlet ];
	}

};//dijon.System.prototype

<commit_msg>added notifications to sysmte<commit_after>/**
 * @author Camille Reynders
 * @version 0.2.0
 * @namespace
 */
var dijon = {
	/**
	 * framework version number
	 * @constant
	 * @type String
	 */
	VERSION : '0.5.0'
};//dijon

  //======================================//
 // dijon.System
//======================================//

/**
 * @class dijon.System
 * @constructor
*/
dijon.System = function(){
	/** @private */
	this._mappings = {};

	/** @private */
	this._outlets = {};

    /** @private */
    this._handlers = {};

    this.strictInjections = true;
};//dijon.System

dijon.System.prototype = {

	/**
	 * @private
	 * @param {Class} clazz
	 */
	_createAndSetupInstance : function( key, clazz ){
		var instance = new clazz();
		this.injectInto( key, instance );
		if( "setup" in instance ) instance.setup.call( instance );
		return instance;
	},

	/**
	 * @private
	 * @param {String} key
	 * @param {Boolean} overrideRules
	 * @return {Object}
	 */
	_retrieveFromCacheOrCreate : function( key, overrideRules ){
        if( overrideRules == undefined ) overrideRules = false;
        if( this._mappings.hasOwnProperty( key ) ){
            var config = this._mappings[ key ];
            var output = null;
            if( !overrideRules && config.isSingleton ){
                if( config.object == null  ){
                    config.object = this._createAndSetupInstance( key, config.clazz );
                }
                output = config.object;
            }else{
                if( config.clazz ) output = this._createAndSetupInstance( key, config.clazz );
            }
        }else{
            throw new Error( this.fqn + " is missing a rule for " + key );
        }
		return output
	},

	/**
	 * defines propertyName as an injection point for the class mapped to targetKey to be injected with an instance
	 * of the class mapped to sourceKey.
	 * @param {String} target the class the injection point is applied to.
	 * @param {String} outlet the name of the property used as an injection point.

	 * [!] MUST BE STRING
	 * @param {String} source the key to the value that will be injected
     * @see dijon.System#removeOutlet
	 */
	addOutlet : function( source, target, outlet ){
        if( target == undefined ) target = "global";
        if( outlet == undefined ) outlet = source;
        if( ! this._outlets.hasOwnProperty( target ) ) this._outlets[ target ] = {};
		this._outlets[ target ][ outlet ] = source
	},

	/**
	 * Create (if possible) or retrieve an instance of the class mapped to key
	 * @param {Object} key
	 * @return {Object}
	 */
	getInstance : function( key ){
		return this._retrieveFromCacheOrCreate( key );
	},

	/**
	 * When asked for an instance of the class whenAskedFor or object whenAskedFor inject the instance useValue.
	 * @param {String} key
	 * @param {Object} useValue
	 */
	mapValue : function( key, useValue ){
		this._mappings[ key ]= {
            clazz : null,
            object : useValue,
            isSingleton : true
		}
	},

	/**
	 * Does a rule exist to satsify such a request?
	 * @param {String} key
	 * @return {Boolean}
	 */
	hasMapping : function( key ){
		return this._mappings.hasOwnProperty( key );
	},

	/**
	 * When asked for an instance of the class whenAskedFor or for object whenAskedFor inject a new instance of instantiateClass.
	 * @param {String} key
	 * @param {Class} clazz
	 */
	mapClass : function( key, clazz ){
		this._mappings[ key ]= {
				clazz : clazz,
				object : null,
				isSingleton : false
        }
	},

    /**
     * When asked for an instance of the class whenAskedFor or object whenAskedFor inject an instance of useSingletonOf.
     * @param {String} key
     * @param {Class} clazz
     */
    mapSingleton : function( key, clazz ){
        this._mappings[ key ] = {
            clazz : clazz,
            object : null,
            isSingleton : true
        }
    },

	/**
	 * create an instance of the class mapped to keyOrClass and fulfill it's mapped dependencies

	 * WILL ALWAYS CREATE A NEW INSTANCE, even if keyOrClass was mapped otherwise or
	 * even when keyOrClass was not mapped.
	 * @param {Class} keyOrClass
	 * @return {Object}
	 */
	instantiate : function( key ){
		return this._retrieveFromCacheOrCreate( key, true );
	},

	/**
	 * Perform an injection into an object, satisfying all it's dependencies
	 * @param {Object} instance
	 */
	injectInto : function( key, instance ){
        var o = [ this._outlets[ 'global' ] ];
        if( this._outlets.hasOwnProperty( key ) ) o.push( this._outlets[ key ] );
        for( var i in o ){
            var l = o [ i ];
            for( var outlet in l ){
                var source = l[ outlet ];
                //must be "in" [!]
                if( ! this.strictInjections || outlet in instance ) instance[ outlet ] = this.getInstance( source );
            }
        }

        return instance;
	},

	/**
	 * Remove a rule from the System
	 * @param {String} key
	 */
	unmap : function( key ){
		delete this._mappings[ key ];
	},

	/**
	 * removes an injection point mapping for a given class mapped to key
	 * @param {Object} key
	 * @param {String} propertyName MUST BE STRING
	 * @see dijon.System#addOutlet
	 */
	removeOutlet : function( target, outlet ){
		delete this._outlets[ target ][ outlet ];
	},

    /**
     *
     * @param {String} key
     * @param {String} eventName
     * @param {String|Function} [handler=eventName]
     */
    addHandler : function( key, eventName, handler, oneShot ){
        if( handler == undefined ) handler = eventName;
        if( oneShot == undefined ) oneShot = false;
        if( ! this._handlers.hasOwnProperty( eventName ) ){
            this._handlers[ eventName ] = {};
        }
        this._handlers[ eventName ][ key ] = {
            handler : handler,
            oneShot: oneShot
        };
    },

    /**
     *
     * @param {String} key
     * @param {String} eventName
     */
    removeHandler : function( key, eventName ){
        if( this._handlers.hasOwnProperty( eventName ) && this._handlers[ eventName ].hasOwnProperty( key ) ){
            delete this._handlers[ eventName ][ key ];
        }
    },

    /**
     *
     * @param {String} eventName
     */
    notify : function( eventName ){
        var args = Array.prototype.slice( arguments );
        if( this._handlers.hasOwnProperty( eventName ) ){
            var handlers = this._handlers[ eventName ];
            for( var key in handlers ){
                var config = handlers[ key ];
                var instance = this.getInstance( key );
                var handler;
                if( typeof handler == "string" ){
                    handler = instance[ config.handler ];
                }else{
                    handler = config.handler;
                }
                if( config.oneShot ) this.removeHandler( key, eventName );
                handler.apply( instance, args );
            }
        }
    }

};//dijon.System.prototype

/*
    system.addHandler( 'userController', 'loginStart' );
    system.notify( 'loginStart' );
 */
<|endoftext|>


<commit_before>"use strict";

// require("../node_modules/bootstrap/dist/css/bootstrap.css");
// require("../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker.css");
// require("../node_modules/font-awesome/css/font-awesome.css");
// require("./main.css");

import React from "react"
import ReactDOM from "react-dom"

import { Provider } from "react-redux";
import Form, { fields } from "./containers/form";
import { store } from "./reducers/index";
import { calculate } from "./actions/result";

class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Form fields={fields} onSubmit={ values => store.dispatch(calculate(values.bills, values.people)) } />
      </Provider>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById("app")
);<commit_msg>Bring back main.css<commit_after>"use strict";

// require("../node_modules/bootstrap/dist/css/bootstrap.css");
// require("../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker.css");
// require("../node_modules/font-awesome/css/font-awesome.css");
require("./main.css");

import React from "react"
import ReactDOM from "react-dom"

import { Provider } from "react-redux";
import Form, { fields } from "./containers/form";
import { store } from "./reducers/index";
import { calculate } from "./actions/result";

class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <Form fields={fields} onSubmit={ values => store.dispatch(calculate(values.bills, values.people)) } />
      </Provider>
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById("app")
);<|endoftext|>


<commit_before>/**
 * Event
 *
 * @author Rakume Hayashi<i@fake.moe>
 */

Faiash.ise.extend({
    bind: function() {
        var args = $.toArr(arguments);

        if (typeof args[0] === 'string') {
            this.each(function(el) {
                el.addEventListener(args[0], args[1], args[2]);
            });
        } else if (typeof args[0] === 'object') {
            Faiash.each(args, function(obj) {
                this.each(function(el) {
                    for (var event in obj) {
                        if (object.hasOwnProperty(event)) {
                            el.addEventListener(event, obj[event][1]);
                        }
                    }
                });
            });
        }
    },

    unbind: function() {
        var args = $.toArr(arguments);

        if (typeof args[0] === 'string') {
            this.each(function(el) {
                el.removeEventListener(args[0], args[1], args[2]);
            });
        }  else if (typeof args[0] === 'object' && args.length === 1) {
            Faiash.each(args, function(obj) {
                this.each(function(el) {
                    for (var event in obj) {
                        if (object.hasOwnProperty(event)) {
                            el.removeEventListener(event, obj[event][1]);
                        }
                    }
                });
            });
        }
    }
});
<commit_msg>Prevent the abort when no arguments<commit_after>/**
 * Event
 *
 * @author Rakume Hayashi<i@fake.moe>
 */

Faiash.ise.extend({
    bind: function() {
        var args = $.toArr(arguments);

        if (typeof args[0] === 'string') {
            if (!args[0] || !args[1]) {
                return this;
            }

            this.each(function(el) {
                el.addEventListener(args[0], args[1], (args[2] ? args[2] : false));
            });
        } else if (typeof args[0] === 'object') {
            Faiash.each(args, function(obj) {
                this.each(function(el) {
                    for (var event in obj) {
                        if (object.hasOwnProperty(event)) {
                            el.addEventListener(event, obj[event][1]);
                        }
                    }
                });
            });
        }
    },

    unbind: function() {
        var args = $.toArr(arguments);

        if (typeof args[0] === 'string') {
            this.each(function(el) {
                el.removeEventListener(args[0], args[1], args[2]);
            });
        }  else if (typeof args[0] === 'object' && args.length === 1) {
            Faiash.each(args, function(obj) {
                this.each(function(el) {
                    for (var event in obj) {
                        if (object.hasOwnProperty(event)) {
                            el.removeEventListener(event, obj[event][1]);
                        }
                    }
                });
            });
        }
    }
});
<|endoftext|>


<commit_before>'use strict';

const appRoot = require('app-root-path')
const fs = require('fs')
const rx = require('rx')
const Tail = require('tail').Tail
const ipcRenderer = require('electron').ipcRenderer

const drawSVGFile = (drawing, path) =>
  fs.readFile(path, 'utf8', (err, data) => drawing.svg(data))

const adjust = (drawing) => (opacity, channel) =>
  drawing.select('.channel' + channel).style('opacity', opacity)

const makeTailerStream = (targetLog) =>
  rx.Observable.fromEvent(new Tail(targetLog), 'line')

const setupGraph = (drawing, tailerStream) =>
  tailerStream
    .map(line => line.split(' '))
    .map(splitLine => splitLine.map(num => parseInt(num, 16) / 256))
    .tap(opacityValues => console.log(opacityValues))
    .subscribe(opacityValues => opacityValues.forEach(adjust(drawing)))

const main = () => {
  const drawing = SVG('main').size(400, 200)
  drawSVGFile(drawing, appRoot + '/images/example1.svg')

  ipcRenderer.on('targetLog', (e, targetLog) =>
    setupGraph(drawing, makeTailerStream(targetLog)))
}

main()
<commit_msg>Added lineParser()<commit_after>'use strict';

const appRoot = require('app-root-path')
const fs = require('fs')
const rx = require('rx')
const Tail = require('tail').Tail
const ipcRenderer = require('electron').ipcRenderer

const drawSVGFile = (drawing, path) =>
  fs.readFile(path, 'utf8', (err, data) => drawing.svg(data))

const adjust = (drawing) => (opacity, channel) =>
  drawing.select('.channel' + channel).style('opacity', opacity)

const makeTailerStream = (targetLog) =>
  rx.Observable
    .fromEvent(new Tail(targetLog), 'line')
    .throttle(20) // milliseconds

const lineParser = (slice, radix, denominator) => (line) =>
  line.slice(slice).split(' ').map(num => parseInt(num, radix) / denominator)
const parseLineVixen = lineParser(30, 16, 256)
const parseLineSimple = lineParser(0, 10, 100)

const setupGraph = (drawing, tailerStream) =>
  tailerStream
    .map(parseLineSimple)
    .tap(opacityValues => console.log(opacityValues))
    .subscribe(opacityValues => opacityValues.forEach(adjust(drawing)))

const main = () => {
  const drawing = SVG('main').size(400, 200)
  drawSVGFile(drawing, appRoot + '/images/example1.svg')

  ipcRenderer.on('targetLog', (e, targetLog) =>
    setupGraph(drawing, makeTailerStream(targetLog)))
}

main()
<|endoftext|>


<commit_before>import React, { Component } from 'react'

import {
  StyleSheet,
  Text,
  View,
  Animated,
  PanResponder,
} from 'react-native'

const clamp = (value, min, max) => Math.max(Math.min(min, value), max)

const SWIPE_THRESHOLD = 120

class SwipableCards extends Component {
  constructor(props) {
    super(props)

    this.state = {
      pan: new Animated.ValueXY(),
      enter: new Animated.Value(0.5),
      card: this.props.cards[0],
      currentCardIdx: 0,
    }
  }

  log = (...args) => {
    this.props.logger(...args)
  }

  _goToNextCard() {
    let newIdx = this.state.currentCardIdx + 1

    // Checks to see if last card.
    // If props.loop=true, will start again from the first card.
    newIdx = newIdx > this.props.cards.length - 1
      ? this.props.loop ? 0 : -1
      : newIdx

    this.setState({
      card: this.props.cards[newIdx],
      currentCardIdx: newIdx,
    })
  }

  componentDidMount() {
    this._animateEntrance()
  }

  _animateEntrance() {
    Animated.spring(
      this.state.enter,
      { toValue: 1, friction: 8 }
    ).start()
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.cards && nextProps.cards.length > 0) {
      this.setState({
        card: nextProps.cards[0],
        currentCardIdx: 0,
      })
    }
  }

  componentWillMount() {
    const onPanResponderMove = this.props.onlyHorizontal ?
      Animated.event([ null, {dx: this.state.pan.x} ]) :
      Animated.event([ null, {dx: this.state.pan.x, dy: this.state.pan.y} ])

    this._panResponder = PanResponder.create({
      onResponderTerminationRequest: () => false,
      onShouldBlockNativeResponder: () => true,
      onMoveShouldSetPanResponder: (evt, { dx }) => Math.abs(dx) > 5,

      onPanResponderTerminate: () => {
        this._backToDeck()
      },

      onPanResponderGrant: () => {
        this.state.pan.setOffset({x: this.state.pan.x._value, y: this.state.pan.y._value})
        this.state.pan.setValue({x: 0, y: 0})
      },

      onPanResponderMove,

      onPanResponderRelease: (e, {vx, vy}) => {
        this.state.pan.flattenOffset()
        let velocity

        if (vx >= 0) {
          velocity = clamp(vx, 3, 5)
        } else if (vx < 0) {
          velocity = clamp(vx * -1, 3, 5) * -1
        }

        const regret = vx * this.state.pan.x._value < 0
        if (Math.abs(this.state.pan.x._value) > SWIPE_THRESHOLD && !regret) {
          this.state.pan.x._value > 0
            ? this.props.handleYup(this.state.card)
            : this.props.handleNope(this.state.card)

          this.props.onCardRemoved(this.props.cards.indexOf(this.state.card))

          Animated.timing(this.state.pan, {
            toValue: { x: velocity * 200, y: vy * 200},
            duration: 200,
          }).start(this._resetState)
        } else {
          this._backToDeck()
        }
      }
    })
  }

  _backToDeck = () => {
    Animated.spring(this.state.pan, {
      toValue: {x: 0, y: 0},
      friction: 4,
    }).start()
  }

  _resetState = () => {
    this.state.pan.setValue({x: 0, y: 0})
    this.state.enter.setValue(0)
    this._goToNextCard()
    this._animateEntrance()
  }

  renderNoMoreCards() {
    return this.props.renderNoMoreCards()
  }

  renderFirstCard(card) {
    const { pan, enter } = this.state

    const [translateX, translateY] = [pan.x, pan.y]

    const rotate = pan.x.interpolate({inputRange: [-200, 0, 200], outputRange: ['-30deg', '0deg', '30deg']})
    const scale = !this.props.stack
      ? enter : this.state.enter.interpolate({inputRange: [0, 1], outputRange: [card.lastScale || 1, 1]})

    const animatedCardstyles = {transform: [{translateX}, {translateY}, {rotate}, {scale} ]}

    if (this.props.fadeOnSwipe) {
      animatedCardstyles.opacity = pan.x.interpolate({inputRange: [-200, 0, 200], outputRange: [0.5, 1, 0.5]})
    }

    return (
      <Animated.View
        key={+new Date() + Math.random()}
        style={[this.props.cardStyle, animatedCardstyles ]}
        {...this._panResponder.panHandlers}
      >
        {this.props.renderCard(card)}
      </Animated.View>
    )
  }

  renderStackCard(card, style) {
    return (
      <Animated.View
        key={+new Date() + Math.random()}
        style={[this.props.cardStyle, style]}
      >
        {this.props.renderCard(card)}
      </Animated.View>
    )
  }

  renderStack() {
    let { currentCardIdx } = this.state
    let cards = this.props.cards.slice(currentCardIdx, currentCardIdx + this.props.stackDepth).reverse()

    return cards.map((card, i) => {
      if (i + 1 === cards.length) {
        return this.renderFirstCard(card)
      }

      let offsetX = this.props.stackOffsetX * (cards.length - i)
      let lastOffsetX = offsetX + this.props.stackOffsetX

      let offsetY = this.props.stackOffsetY * (cards.length - i)
      let lastOffsetY = offsetY + this.props.stackOffsetY

      let style = {
        position: 'absolute',
        top: this.state.enter.interpolate({inputRange: [0, 1], outputRange: [lastOffsetY, offsetY]}),
        left: this.state.enter.interpolate({inputRange: [0, 1], outputRange: [lastOffsetX, offsetX]}),
        elevation: i * 10
      }

      return this.renderStackCard(card, style)
    })
  }

  render() {
    let { pan } = this.state

    let yupOpacity = pan.x.interpolate({inputRange: [0, 150], outputRange: [0, 1]})
    let yupScale = pan.x.interpolate({inputRange: [0, 150], outputRange: [0.5, 1], extrapolate: 'clamp'})
    let animatedYupStyles = {transform: [{scale: yupScale}], opacity: yupOpacity}

    let nopeOpacity = pan.x.interpolate({inputRange: [-150, 0], outputRange: [1, 0]})
    let nopeScale = pan.x.interpolate({inputRange: [-150, 0], outputRange: [1, 0.5], extrapolate: 'clamp'})
    let animatedNopeStyles = {transform: [{scale: nopeScale}], opacity: nopeOpacity}

    return (
      <View style={this.props.containerStyle}>
        { this.state.card
          ? (this.props.stack ? this.renderStack() : this.renderFirstCard(this.state.card))
            : this.renderNoMoreCards() }

          { this.props.renderNope
            ? this.props.renderNope(pan)
            : (
                this.props.showNope
                ? (
                  <Animated.View style={[this.props.nopeStyle, animatedNopeStyles]}>
                      {this.props.nopeView
                          ? this.props.nopeView
                          : <Text style={this.props.nopeTextStyle}>{this.props.nopeText}</Text>
                      }
                  </Animated.View>
                  )
                : null
              )
          }

          { this.props.renderYup
            ? this.props.renderYup(pan)
            : (
                this.props.showYup
                ? (
                  <Animated.View style={[this.props.yupStyle, animatedYupStyles]}>
                    {this.props.yupView
                      ? this.props.yupView
                      : <Text style={this.props.yupTextStyle}>{this.props.yupText}</Text>
                    }
                  </Animated.View>
                )
                : null
              )
          }
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF'
  },
  yup: {
    borderColor: 'green',
    borderWidth: 2,
    position: 'absolute',
    padding: 20,
    bottom: 20,
    borderRadius: 5,
    right: 20,
  },
  yupText: {
    fontSize: 16,
    color: 'green',
  },
  nope: {
    borderColor: 'red',
    borderWidth: 2,
    position: 'absolute',
    bottom: 20,
    padding: 20,
    borderRadius: 5,
    left: 20,
  },
  nopeText: {
    fontSize: 16,
    color: 'red',
  }
})

SwipableCards.propTypes = {
  cards: React.PropTypes.array,
  loop: React.PropTypes.bool,
  onlyHorizontal: React.PropTypes.bool,
  stack: React.PropTypes.bool,
  showYup: React.PropTypes.bool,
  showNope: React.PropTypes.bool,
  yupView: React.PropTypes.element,
  yupText: React.PropTypes.string,
  nopeView: React.PropTypes.element,
  nopeText: React.PropTypes.string,
  containerStyle: View.propTypes.style,
  cardStyle: View.propTypes.style,
  yupStyle: View.propTypes.style,
  yupTextStyle: Text.propTypes.style,
  nopeStyle: View.propTypes.style,
  nopeTextStyle: Text.propTypes.style,
  stackDepth: React.PropTypes.number,
  stackOffsetX: React.PropTypes.number,
  stackOffsetY: React.PropTypes.number,
  fadeOnSwipe: React.PropTypes.bool,
  handleYup: React.PropTypes.func,
  handleNope: React.PropTypes.func,
  onCardRemoved: React.PropTypes.func,
  renderCard: React.PropTypes.func,
  renderYup: React.PropTypes.func,
  renderNope: React.PropTypes.func,
  renderNoMoreCards: React.PropTypes.func,
  logger: React.PropTypes.func,
}

SwipableCards.defaultProps = {
  cards: [],
  loop: false,
  onlyHorizontal: false,
  showYup: true,
  showNope: true,
  containerStyle: styles.container,
  yupStyle: styles.yup,
  yupText: 'Yup!',
  yupTextStyle: styles.yupText,
  nopeStyle: styles.nope,
  nopeText: 'Nope!',
  nopeTextStyle: styles.nopeText,
  stack: true,
  stackDepth: 2,
  stackOffsetX: 0,
  stackOffsetY: 0,
  fadeOnSwipe: false,
  renderNoMoreCards: () => <View />,
  onCardRemoved: () => null,
  logger: () => null,
}

export default SwipableCards
<commit_msg>Avoid unnecessary re-renders<commit_after>import React, { Component } from 'react'

import {
  StyleSheet,
  Text,
  View,
  Animated,
  PanResponder,
} from 'react-native'

const clamp = (value, min, max) => Math.max(Math.min(min, value), max)

const SWIPE_THRESHOLD = 120

class SwipableCards extends Component {
  constructor(props) {
    super(props)

    this.state = {
      pan: new Animated.ValueXY(),
      enter: new Animated.Value(0.5),
      card: this.props.cards[0],
      currentCardIdx: 0,
    }
  }

  log = (...args) => {
    this.props.logger(...args)
  }

  _goToNextCard() {
    let newIdx = this.state.currentCardIdx + 1

    // Checks to see if last card.
    // If props.loop=true, will start again from the first card.
    newIdx = newIdx > this.props.cards.length - 1
      ? this.props.loop ? 0 : -1
      : newIdx

    this.setState({
      card: this.props.cards[newIdx],
      currentCardIdx: newIdx,
    })
  }

  componentDidMount() {
    this._animateEntrance()
  }

  _animateEntrance() {
    Animated.spring(
      this.state.enter,
      { toValue: 1, friction: 8 }
    ).start()
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.cards && nextProps.cards.length > 0) {
      this.setState({
        card: nextProps.cards[0],
        currentCardIdx: 0,
      })
    }
  }

  componentWillMount() {
    const onPanResponderMove = this.props.onlyHorizontal ?
      Animated.event([ null, {dx: this.state.pan.x} ]) :
      Animated.event([ null, {dx: this.state.pan.x, dy: this.state.pan.y} ])

    this._panResponder = PanResponder.create({
      onResponderTerminationRequest: () => false,
      onShouldBlockNativeResponder: () => true,
      onMoveShouldSetPanResponder: (evt, { dx }) => Math.abs(dx) > 5,

      onPanResponderTerminate: () => {
        this._backToDeck()
      },

      onPanResponderGrant: () => {
        this.state.pan.setOffset({x: this.state.pan.x._value, y: this.state.pan.y._value})
        this.state.pan.setValue({x: 0, y: 0})
      },

      onPanResponderMove,

      onPanResponderRelease: (e, {vx, vy}) => {
        this.state.pan.flattenOffset()
        let velocity

        if (vx >= 0) {
          velocity = clamp(vx, 3, 5)
        } else if (vx < 0) {
          velocity = clamp(vx * -1, 3, 5) * -1
        }

        const regret = vx * this.state.pan.x._value < 0
        if (Math.abs(this.state.pan.x._value) > SWIPE_THRESHOLD && !regret) {
          this.state.pan.x._value > 0
            ? this.props.handleYup(this.state.card)
            : this.props.handleNope(this.state.card)

          this.props.onCardRemoved(this.props.cards.indexOf(this.state.card))

          Animated.timing(this.state.pan, {
            toValue: { x: velocity * 200, y: vy * 200},
            duration: 200,
          }).start(this._resetState)
        } else {
          this._backToDeck()
        }
      }
    })
  }

  _backToDeck = () => {
    Animated.spring(this.state.pan, {
      toValue: {x: 0, y: 0},
      friction: 4,
    }).start()
  }

  _resetState = () => {
    this.state.pan.setValue({x: 0, y: 0})
    this.state.enter.setValue(0)
    this._goToNextCard()
    this._animateEntrance()
  }

  renderNoMoreCards() {
    return this.props.renderNoMoreCards()
  }

  renderFirstCard(card, cardIndex) {
    const { pan, enter } = this.state

    const [translateX, translateY] = [pan.x, pan.y]

    const rotate = pan.x.interpolate({inputRange: [-200, 0, 200], outputRange: ['-30deg', '0deg', '30deg']})
    const scale = !this.props.stack
      ? enter : this.state.enter.interpolate({inputRange: [0, 1], outputRange: [card.lastScale || 1, 1]})

    const animatedCardstyles = {transform: [{translateX}, {translateY}, {rotate}, {scale} ]}

    if (this.props.fadeOnSwipe) {
      animatedCardstyles.opacity = pan.x.interpolate({inputRange: [-200, 0, 200], outputRange: [0.5, 1, 0.5]})
    }

    return (
      <Animated.View
        key={cardIndex}
        style={[this.props.cardStyle, animatedCardstyles ]}
        {...this._panResponder.panHandlers}
      >
        {this.props.renderCard(card)}
      </Animated.View>
    )
  }

  renderStackCard(card, style, cardIndex) {
    return (
      <Animated.View
        key={cardIndex}
        style={[this.props.cardStyle, style]}
      >
        {this.props.renderCard(card)}
      </Animated.View>
    )
  }

  renderStack() {
    const { currentCardIdx } = this.state
    const { cards, stackDepth } = this.props

    return Array(stackDepth).fill().map((_, i) => {
      // Render last card first
      const cardIndex = currentCardIdx + (stackDepth - 1) - i
      const card = cards[cardIndex]

      if (cardIndex === currentCardIdx) {
        return card && this.renderFirstCard(card, cardIndex)
      }

      let offsetX = this.props.stackOffsetX * (cards.length - i)
      let lastOffsetX = offsetX + this.props.stackOffsetX

      let offsetY = this.props.stackOffsetY * (cards.length - i)
      let lastOffsetY = offsetY + this.props.stackOffsetY

      let style = {
        position: 'absolute',
        top: this.state.enter.interpolate({inputRange: [0, 1], outputRange: [lastOffsetY, offsetY]}),
        left: this.state.enter.interpolate({inputRange: [0, 1], outputRange: [lastOffsetX, offsetX]}),
        elevation: i * 10
      }

      return card && this.renderStackCard(card, style, cardIndex)
    })
  }

  render() {
    let { pan } = this.state

    let yupOpacity = pan.x.interpolate({inputRange: [0, 150], outputRange: [0, 1]})
    let yupScale = pan.x.interpolate({inputRange: [0, 150], outputRange: [0.5, 1], extrapolate: 'clamp'})
    let animatedYupStyles = {transform: [{scale: yupScale}], opacity: yupOpacity}

    let nopeOpacity = pan.x.interpolate({inputRange: [-150, 0], outputRange: [1, 0]})
    let nopeScale = pan.x.interpolate({inputRange: [-150, 0], outputRange: [1, 0.5], extrapolate: 'clamp'})
    let animatedNopeStyles = {transform: [{scale: nopeScale}], opacity: nopeOpacity}

    return (
      <View style={this.props.containerStyle}>
        { this.state.card ? this.renderStack() : this.renderNoMoreCards() }

          { this.props.renderNope
            ? this.props.renderNope(pan)
            : (
                this.props.showNope
                ? (
                  <Animated.View style={[this.props.nopeStyle, animatedNopeStyles]}>
                      {this.props.nopeView
                          ? this.props.nopeView
                          : <Text style={this.props.nopeTextStyle}>{this.props.nopeText}</Text>
                      }
                  </Animated.View>
                  )
                : null
              )
          }

          { this.props.renderYup
            ? this.props.renderYup(pan)
            : (
                this.props.showYup
                ? (
                  <Animated.View style={[this.props.yupStyle, animatedYupStyles]}>
                    {this.props.yupView
                      ? this.props.yupView
                      : <Text style={this.props.yupTextStyle}>{this.props.yupText}</Text>
                    }
                  </Animated.View>
                )
                : null
              )
          }
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  yup: {
    borderColor: 'green',
    borderWidth: 2,
    position: 'absolute',
    padding: 20,
    bottom: 20,
    borderRadius: 5,
    right: 20,
  },
  yupText: {
    fontSize: 16,
    color: 'green',
  },
  nope: {
    borderColor: 'red',
    borderWidth: 2,
    position: 'absolute',
    bottom: 20,
    padding: 20,
    borderRadius: 5,
    left: 20,
  },
  nopeText: {
    fontSize: 16,
    color: 'red',
  }
})

SwipableCards.propTypes = {
  cards: React.PropTypes.array,
  loop: React.PropTypes.bool,
  onlyHorizontal: React.PropTypes.bool,
  stack: React.PropTypes.bool,
  showYup: React.PropTypes.bool,
  showNope: React.PropTypes.bool,
  yupView: React.PropTypes.element,
  yupText: React.PropTypes.string,
  nopeView: React.PropTypes.element,
  nopeText: React.PropTypes.string,
  containerStyle: View.propTypes.style,
  cardStyle: View.propTypes.style,
  yupStyle: View.propTypes.style,
  yupTextStyle: Text.propTypes.style,
  nopeStyle: View.propTypes.style,
  nopeTextStyle: Text.propTypes.style,
  stackDepth: React.PropTypes.number,
  stackOffsetX: React.PropTypes.number,
  stackOffsetY: React.PropTypes.number,
  fadeOnSwipe: React.PropTypes.bool,
  handleYup: React.PropTypes.func,
  handleNope: React.PropTypes.func,
  onCardRemoved: React.PropTypes.func,
  renderCard: React.PropTypes.func,
  renderYup: React.PropTypes.func,
  renderNope: React.PropTypes.func,
  renderNoMoreCards: React.PropTypes.func,
  logger: React.PropTypes.func,
}

SwipableCards.defaultProps = {
  cards: [],
  loop: false,
  onlyHorizontal: false,
  showYup: true,
  showNope: true,
  containerStyle: styles.container,
  yupStyle: styles.yup,
  yupText: 'Yup!',
  yupTextStyle: styles.yupText,
  nopeStyle: styles.nope,
  nopeText: 'Nope!',
  nopeTextStyle: styles.nopeText,
  stack: true,
  stackDepth: 2,
  stackOffsetX: 0,
  stackOffsetY: 0,
  fadeOnSwipe: false,
  renderNoMoreCards: () => <View />,
  onCardRemoved: () => null,
  logger: () => null,
}

export default SwipableCards
<|endoftext|>


<commit_before>import React from 'react'
import {Modal} from 'react-bootstrap'

/**
 * The modal dialog which can be altenative to `window.confirm` and `window.alert`.
 * @example <Dialog ref={(el) => {this.dialog = el} />
 * @example this.dialog.show({body: 'Hello!', actions: [Dialog.Action('do', () => console.log('ok'))]})
 * @example this.dialog.showAlert('Hello!')
 */
class Dialog extends React.Component {
  /**
   * Set default options for applying to all dialogs.
   * @param options
   */
  static setOptions (options) {
    Dialog.options = Object.assign({}, Dialog.DEFAULT_OPTIONS, options)
  }

  /**
   * Reset default options to presets.
   */
  static resetOptions () {
    Dialog.options = Dialog.DEFAULT_OPTIONS
  }

  constructor (props) {
    super(props)
    this.state = {
      showModal: false,
      actions: [],
      bsSize: undefined,
      onHide: null
    }
    this.onHide = this.onHide.bind(this)
  }

  componentWillUnmount () {
    if (this.state.showModal) {
      this.hide()
    }
  }

  /**
   * Show dialog with choices. This is similar to `window.confirm`.
   * @param options Object for dialog options.
   * @param options.title The title of dialog.
   * @param options.body The body of message.
   * @param options.actions {DialogAction} The choices for presenting to user.
   * @param options.bsSize {[null, 'medium', 'large', 'small']} The width size for dialog.
   * @param options.onHide {function} The method to call when the dialog was closed by clicking background.
   */
  show (options = {}) {
    let keyBinds = {}
    let actions = options.actions || []
    actions.forEach((action) => {
      if (action.key) {
        action.key.split(',').forEach((key) => {
          keyBinds[key] = () => { action.func && action.func(this) }
        })
      }
    })
    // TODO: Add keybinds
    options['showModal'] = true
    this.setState(options)
  }

  /**
   * Show message dialog This is similar to `window.alert`.
   * @param body The body of message.
   * @param bsSize {[null, 'medium', 'large', 'small']} The width size for dialog.
   */
  showAlert (body, bsSize = undefined) {
    const options = {
      body: body,
      actions: [
        Dialog.SingleOKAction()
      ],
      bsSize: bsSize
    }
    this.show(options)
  }

  onHide () {
    const onHide = this.state.onHide
    if (typeof onHide === 'function') {
      onHide(this)
    } else {
      this.hide()
    }
  }

  /**
   * Hide this dialog.
   */
  hide () {
    if (!this.state.showModal) return
    // TODO: Remove keybinds
    this.setState({showModal: false})
  }

  render () {
    const size = (typeof this.state.bsSize) === 'undefined' ? 'small' : (this.state.bsSize === 'medium' ? null : this.state.bsSize)
    return (
      <Modal show={this.state.showModal} onHide={this.onHide} bsSize={size}>
        {
          this.state.title && (
            <Modal.Header>
              <Modal.Title>
                {this.state.title}
              </Modal.Title>
            </Modal.Header>
          )
        }
        <Modal.Body>
          {
            typeof this.state.body === 'string'
              ? (
{this.state.body}
)
              : this.state.body
          }
        </Modal.Body>
        <Modal.Footer>
          {
            this.state.actions.map((action) => {
              return (
                <button
                  key={action.label}
                  type='button'
                  className={`btn btn-sm ${action.className}`}
                  onClick={() => { action.func && action.func(this) }}
                  style={{minWidth: 82}}>
                  {action.label}
                </button>
              )
            })
          }
        </Modal.Footer>
      </Modal>
    )
  }
}

/**
 * The class to construct a choice for Dialog.
 * Use `Dialog.Action(options)`.
 */
class DialogAction {
  /**
   * Constructor
   * @param label The text or node for button. Default is `OK`.
   * @param func The function to execute when button is clicked. Default is null.
   * @param className The class name for button. Default is ''.
   */
  constructor (label, func, className, key) {
    this.label = label || Dialog.options.defaultOkLabel
    this._func = func
    this.className = className || 'btn-default'
    this.key = key
  }

  func (dialog) {
    dialog.hide()
    this._func && this._func(dialog)
  }
}

Dialog.DEFAULT_OPTIONS = {
  defaultOkLabel: 'OK',
  defaultCancelLabel: 'Cancel',
  primaryClassName: 'btn-primary'
}

Dialog.options = Dialog.DEFAULT_OPTIONS

Dialog.Action = (label, func, className, key) => new DialogAction(label, func, className, key)
Dialog.DefaultAction = (label, func, className) => new DialogAction(label, func, className && className.length > 0 ? className : Dialog.options.primaryClassName, 'enter')
Dialog.OKAction = (func) => new DialogAction(Dialog.options.defaultOkLabel, (dialog) => { dialog.hide(); func && func(dialog) }, Dialog.options.primaryClassName, 'enter')
Dialog.CancelAction = (func) => new DialogAction(Dialog.options.defaultCancelLabel, (dialog) => { dialog.hide(); func && func(dialog) }, null, 'esc')
Dialog.SingleOKAction = () => new DialogAction(Dialog.options.defaultOkLabel, (dialog) => { dialog.hide() }, Dialog.options.primaryClassName, 'enter,esc')

Dialog.displayName = 'Dialog'
module.exports = Dialog
<commit_msg>Prevent pollution in each others<commit_after>import React from 'react'
import {Modal} from 'react-bootstrap'

/**
 * The modal dialog which can be altenative to `window.confirm` and `window.alert`.
 * @example <Dialog ref={(el) => {this.dialog = el} />
 * @example this.dialog.show({body: 'Hello!', actions: [Dialog.Action('do', () => console.log('ok'))]})
 * @example this.dialog.showAlert('Hello!')
 */
class Dialog extends React.Component {
  /**
   * Set default options for applying to all dialogs.
   * @param options
   */
  static setOptions (options) {
    Dialog.options = Object.assign({}, Dialog.DEFAULT_OPTIONS, options)
  }

  /**
   * Reset default options to presets.
   */
  static resetOptions () {
    Dialog.options = Dialog.DEFAULT_OPTIONS
  }

  static initialiState () {
    return {
      title: null,
      body: null,
      showModal: false,
      actions: [],
      bsSize: undefined,
      onHide: null
    }
  }

  constructor (props) {
    super(props)
    this.state = Dialog.initialiState()
    this.onHide = this.onHide.bind(this)
  }

  componentWillUnmount () {
    if (this.state.showModal) {
      this.hide()
    }
  }

  /**
   * Show dialog with choices. This is similar to `window.confirm`.
   * @param options Object for dialog options.
   * @param options.title The title of dialog.
   * @param options.body The body of message.
   * @param options.actions {DialogAction} The choices for presenting to user.
   * @param options.bsSize {[null, 'medium', 'large', 'small']} The width size for dialog.
   * @param options.onHide {function} The method to call when the dialog was closed by clicking background.
   */
  show (options = {}) {
    let keyBinds = {}
    let actions = options.actions || []
    actions.forEach((action) => {
      if (action.key) {
        action.key.split(',').forEach((key) => {
          keyBinds[key] = () => { action.func && action.func(this) }
        })
      }
    })
    // TODO: Add keybinds
    options['showModal'] = true
    this.setState(Dialog.initialiState())
    this.setState(options)
  }

  /**
   * Show message dialog This is similar to `window.alert`.
   * @param body The body of message.
   * @param bsSize {[null, 'medium', 'large', 'small']} The width size for dialog.
   */
  showAlert (body, bsSize = undefined) {
    const options = {
      body: body,
      actions: [
        Dialog.SingleOKAction()
      ],
      bsSize: bsSize
    }
    this.show(options)
  }

  onHide () {
    const onHide = this.state.onHide
    if (typeof onHide === 'function') {
      onHide(this)
    } else {
      this.hide()
    }
  }

  /**
   * Hide this dialog.
   */
  hide () {
    if (!this.state.showModal) return
    // TODO: Remove keybinds
    this.setState({showModal: false})
  }

  render () {
    const size = (typeof this.state.bsSize) === 'undefined' ? 'small' : (this.state.bsSize === 'medium' ? null : this.state.bsSize)
    return (
      <Modal show={this.state.showModal} onHide={this.onHide} bsSize={size}>
        {
          this.state.title && (
            <Modal.Header>
              <Modal.Title>
                {this.state.title}
              </Modal.Title>
            </Modal.Header>
          )
        }
        <Modal.Body>
          {
            typeof this.state.body === 'string'
              ? (
{this.state.body}
)
              : this.state.body
          }
        </Modal.Body>
        <Modal.Footer>
          {
            this.state.actions.map((action) => {
              return (
                <button
                  key={action.label}
                  type='button'
                  className={`btn btn-sm ${action.className}`}
                  onClick={() => { action.func && action.func(this) }}
                  style={{minWidth: 82}}>
                  {action.label}
                </button>
              )
            })
          }
        </Modal.Footer>
      </Modal>
    )
  }
}

/**
 * The class to construct a choice for Dialog.
 * Use `Dialog.Action(options)`.
 */
class DialogAction {
  /**
   * Constructor
   * @param label The text or node for button. Default is `OK`.
   * @param func The function to execute when button is clicked. Default is null.
   * @param className The class name for button. Default is ''.
   */
  constructor (label, func, className, key) {
    this.label = label || Dialog.options.defaultOkLabel
    this._func = func
    this.className = className || 'btn-default'
    this.key = key
  }

  func (dialog) {
    dialog.hide()
    this._func && this._func(dialog)
  }
}

Dialog.DEFAULT_OPTIONS = {
  defaultOkLabel: 'OK',
  defaultCancelLabel: 'Cancel',
  primaryClassName: 'btn-primary'
}

Dialog.options = Dialog.DEFAULT_OPTIONS

Dialog.Action = (label, func, className, key) => new DialogAction(label, func, className, key)
Dialog.DefaultAction = (label, func, className) => new DialogAction(label, func, className && className.length > 0 ? className : Dialog.options.primaryClassName, 'enter')
Dialog.OKAction = (func) => new DialogAction(Dialog.options.defaultOkLabel, (dialog) => { dialog.hide(); func && func(dialog) }, Dialog.options.primaryClassName, 'enter')
Dialog.CancelAction = (func) => new DialogAction(Dialog.options.defaultCancelLabel, (dialog) => { dialog.hide(); func && func(dialog) }, null, 'esc')
Dialog.SingleOKAction = () => new DialogAction(Dialog.options.defaultOkLabel, (dialog) => { dialog.hide() }, Dialog.options.primaryClassName, 'enter,esc')

Dialog.displayName = 'Dialog'
module.exports = Dialog
<|endoftext|>


<commit_before>#!/usr/bin/env node

const yargs = require('yargs');

// ./modules
const rocketLaunch = require('./modules/rocketLaunch');
const info = require('./modules/info');
const settings = require('./modules/settings');

const argv = yargs // eslint-disable-line
  .usage('Usage: space <command> [options]')
  .demandCommand(1)
  .command('about', 'Info about the CLI', info.about)
  .command('next', 'Get next rocket launch',
    function (yargs) {
      return yargs.option('d', {
        alias: 'details',
        describe: 'Details about the next launch'
      }).option('tz', {
        alias: 'timezone',
        describe: 'Define time zone for time info e.g. America/New_York, Europe/Paris, Asia/Shanghai'
      }).option('lt', {
        alias: 'limit',
        describe: 'Define amount of upcoming events to show'
      });
    },
    rocketLaunch.nextLaunch
  )
  .command('settings', 'Set default settings',
    function (yargs) {
      return yargs.option('tz', {
        alias: 'timezone',
        describe: 'Define default time zone for time info e.g. America/New_York, Europe/Paris, Asia/Shanghai'
      });
    },
    settings.update
  )
  .help('h')
  .alias('h', 'help')
  .argv;
<commit_msg>Change d to v, add verbose alias<commit_after>#!/usr/bin/env node

const yargs = require('yargs');

// ./modules
const rocketLaunch = require('./modules/rocketLaunch');
const info = require('./modules/info');
const settings = require('./modules/settings');

const argv = yargs // eslint-disable-line
  .usage('Usage: space <command> [options]')
  .demandCommand(1)
  .command('about', 'Info about the CLI', info.about)
  .command('next', 'Get next rocket launch',
    function (yargs) {
      return yargs
        .option('v', {
          alias: ['verbose', 'details'],
          describe: 'Details about the next launch'
        }).option('tz', {
          alias: 'timezone',
          describe: 'Define time zone for time info e.g. America/New_York, Europe/Paris, Asia/Shanghai'
        }).option('lt', {
          alias: 'limit',
          describe: 'Define amount of upcoming events to show'
        });
    },
    rocketLaunch.nextLaunch
  )
  .command('settings', 'Set default settings',
    function (yargs) {
      return yargs.option('tz', {
        alias: 'timezone',
        describe: 'Define default time zone for time info e.g. America/New_York, Europe/Paris, Asia/Shanghai'
      });
    },
    settings.update
  )
  .help('h')
  .alias('h', 'help')
  .argv;
<|endoftext|>


<commit_before>import GitHubApi from "github";
import _ from "lodash";

import auth from "../auth.json";

const github = new GitHubApi({
  protocol: "https",
  Promise,
  timeout: 5000,
});

github.authenticate({
  type: "oauth",
  token: auth.token,
});

const repo = {
  owner: "babel",
  repo: "babel",
};

const closedIssues = [];

function processPulls(pulls) {
  _.forEach(pulls, (pull) => {
    if (!pull.body) {
      return;
    }

    // eslint-disable-next-line max-len
    const regex = /Fixed tickets[\s]*\|[\s]*(?:https:\/\/github\.com\/babel\/babel\/issues\/(\d+)|(#\d+(?:\s*,\s*#\d+)*))/;
    const issues = pull.body.match(regex);
    if (issues <= 1) {
      return;
    }

    console.log(`Processing PR${pull.number}`);

    if (!pull.merged_at) {
      console.log("The pull request was not merged.");
      return;
    }

    // single issue
    if (issues[1]) {
      processIssue(issues[1]);
      return;
    }

    // multiple issues
    issues[2].replace(/\s|#/g, "")
      .split(",")
      .forEach(processIssue);
  });
}

async function processIssue(number) {
  console.log(`Processing issue #${number}`);
  if (closedIssues.includes(number)) {
    console.log("Issue was already processed.");
    return;
  }

  closedIssues.push(number);

  const issueParam = { ...repo, number };

  let issue;
  try {
    issue = await github.issues.get(issueParam);
    if (!issue) {
      console.log("Couldn't retrieve issue.");
      return;
    }
  } catch (err) {
    console.log(`Couldn't retrieve issue #${number}: ${err}`);
  }

  if (issue.state === "closed") {
    console.log(`Issue #${number} is already closed.`);
    return;
  }

  try {
    // close issue
    await github.issues.edit({ ...issueParam, state: "closed" });
  } catch (err) {
    console.log(`Error closing issue: ${err}`);
  }
}

async function pager(res) {
  let pulls = res;

  processPulls(pulls);

  while (github.hasNextPage(pulls)) {
    pulls = await github.getNextPage(pulls);
    if (!pulls) {
      break;
    }

    processPulls(pulls);
  }
}

github.pullRequests
  .getAll({
    ...repo,
    state: "closed",
    per_page: 99,
  })
  .then(pager)
  .catch((err) => console.log("Error: ", err));
<commit_msg>Add the issue number to the message when there's an error closing an issue<commit_after>import GitHubApi from "github";
import _ from "lodash";

import auth from "../auth.json";

const github = new GitHubApi({
  protocol: "https",
  Promise,
  timeout: 5000,
});

github.authenticate({
  type: "oauth",
  token: auth.token,
});

const repo = {
  owner: "babel",
  repo: "babel",
};

const closedIssues = [];

function processPulls(pulls) {
  _.forEach(pulls, (pull) => {
    if (!pull.body) {
      return;
    }

    // eslint-disable-next-line max-len
    const regex = /Fixed tickets[\s]*\|[\s]*(?:https:\/\/github\.com\/babel\/babel\/issues\/(\d+)|(#\d+(?:\s*,\s*#\d+)*))/;
    const issues = pull.body.match(regex);
    if (issues <= 1) {
      return;
    }

    console.log(`Processing PR${pull.number}`);

    if (!pull.merged_at) {
      console.log("The pull request was not merged.");
      return;
    }

    // single issue
    if (issues[1]) {
      processIssue(issues[1]);
      return;
    }

    // multiple issues
    issues[2].replace(/\s|#/g, "")
      .split(",")
      .forEach(processIssue);
  });
}

async function processIssue(number) {
  console.log(`Processing issue #${number}`);
  if (closedIssues.includes(number)) {
    console.log("Issue was already processed.");
    return;
  }

  closedIssues.push(number);

  const issueParam = { ...repo, number };

  let issue;
  try {
    issue = await github.issues.get(issueParam);
    if (!issue) {
      console.log("Couldn't retrieve issue.");
      return;
    }
  } catch (err) {
    console.log(`Couldn't retrieve issue #${number}: ${err}`);
  }

  if (issue.state === "closed") {
    console.log(`Issue #${number} is already closed.`);
    return;
  }

  try {
    // close issue
    await github.issues.edit({ ...issueParam, state: "closed" });
  } catch (err) {
    console.log(`Error closing issue #${number}: ${err}`);
  }
}

async function pager(res) {
  let pulls = res;

  processPulls(pulls);

  while (github.hasNextPage(pulls)) {
    pulls = await github.getNextPage(pulls);
    if (!pulls) {
      break;
    }

    processPulls(pulls);
  }
}

github.pullRequests
  .getAll({
    ...repo,
    state: "closed",
    per_page: 99,
  })
  .then(pager)
  .catch((err) => console.log("Error: ", err));
<|endoftext|>


<commit_before>const DEFAULTS = {
    name: '',
    time: 0,
    delay: 0,
    ready: 0,
    easing: '',
    last: true,
}

function removeElement (el) {
    if (el.parentNode) {
        el.parentNode.removeChild(el)
    }
}

function setTransition (props, el) {
    el.style.transition = `all ${props.easing} ${props.time}ms`
}

function props2Fn(props) {
    return _ => {
        var props2 = (typeof props === 'function') ? props() : props
        return Object.assign({}, DEFAULTS, props2)
    }
}

function txmethod (name, f) {
    return function (props) {
        const propsFn = props2Fn(props)
        const handler = (...args) => f(propsFn(), ...args)
        return function (vnode) {
            const origHandler = vnode.data[name] || (_ => {})
            vnode.data[name] = (...args) => {
                origHandler(...args)
                handler(...args)
            }
            return vnode
        }
    }
}

function trackMoves (el) {
    const prevX = +el.getAttribute('data-t-x')
    const prevY = +el.getAttribute('data-t-y')
    const {left: newX, top: newY} = el.getBoundingClientRect()
    el.setAttribute('data-t-x', newX)
    el.setAttribute('data-t-y', newY)
    if (!prevX) return [null, null]
    return [prevX - newX, prevY - newY]
}

const _leaveOnRemove = txmethod('onremove', (props, el) => {
    const cls = `${props.name}-leave`
    //first we need to capture any transforms the
    //leave class will apply
    el.style.transition = ''
    el.style.transform = ''
    el.classList.add(cls)
    const willTransform = getComputedStyle(el).getPropertyValue('transform')
    const [sx, wx, wy, sy, tx, ty] = (willTransform === 'none')
        ? [1, 0, 0, 1, 0, 0]
        : willTransform.match(/^matrix\(([^\)]*)\)$/)[1].split(', ').map(s => +s);
    el.classList.remove(cls)

    //and set the plain translation:
    const [dx, dy] = trackMoves(el)
    el.style.transform = `translate(${dx}px, ${dy}px)`

    //after the specified delay, apply the transition
    setTimeout(_ => {
        el.classList.add(cls)
        //override the transition props
        el.style.transform = `matrix(${sx}, ${wx}, ${wy}, ${sy}, ${tx + dx}, ${ty + dy})`
        setTransition(props, el)
        //after the delay, if last, remove:
        if (props.last) setTimeout(_ => removeElement(el), props.time)
    }, props.delay)
})

const _leaveOnCreate = txmethod('oncreate', (props, el) => setTimeout(_ => trackMoves(el), props.ready))

const leave = props => combine(
    _leaveOnCreate(props),
    _leaveOnRemove(props)
)

const enter = txmethod('oncreate', (props, el) => {
    const clsEnter = `${props.name}-enter`
    el.classList.add(clsEnter)
    setTimeout(_ => {
        setTransition(props, el)
        el.classList.remove(clsEnter)
    }, props.delay)
})

const change = txmethod('oncreate', (props, el) => setTransition(props, el))

const _moveOnUpdate = txmethod('onupdate', (props, el) => {
    const [dx, dy] = trackMoves(el)
    el.style.transition = ''
    el.style.transform = `translate(${dx}px, ${dy}px)`
    setTimeout(_ => {
        setTransition(props, el)
        el.style.transition = `all ${props.easing} ${props.time}ms`
        el.style.transform = 'translate(0,0)'
        setTimeout(_ => {
        el.style.transform = ''
        el.style.transition = ''
        }, props.time)
    })
})

const _moveOnCreate = txmethod('oncreate', (props, el) => setTimeout(_ => trackMoves(el), props.ready))

const move = props => combine(
    _moveOnCreate(props),
    _moveOnUpdate(props)
)

function combine(...args) {
    var a, b
    const ts = [...args]
    const l = ts.length
    var a = ts[0]
    if (l === 1) return a
    var b
    if (l > 2) b = combine(...ts.slice(1))
    else b = ts[1]
    return v => a(b(v))
}

function group(f) {
    return vnode => {
        vnode.children.forEach(f)
        return vnode
    }
}

module.exports = {
    change,
    enter,
    leave,
    move,
    group,
    combine
}<commit_msg>minor stylistic improvements<commit_after>const DEFAULTS = {
    name: '',
    time: 0,
    delay: 0,
    ready: 0,
    easing: '',
    last: true,
}

function removeElement (el) {
    if (!el.parentNode) return
    el.parentNode.removeChild(el)
}

function setTransition (props, el) {
    el.style.transition = `all ${props.easing} ${props.time}ms`
}

function props2Fn(props) {
    return _ => {
        var props2 = (typeof props === 'function') ? props() : props
        return Object.assign({}, DEFAULTS, props2)
    }
}

function txmethod (name, f) {
    return function (props) {
        const propsFn = props2Fn(props)
        const handler = (...args) => f(propsFn(), ...args)
        return function (vnode) {
            const origHandler = vnode.data[name] || (_ => {})
            vnode.data[name] = (...args) => {
                origHandler(...args)
                handler(...args)
            }
            return vnode
        }
    }
}

function trackMoves (el) {
    const prevX = +el.getAttribute('data-t-x')
    const prevY = +el.getAttribute('data-t-y')
    const {left: newX, top: newY} = el.getBoundingClientRect()
    el.setAttribute('data-t-x', newX)
    el.setAttribute('data-t-y', newY)
    if (!prevX) return [null, null]
    return [prevX - newX, prevY - newY]
}

const _leaveOnRemove = txmethod('onremove', (props, el) => {
    const cls = `${props.name}-leave`

    //first we need to capture any transforms the
    //leave class will apply
    el.style.transition = ''
    el.style.transform = ''
    el.classList.add(cls)
    const willTransform = getComputedStyle(el).getPropertyValue('transform')
    const [sx, wx, wy, sy, tx, ty] = (willTransform === 'none')
        ? [1, 0, 0, 1, 0, 0]
        : willTransform.match(/^matrix\(([^\)]*)\)$/)[1].split(', ').map(s => +s);
    el.classList.remove(cls)

    //and set the plain translation:
    const [dx, dy] = trackMoves(el)
    el.style.transform = `translate(${dx}px, ${dy}px)`

    //after the specified delay, apply the transition
    setTimeout(_ => {
        el.classList.add(cls)
        //override the transition props
        el.style.transform = `matrix(${sx}, ${wx}, ${wy}, ${sy}, ${tx + dx}, ${ty + dy})`
        setTransition(props, el)
        //after the delay, if last, remove:
        if (props.last) setTimeout(_ => removeElement(el), props.time)
    }, props.delay)
})

const _leaveOnCreate = txmethod('oncreate', (props, el) => setTimeout(_ => trackMoves(el), props.ready))

const leave = props => combine(
    _leaveOnCreate(props),
    _leaveOnRemove(props)
)

const enter = txmethod('oncreate', (props, el) => {
    const clsEnter = `${props.name}-enter`
    el.classList.add(clsEnter)
    setTimeout(_ => {
        setTransition(props, el)
        el.classList.remove(clsEnter)
    }, props.delay)
})

const change = txmethod('oncreate', (props, el) => setTransition(props, el))

const _moveOnUpdate = txmethod('onupdate', (props, el) => {
    const [dx, dy] = trackMoves(el)
    el.style.transition = ''
    el.style.transform = `translate(${dx}px, ${dy}px)`
    setTimeout(_ => {
        setTransition(props, el)
        el.style.transition = `all ${props.easing} ${props.time}ms`
        el.style.transform = 'translate(0,0)'
        setTimeout(_ => {
            el.style.transform = ''
            el.style.transition = ''
        }, props.time)
    })
})

const _moveOnCreate = txmethod('oncreate', (props, el) => setTimeout(_ => trackMoves(el), props.ready))

const move = props => combine(
    _moveOnCreate(props),
    _moveOnUpdate(props)
)

function combine(...args) {
    var a, b
    const ts = [...args]
    const l = ts.length
    var a = ts[0]
    if (l === 1) return a
    var b
    if (l > 2) b = combine(...ts.slice(1))
    else b = ts[1]
    return v => a(b(v))
}

function group(f) {
    return vnode => {
        vnode.children.forEach(f)
        return vnode
    }
}

module.exports = {
    change,
    enter,
    leave,
    move,
    group,
    combine
}<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import 'whatwg-fetch'
import 'url-search-params-polyfill';
import  TwitterIcon from 'react-icons/lib/fa/twitter';

class TwitterLogin extends Component {

  constructor(props) {
    super(props);

    this.onButtonClick = this.onButtonClick.bind(this);
  }

  onButtonClick() {
    return this.getRequestToken();
  }

  getRequestToken() {
    return window.fetch(this.props.requestTokenUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      }
    }).then(response => {
      return response.json();
    }).then(data => {
      this.openPopup(data.oauth_token);
    }).catch(error => {
      return this.props.onFailure(error);
    });
  }

  openPopup(token) {
    const w = this.props.dialogWidth;
    const h = this.props.dialogHeight;
    const left = (screen.width/2)-(w/2);
    const top = (screen.height/2)-(h/2);
    const popup = window.open(`https://api.twitter.com/oauth/authenticate?oauth_token=${token}`, '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);

    this.polling(popup);
  }

  polling(popup) {
    const polling = setInterval(() => {
      if (!popup || popup.closed || popup.closed === undefined) {
        clearInterval(polling);
        this.props.onFailure(new Error('Popup has been closed by user'));
      }

      try {
        if (!popup.location.hostname.includes('api.twitter.com')) {
          if (popup.location.search) {
            const query = new URLSearchParams(popup.location.search);

            const oauthToken = query.get('oauth_token');
            const oauthVerifier = query.get('oauth_verifier');

            this.getOathToken(oauthVerifier, oauthToken);
          } else {
            this.props.onFailure(new Error(
              'OAuth redirect has occurred but no query or hash parameters were found. ' +
              'They were either not set during the redirect, or were removed—typically by a ' +
              'routing library—before Twitter react component could read it.'
            ));
          }

          clearInterval(polling);
          popup.close();
        }
      } catch (error) {
        // Ignore DOMException: Blocked a frame with origin from accessing a cross-origin frame.
        // A hack to get around same-origin security policy errors in IE.
      }
    }, 500);
  }

  getOathToken(oAuthVerifier, oauthToken) {
    return window.fetch(`${this.props.loginUrl}?oauth_verifier=${oAuthVerifier}&oauth_token=${oauthToken}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      }
    }).then(response => {
      return response.json();
    }).then(data => {
      this.props.onSuccess(data);
    }).catch(error => {
      return this.props.onFailure(error);
    });
  }

  getDefaultButtonContent() {
    return (

        <TwitterIcon color='#00aced' size={25}/> {this.props.text}

    );
  }

  render() {
    const twitterButton = React.createElement(
      this.props.tag, {
        onClick: this.onButtonClick,
        style: this.props.style,
        disabled: this.props.disabled,
        className: this.props.className,
      }, this.props.children ? this.props.children : this.getDefaultButtonContent()
    );
    return twitterButton;
  }
}

TwitterLogin.propTypes = {
  tag: PropTypes.string,
  text: PropTypes.string,
  loginUrl: PropTypes.string.isRequired,
  requestTokenUrl: PropTypes.string.isRequired,
  onFailure: PropTypes.func.isRequired,
  onSuccess: PropTypes.func.isRequired,
  disabled: PropTypes.bool,
  style: PropTypes.object,
  className: PropTypes.string,
  dialogWidth: PropTypes.number,
  dialogHeight: PropTypes.number
};

TwitterLogin.defaultProps = {
  tag: 'button',
  text: 'Sign in with Twitter',
  disabled: false,
  dialogWidth: 600,
  dialogHeight: 400
};

export default TwitterLogin;
<commit_msg>If user is authenticated return the whole response<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import 'whatwg-fetch'
import 'url-search-params-polyfill';
import  TwitterIcon from 'react-icons/lib/fa/twitter';

class TwitterLogin extends Component {

  constructor(props) {
    super(props);

    this.onButtonClick = this.onButtonClick.bind(this);
  }

  onButtonClick() {
    return this.getRequestToken();
  }

  getRequestToken() {
    return window.fetch(this.props.requestTokenUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      }
    }).then(response => {
      return response.json();
    }).then(data => {
      this.openPopup(data.oauth_token);
    }).catch(error => {
      return this.props.onFailure(error);
    });
  }

  openPopup(token) {
    const w = this.props.dialogWidth;
    const h = this.props.dialogHeight;
    const left = (screen.width/2)-(w/2);
    const top = (screen.height/2)-(h/2);
    const popup = window.open(`https://api.twitter.com/oauth/authenticate?oauth_token=${token}`, '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);

    this.polling(popup);
  }

  polling(popup) {
    const polling = setInterval(() => {
      if (!popup || popup.closed || popup.closed === undefined) {
        clearInterval(polling);
        this.props.onFailure(new Error('Popup has been closed by user'));
      }

      try {
        if (!popup.location.hostname.includes('api.twitter.com')) {
          if (popup.location.search) {
            const query = new URLSearchParams(popup.location.search);

            const oauthToken = query.get('oauth_token');
            const oauthVerifier = query.get('oauth_verifier');

            this.getOathToken(oauthVerifier, oauthToken);
          } else {
            this.props.onFailure(new Error(
              'OAuth redirect has occurred but no query or hash parameters were found. ' +
              'They were either not set during the redirect, or were removed—typically by a ' +
              'routing library—before Twitter react component could read it.'
            ));
          }

          clearInterval(polling);
          popup.close();
        }
      } catch (error) {
        // Ignore DOMException: Blocked a frame with origin from accessing a cross-origin frame.
        // A hack to get around same-origin security policy errors in IE.
      }
    }, 500);
  }

  getOathToken(oAuthVerifier, oauthToken) {
    return window.fetch(`${this.props.loginUrl}?oauth_verifier=${oAuthVerifier}&oauth_token=${oauthToken}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      }
    }).then(response => {
      this.props.onSuccess(response);
    }).catch(error => {
      return this.props.onFailure(error);
    });
  }

  getDefaultButtonContent() {
    return (

        <TwitterIcon color='#00aced' size={25}/> {this.props.text}

    );
  }

  render() {
    const twitterButton = React.createElement(
      this.props.tag, {
        onClick: this.onButtonClick,
        style: this.props.style,
        disabled: this.props.disabled,
        className: this.props.className,
      }, this.props.children ? this.props.children : this.getDefaultButtonContent()
    );
    return twitterButton;
  }
}

TwitterLogin.propTypes = {
  tag: PropTypes.string,
  text: PropTypes.string,
  loginUrl: PropTypes.string.isRequired,
  requestTokenUrl: PropTypes.string.isRequired,
  onFailure: PropTypes.func.isRequired,
  onSuccess: PropTypes.func.isRequired,
  disabled: PropTypes.bool,
  style: PropTypes.object,
  className: PropTypes.string,
  dialogWidth: PropTypes.number,
  dialogHeight: PropTypes.number
};

TwitterLogin.defaultProps = {
  tag: 'button',
  text: 'Sign in with Twitter',
  disabled: false,
  dialogWidth: 600,
  dialogHeight: 400
};

export default TwitterLogin;
<|endoftext|>


<commit_before>import createProgram from './webgl-wrapper';

console.log('🐭');

const vertexSource = `
	precision highp float;
	attribute vec3 aPosition;
	varying vec2 vTexturePosition;
	varying vec2 vPosition;
	void main(void) {
		vPosition = aPosition.xy;
		vTexturePosition = vec2(aPosition.x + 1.0, -1.0 + aPosition.y) * 0.5;
		gl_Position = vec4(aPosition, 1.0);
	}
`;

const fragmentSource = `
	precision highp float;
	uniform sampler2D uSampler;
	varying vec2 vTexturePosition;
	varying vec2 vPosition;
	uniform vec2 uMousePosition;
	uniform highp float uWidth;

	bool isLive(vec2 offset) {
			vec4 lastColor = texture2D(uSampler, vTexturePosition + offset);
			if (lastColor.r == 0.0) {
				return true;
			} else {
				return false;
			}
	}

	void main(void) {
		float saturation = 1.0 - distance(uMousePosition, vPosition);
		int liveCount = 0;
		float step = 1.0/uWidth;
		// step = 0.0;

		if (isLive(vec2(-step, -step))) {liveCount++;}
		if (isLive(vec2(-step, 0))) {liveCount++;}
		if (isLive(vec2(-step, step))) {liveCount++;}
		if (isLive(vec2(0, -step))) {liveCount++;}
		if (isLive(vec2(0, step))) {liveCount++;}
		if (isLive(vec2(step, -step))) {liveCount++;}
		if (isLive(vec2(step, 0))) {liveCount++;}
		if (isLive(vec2(step, step))) {liveCount++;}

		if (liveCount < 2) {
			gl_FragColor = vec4(1.0, 0, 0, 1.0);
		} else if (liveCount < 4) {
			gl_FragColor = vec4(0, 1.0, 0, 1.0);
		} else if (liveCount < 8) {
			gl_FragColor = vec4(0, 0, 1.0, 1.0);
		} else {
			gl_FragColor = vec4(1.0, 0, 1.0, 1.0);
		}
		// gl_FragColor = vec4(0, 0, 0, 1.0);
		bool selfIsLive = isLive(vec2(0,0));
		if (selfIsLive && (liveCount == 2 || liveCount == 3)) {
			gl_FragColor = vec4(0, 0, 0, 1.0);
		} else if (!selfIsLive && (liveCount == 3)) {
			gl_FragColor = vec4(0, 0, 0, 1.0);
		} else {
			gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
		}

		// gl_FragColor = texture2D(uSampler, vTexturePosition);
		// gl_FragColor = vec4(lastColor.r + saturation, lastColor.gba);
		// gl_FragColor = vec4(saturation, 0, 0, 1.0);
	}
`;

createProgram(vertexSource, fragmentSource, (gl, shaderProgram) => {
	console.log(gl.canvas);

	// INITIALIZE BUFFERS
	const vertexBuffer = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
	const vertices = [
		1, 1, 0,
		-1, 1, 0,
		1, -1, 0,
		-1, -1, 0
	];
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
	// END INITIALIZE BUFFERS

	// POINTERS
	const aPosition = gl.getAttribLocation(shaderProgram, "aPosition");
	gl.enableVertexAttribArray(aPosition);
	//gl.vertexAttribPointer(index, size, type, normalized, stride, offset);
	gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);

	const uSampler = gl.getUniformLocation(shaderProgram, "uSampler");
	const uWidth = gl.getUniformLocation(shaderProgram, "uWidth");
	const uMousePosition = gl.getUniformLocation(shaderProgram, "uMousePosition");
	const tTexture0 = gl.createTexture();
	gl.activeTexture(gl.TEXTURE0);
	gl.bindTexture(gl.TEXTURE_2D, tTexture0);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);

	const tTexture1 = gl.createTexture();
	gl.activeTexture(gl.TEXTURE0);
	gl.bindTexture(gl.TEXTURE_2D, tTexture1);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);

	const frameBuffer = gl.createFramebuffer();
	gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
	frameBuffer.width = gl.canvas.width;
	frameBuffer.height = gl.canvas.height;
	gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, frameBuffer.width, frameBuffer.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);

	var renderBuffer = gl.createRenderbuffer();
	gl.bindRenderbuffer(gl.RENDERBUFFER, renderBuffer);
	gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, frameBuffer.width, frameBuffer.height);
	gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderBuffer);

	gl.bindTexture(gl.TEXTURE_2D, null);
	gl.bindRenderbuffer(gl.RENDERBUFFER, null);
	gl.bindFramebuffer(gl.FRAMEBUFFER, null);

	// END POINTERS

	// INTERACTION HANDLER
	var mousePosition = [];
	gl.canvas.addEventListener('mousemove', evt => {
	  mousePosition = [
	    (evt.clientX/gl.canvas.width - 0.5) * 2.0,
	    (1.0 - evt.clientY/gl.canvas.height - 0.5) * 2.0
	  ];
		// draw();
	});
	// END INTERACTION HANDLER

	// DRAW LOOP
	gl.clearColor(0, 0, 0, 1.0);
	gl.clear(gl.COLOR_BUFFER_BIT);

	//Initial state
	const initialCanvas = document.createElement('canvas');
	initialCanvas.width = gl.canvas.width;
	initialCanvas.height = gl.canvas.height;
	const context = initialCanvas.getContext('2d');
	context.globalAlpha = 1.0;
	for (var i = 0; i < gl.canvas.width; i++) {
		for (var j = 0; j < gl.canvas.width; j++) {
			if (Math.random() < 0.35) {
				context.fillStyle = 'black';
				context.fillRect(i, j, 1, 1);
			} else {
				context.fillStyle = 'white';
				context.fillRect(i, j, 1, 1);
			}
		}
	}
	gl.bindTexture(gl.TEXTURE_2D, tTexture0);
	gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, initialCanvas);
	gl.bindTexture(gl.TEXTURE_2D, null);

	gl.uniform1f(uWidth, gl.canvas.width);

	let flip = 0;

	function draw() {
	  // Clear pixels and depth
		// console.log('Draw');

		// gl.bindTexture(gl.TEXTURE_2D, tTexture);
		// gl.generateMipmap(gl.TEXTURE_2D);

		gl.uniform2f(uMousePosition, mousePosition[0], mousePosition[1]);

		//Draw to frame buffer
		gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
		if (flip == 0) {
			gl.bindTexture(gl.TEXTURE_2D, tTexture0);
			gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tTexture1, 0);
		} else {
			gl.bindTexture(gl.TEXTURE_2D, tTexture1);
			gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tTexture0, 0);
		}

	  gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 3);

		//Draw to canvas
		gl.bindFramebuffer(gl.FRAMEBUFFER, null);
	  gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 3);

		flip = (flip + 1) % 2;
		gl.bindTexture(gl.TEXTURE_2D, null);

		// setTimeout(draw, 1000);
	  requestAnimationFrame(draw);
	}
	requestAnimationFrame(draw);
	// END DRAW LOOP
});
<commit_msg>Track age<commit_after>import createProgram from './webgl-wrapper';

console.log('🐭');

const vertexSource = `
	precision highp float;
	attribute vec3 aPosition;
	varying vec2 vTexturePosition;
	varying vec2 vPosition;
	void main(void) {
		vPosition = aPosition.xy;
		vTexturePosition = vec2(aPosition.x + 1.0, -1.0 + aPosition.y) * 0.5;
		gl_Position = vec4(aPosition, 1.0);
	}
`;

const fragmentSource = `
	precision highp float;
	uniform sampler2D uSampler;
	varying vec2 vTexturePosition;
	varying vec2 vPosition;
	uniform vec2 uMousePosition;
	uniform highp float uWidth;

	bool isLive(vec2 offset) {
			vec4 lastColor = texture2D(uSampler, vTexturePosition + offset);
			if (lastColor.r == 1.0) {
				return true;
			} else {
				return false;
			}
	}

	void main(void) {
		float saturation = 1.0 - distance(uMousePosition, vPosition);
		int liveCount = 0;
		float step = 1.0/uWidth;
		// step = 0.0;

		if (isLive(vec2(-step, -step))) {liveCount++;}
		if (isLive(vec2(-step, 0))) {liveCount++;}
		if (isLive(vec2(-step, step))) {liveCount++;}
		if (isLive(vec2(0, -step))) {liveCount++;}
		if (isLive(vec2(0, step))) {liveCount++;}
		if (isLive(vec2(step, -step))) {liveCount++;}
		if (isLive(vec2(step, 0))) {liveCount++;}
		if (isLive(vec2(step, step))) {liveCount++;}

		if (liveCount < 2) {
			gl_FragColor = vec4(1.0, 0, 0, 1.0);
		} else if (liveCount < 4) {
			gl_FragColor = vec4(0, 1.0, 0, 1.0);
		} else if (liveCount < 8) {
			gl_FragColor = vec4(0, 0, 1.0, 1.0);
		} else {
			gl_FragColor = vec4(1.0, 0, 1.0, 1.0);
		}
		// gl_FragColor = vec4(0, 0, 0, 1.0);
		bool selfIsLive = isLive(vec2(0,0));
		vec4 lastColor = texture2D(uSampler, vTexturePosition);
		if (selfIsLive && (liveCount == 2 || liveCount == 3)) {
			if (lastColor.g < 1.0) {
				gl_FragColor = lastColor + vec4(1.0, 0.05, 0.0, 1.0);
			} else {
				gl_FragColor = lastColor + vec4(1.0, 0.0, 0.05, 1.0);
			}
		} else if (!selfIsLive && (liveCount == 3)) {
			gl_FragColor = vec4(1.0, 0, 0, 1.0);
		} else {
			gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
		}

		// gl_FragColor = texture2D(uSampler, vTexturePosition);
		// gl_FragColor = vec4(lastColor.r + saturation, lastColor.gba);
		// gl_FragColor = vec4(saturation, 0, 0, 1.0);
	}
`;

createProgram(vertexSource, fragmentSource, (gl, shaderProgram) => {
	console.log(gl.canvas);

	// INITIALIZE BUFFERS
	const vertexBuffer = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
	const vertices = [
		1, 1, 0,
		-1, 1, 0,
		1, -1, 0,
		-1, -1, 0
	];
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
	// END INITIALIZE BUFFERS

	// POINTERS
	const aPosition = gl.getAttribLocation(shaderProgram, "aPosition");
	gl.enableVertexAttribArray(aPosition);
	//gl.vertexAttribPointer(index, size, type, normalized, stride, offset);
	gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);

	const uSampler = gl.getUniformLocation(shaderProgram, "uSampler");
	const uWidth = gl.getUniformLocation(shaderProgram, "uWidth");
	const uMousePosition = gl.getUniformLocation(shaderProgram, "uMousePosition");
	const tTexture0 = gl.createTexture();
	gl.activeTexture(gl.TEXTURE0);
	gl.bindTexture(gl.TEXTURE_2D, tTexture0);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);

	const tTexture1 = gl.createTexture();
	gl.activeTexture(gl.TEXTURE0);
	gl.bindTexture(gl.TEXTURE_2D, tTexture1);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);

	const frameBuffer = gl.createFramebuffer();
	gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
	frameBuffer.width = gl.canvas.width;
	frameBuffer.height = gl.canvas.height;
	gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, frameBuffer.width, frameBuffer.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);

	var renderBuffer = gl.createRenderbuffer();
	gl.bindRenderbuffer(gl.RENDERBUFFER, renderBuffer);
	gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, frameBuffer.width, frameBuffer.height);
	gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderBuffer);

	gl.bindTexture(gl.TEXTURE_2D, null);
	gl.bindRenderbuffer(gl.RENDERBUFFER, null);
	gl.bindFramebuffer(gl.FRAMEBUFFER, null);

	// END POINTERS

	// INTERACTION HANDLER
	var mousePosition = [];
	gl.canvas.addEventListener('mousemove', evt => {
	  mousePosition = [
	    (evt.clientX/gl.canvas.width - 0.5) * 2.0,
	    (1.0 - evt.clientY/gl.canvas.height - 0.5) * 2.0
	  ];
		// draw();
	});
	// END INTERACTION HANDLER

	// DRAW LOOP
	gl.clearColor(0, 0, 0, 1.0);
	gl.clear(gl.COLOR_BUFFER_BIT);

	//Initial state
	const initialCanvas = document.createElement('canvas');
	initialCanvas.width = gl.canvas.width;
	initialCanvas.height = gl.canvas.height;
	const context = initialCanvas.getContext('2d');
	context.globalAlpha = 1.0;
	for (var i = 0; i < gl.canvas.width; i++) {
		for (var j = 0; j < gl.canvas.width; j++) {
			if (Math.random() < 0.35) {
				context.fillStyle = 'red';
				context.fillRect(i, j, 1, 1);
			} else {
				context.fillStyle = 'black';
				context.fillRect(i, j, 1, 1);
			}
		}
	}
	gl.bindTexture(gl.TEXTURE_2D, tTexture0);
	gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, initialCanvas);
	gl.bindTexture(gl.TEXTURE_2D, null);

	gl.uniform1f(uWidth, gl.canvas.width);

	let flip = 0;

	function draw() {
	  // Clear pixels and depth
		// console.log('Draw');

		// gl.bindTexture(gl.TEXTURE_2D, tTexture);
		// gl.generateMipmap(gl.TEXTURE_2D);

		gl.uniform2f(uMousePosition, mousePosition[0], mousePosition[1]);

		//Draw to frame buffer
		gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
		if (flip == 0) {
			gl.bindTexture(gl.TEXTURE_2D, tTexture0);
			gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tTexture1, 0);
		} else {
			gl.bindTexture(gl.TEXTURE_2D, tTexture1);
			gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tTexture0, 0);
		}

	  gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 3);

		//Draw to canvas
		gl.bindFramebuffer(gl.FRAMEBUFFER, null);
	  gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length / 3);

		flip = (flip + 1) % 2;
		gl.bindTexture(gl.TEXTURE_2D, null);

		// setTimeout(draw, 1000);
	  requestAnimationFrame(draw);
	}
	requestAnimationFrame(draw);
	// END DRAW LOOP
});
<|endoftext|>