<commit_before>import _ from 'messages'
import findKey from 'lodash/findKey'
import Icon from 'icon'
import isFunction from 'lodash/isFunction'
import isString from 'lodash/isString'
import map from 'lodash/map'
import React from 'react'
import round from 'lodash/round'
import { DropdownButton, MenuItem } from 'react-bootstrap-4/lib'

import Component from './base-component'
import { formatSize, formatSizeRaw, parseSize, propTypes } from './utils'

const LONG_CLICK = 400
const SELECT_STYLE = { padding: '0px' }
const SIZE_STYLE = { width: '10rem' }
const UNITS = ['kiB', 'MiB', 'GiB']
const EDITABLE_STYLE = { borderBottom: '1px dashed #ccc' }

@propTypes({
  alt: propTypes.node.isRequired
})
class Hover extends Component {
  constructor () {
    super()

    this.state = {
      hover: false
    }

    this._onMouseEnter = () => this.setState({ hover: true })
    this._onMouseLeave = () => this.setState({ hover: false })
  }

  render () {
    if (this.state.hover) {
      return
        {this.props.alt}

    }

    return
      {this.props.children}

  }
}

@propTypes({
  onChange: propTypes.func.isRequired,
  onUndo: propTypes.oneOfType([
    propTypes.bool,
    propTypes.func
  ]),
  useLongClick: propTypes.bool,
  value: propTypes.any.isRequired
})
class Editable extends Component {
  _onKeyDown = event => {
    const { keyCode } = event
    if (keyCode === 27) {
      return this._closeEdition()
    }

    if (keyCode === 13) {
      return this._save(this.value)
    }
  }

  _closeEdition = () => {
    this.setState({ editing: false })
  }

  _openEdition = () => {
    this.setState({
      editing: true,
      error: null,
      saving: false
    })
  }

  _undo = () => {
    const { onUndo } = this.props
    if (onUndo === false) {
      return
    }

    return this._save(this.state.previous, isFunction(onUndo) && onUndo)
  }

  async _save (value, fn) {
    const { props } = this

    const previous = props.value
    if (value === previous) {
      return this._closeEdition()
    }

    this.setState({ saving: true })

    try {
      await (fn || props.onChange)(value)

      this.setState({ previous })
      this._closeEdition()
    } catch (error) {
      this.setState({
        error: isString(error) ? error : error.message,
        saving: false
      })
    }
  }

  _startTimer = event => {
    event.persist()
    this._timeout = setTimeout(() => {
      event.preventDefault()
      this._openEdition()
    }, LONG_CLICK)
  }
  _stopTimer = () => clearTimeout(this._timeout)

  render () {
    const { state, props } = this

    if (!state.editing) {
      const { onUndo, previous } = state
      const { useLongClick } = props

      const success = <Icon icon='success' />
      return

          {this._renderDisplay()}

        {previous != null && (onUndo !== false
          ? <Hover alt={<Icon icon='undo' onClick={this._undo} />}>
            {success}
          </Hover>
          : success
        )}

    }

    const { error, saving } = state

    return
      {this._renderEdition()}
      {saving && {' '}<Icon icon='loading' />}
      {error != null && {' '}<Icon icon='error' title={error} />}

  }
}

@propTypes({
  children: propTypes.string,
  value: propTypes.string.isRequired
})
export class Text extends Editable {
  get value () {
    return this.refs.input.value
  }

  _onInput = ({ target }) => {
    target.style.width = `${target.value.length + 1}ex`
  }

  _renderDisplay () {
    const {
      children,
      value
    } = this.props

    if (children || value) {
      return  {children || value}
    }

    const {
      placeholder,
      useLongClick
    } = this.props

    return
      {placeholder ||
        (useLongClick ? _('editableLongClickPlaceholder') : _('editableClickPlaceholder'))
      }

  }

  _renderEdition () {
    const { value } = this.props
    const { saving } = this.state

    return <input
      autoFocus
      defaultValue={value}
      onBlur={this._closeEdition}
      onInput={this._onInput}
      onKeyDown={this._onKeyDown}
      readOnly={saving}
      ref='input'
      style={{
        width: `${value.length + 1}ex`
      }}
      type='text'
    />
  }
}

@propTypes({
  labelProp: propTypes.string.isRequired,
  options: propTypes.oneOfType([
    propTypes.array,
    propTypes.object
  ]).isRequired
})
export class Select extends Editable {
  componentWillReceiveProps () {
    this._defaultValue = findKey(this.props.options, option => option === this.props.value)
  }

  get value () {
    return this.props.options[this._select.value]
  }

  _onChange = event => {
    this._save(this.props.options[event.target.value])
  }
  _optionToJsx = (option, index) => {
    const { labelProp } = this.props
    return <option
      key={index}
      value={index}
    >
      {labelProp ? option[labelProp] : option}
    </option>
  }

  _onEditionMount = ref => {
    this._select = ref
    // Seems to work in Google Chrome (not in Firefox)
    ref && ref.dispatchEvent(new window.MouseEvent('mousedown'))
  }

  _renderDisplay () {
    return this.props.children ||
      {this.props.value[this.props.labelProp]}
  }

  _renderEdition () {
    const { saving } = this.state
    const { options } = this.props

    return <select
      autoFocus
      className='form-control'
      defaultValue={this._defaultValue}
      onBlur={this._closeEdition}
      onChange={this._onChange}
      onKeyDown={this._onKeyDown}
      readOnly={saving}
      ref={this._onEditionMount}
      style={SELECT_STYLE}
    >
      {map(options, this._optionToJsx)}
    </select>
  }
}

@propTypes({
  children: propTypes.string,
  value: propTypes.number.isRequired
})
export class Size extends Editable {
  get value () {
    const { sizeNumber, sizeUnit } = this.state
    return sizeNumber ? parseSize(sizeNumber + ' ' + sizeUnit) : 0
  }

  componentWillReceiveProps () {
    const humanSize = formatSizeRaw(this.props.value)
    this.setState({
      sizeNumber: round(humanSize.value, 1),
      sizeUnit: humanSize.prefix + 'B'
    })
  }

  _updateNumber = () => {
    this.setState({ sizeNumber: this.refs.value.value })
  }
  _updateUnit = sizeUnit => {
    this.setState({ sizeUnit })
  }

  _renderDisplay () {
    return this.props.children || formatSize(this.props.value)
  }

  _renderEdition () {
    const {
      saving,
      sizeNumber,
      sizeUnit
    } = this.state

    return
      <input
        autoFocus
        className='form-control'
        defaultValue={sizeNumber}
        onChange={this._updateNumber}
        readOnly={saving}
        ref='value'
        step={0.1}
        type='number'
      />

        <DropdownButton
          title={sizeUnit}
          id='size'
          bsStyle='secondary'
        >
          {map(UNITS, unit => <MenuItem key={unit} onClick={() => this._updateUnit(unit)}>{unit}</MenuItem>)}
        </DropdownButton>

  }
}
<commit_msg>fix(editable): anything can be used as children<commit_after>import _ from 'messages'
import findKey from 'lodash/findKey'
import Icon from 'icon'
import isFunction from 'lodash/isFunction'
import isString from 'lodash/isString'
import map from 'lodash/map'
import React from 'react'
import round from 'lodash/round'
import { DropdownButton, MenuItem } from 'react-bootstrap-4/lib'

import Component from './base-component'
import { formatSize, formatSizeRaw, parseSize, propTypes } from './utils'

const LONG_CLICK = 400
const SELECT_STYLE = { padding: '0px' }
const SIZE_STYLE = { width: '10rem' }
const UNITS = ['kiB', 'MiB', 'GiB']
const EDITABLE_STYLE = { borderBottom: '1px dashed #ccc' }

@propTypes({
  alt: propTypes.node.isRequired
})
class Hover extends Component {
  constructor () {
    super()

    this.state = {
      hover: false
    }

    this._onMouseEnter = () => this.setState({ hover: true })
    this._onMouseLeave = () => this.setState({ hover: false })
  }

  render () {
    if (this.state.hover) {
      return
        {this.props.alt}

    }

    return
      {this.props.children}

  }
}

@propTypes({
  onChange: propTypes.func.isRequired,
  onUndo: propTypes.oneOfType([
    propTypes.bool,
    propTypes.func
  ]),
  useLongClick: propTypes.bool,
  value: propTypes.any.isRequired
})
class Editable extends Component {
  _onKeyDown = event => {
    const { keyCode } = event
    if (keyCode === 27) {
      return this._closeEdition()
    }

    if (keyCode === 13) {
      return this._save(this.value)
    }
  }

  _closeEdition = () => {
    this.setState({ editing: false })
  }

  _openEdition = () => {
    this.setState({
      editing: true,
      error: null,
      saving: false
    })
  }

  _undo = () => {
    const { onUndo } = this.props
    if (onUndo === false) {
      return
    }

    return this._save(this.state.previous, isFunction(onUndo) && onUndo)
  }

  async _save (value, fn) {
    const { props } = this

    const previous = props.value
    if (value === previous) {
      return this._closeEdition()
    }

    this.setState({ saving: true })

    try {
      await (fn || props.onChange)(value)

      this.setState({ previous })
      this._closeEdition()
    } catch (error) {
      this.setState({
        error: isString(error) ? error : error.message,
        saving: false
      })
    }
  }

  _startTimer = event => {
    event.persist()
    this._timeout = setTimeout(() => {
      event.preventDefault()
      this._openEdition()
    }, LONG_CLICK)
  }
  _stopTimer = () => clearTimeout(this._timeout)

  render () {
    const { state, props } = this

    if (!state.editing) {
      const { onUndo, previous } = state
      const { useLongClick } = props

      const success = <Icon icon='success' />
      return

          {this._renderDisplay()}

        {previous != null && (onUndo !== false
          ? <Hover alt={<Icon icon='undo' onClick={this._undo} />}>
            {success}
          </Hover>
          : success
        )}

    }

    const { error, saving } = state

    return
      {this._renderEdition()}
      {saving && {' '}<Icon icon='loading' />}
      {error != null && {' '}<Icon icon='error' title={error} />}

  }
}

@propTypes({
  value: propTypes.string.isRequired
})
export class Text extends Editable {
  get value () {
    return this.refs.input.value
  }

  _onInput = ({ target }) => {
    target.style.width = `${target.value.length + 1}ex`
  }

  _renderDisplay () {
    const {
      children,
      value
    } = this.props

    if (children || value) {
      return  {children || value}
    }

    const {
      placeholder,
      useLongClick
    } = this.props

    return
      {placeholder ||
        (useLongClick ? _('editableLongClickPlaceholder') : _('editableClickPlaceholder'))
      }

  }

  _renderEdition () {
    const { value } = this.props
    const { saving } = this.state

    return <input
      autoFocus
      defaultValue={value}
      onBlur={this._closeEdition}
      onInput={this._onInput}
      onKeyDown={this._onKeyDown}
      readOnly={saving}
      ref='input'
      style={{
        width: `${value.length + 1}ex`
      }}
      type='text'
    />
  }
}

@propTypes({
  labelProp: propTypes.string.isRequired,
  options: propTypes.oneOfType([
    propTypes.array,
    propTypes.object
  ]).isRequired
})
export class Select extends Editable {
  componentWillReceiveProps () {
    this._defaultValue = findKey(this.props.options, option => option === this.props.value)
  }

  get value () {
    return this.props.options[this._select.value]
  }

  _onChange = event => {
    this._save(this.props.options[event.target.value])
  }
  _optionToJsx = (option, index) => {
    const { labelProp } = this.props
    return <option
      key={index}
      value={index}
    >
      {labelProp ? option[labelProp] : option}
    </option>
  }

  _onEditionMount = ref => {
    this._select = ref
    // Seems to work in Google Chrome (not in Firefox)
    ref && ref.dispatchEvent(new window.MouseEvent('mousedown'))
  }

  _renderDisplay () {
    return this.props.children ||
      {this.props.value[this.props.labelProp]}
  }

  _renderEdition () {
    const { saving } = this.state
    const { options } = this.props

    return <select
      autoFocus
      className='form-control'
      defaultValue={this._defaultValue}
      onBlur={this._closeEdition}
      onChange={this._onChange}
      onKeyDown={this._onKeyDown}
      readOnly={saving}
      ref={this._onEditionMount}
      style={SELECT_STYLE}
    >
      {map(options, this._optionToJsx)}
    </select>
  }
}

@propTypes({
  value: propTypes.number.isRequired
})
export class Size extends Editable {
  get value () {
    const { sizeNumber, sizeUnit } = this.state
    return sizeNumber ? parseSize(sizeNumber + ' ' + sizeUnit) : 0
  }

  componentWillReceiveProps () {
    const humanSize = formatSizeRaw(this.props.value)
    this.setState({
      sizeNumber: round(humanSize.value, 1),
      sizeUnit: humanSize.prefix + 'B'
    })
  }

  _updateNumber = () => {
    this.setState({ sizeNumber: this.refs.value.value })
  }
  _updateUnit = sizeUnit => {
    this.setState({ sizeUnit })
  }

  _renderDisplay () {
    return this.props.children || formatSize(this.props.value)
  }

  _renderEdition () {
    const {
      saving,
      sizeNumber,
      sizeUnit
    } = this.state

    return
      <input
        autoFocus
        className='form-control'
        defaultValue={sizeNumber}
        onChange={this._updateNumber}
        readOnly={saving}
        ref='value'
        step={0.1}
        type='number'
      />

        <DropdownButton
          title={sizeUnit}
          id='size'
          bsStyle='secondary'
        >
          {map(UNITS, unit => <MenuItem key={unit} onClick={() => this._updateUnit(unit)}>{unit}</MenuItem>)}
        </DropdownButton>

  }
}
<|endoftext|>


<commit_before>(function () {
    //Helper function to handle results
    function handleResult(xhr, success, fail) {
        if (xhr.status === 200) {
            if (success !== undefined) {
                var data = undefined;
                try {
                    data = JSON.parse(xhr.response);
                }
                catch (err) { }
                success(data);
            }
        }
        else {
            if (fail !== undefined) {
                try {
                    data = JSON.parse(xhr.response);
                }
                catch (err) { }
                fail(data);
            }
        }
    }

    //Rest Functions
    htmlrest.rest = htmlrest.rest || {

    }

    /**
     * This callback is called when server communication has occured.
     * @callback htmlrest.rest~resultCallback
     * @param {object} data - The data result from the server.
     */

    /**
     * Post data to a url. Success and fail called depending on result
     * @param {string} url - The url to post to
     * @param {object} data - The data to post
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     */
    htmlrest.rest.post = function (url, data, success, fail) {
        htmlrest.rest.ajax(url, 'POST', data, success, fail);
    }

    /**
     * Put data to a url. Success and fail called depending on result
     * @param {string} url - The url to put to
     * @param {object} data - The data to put
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     */
    htmlrest.rest.put = function (url, data, success, fail) {
        htmlrest.rest.ajax(url, 'PUT', data, success, fail);
    }

    /**
     * Delete data at a url. Success and fail called depending on result
     * @param {string} url - The url to delete to
     * @param {object} data - Data to include
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     */
    htmlrest.rest.delete = function (url, data, success, fail) {
        htmlrest.rest.ajax(url, 'DELETE', data, success, fail);
    }

    /**
     * Get data from a url. Success and fail called depending on result
     * @param {string} url - The url to get data from
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     * @param {type} [cache=false] - True to use cached results, false to always get, default false.
     */
    htmlrest.rest.get = function (url, success, fail, cache) {
        if (fail === undefined) {
            fail = success;
        }
        if (cache === undefined || cache === false) {
            if (url.indexOf('?') > -1) {
                url += '&';
            }
            else {
                url += '?';
            }
            url += 'noCache=' + new Date().getTime();
        }

        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.onload = function () {
            handleResult(xhr, success, fail);
        };
        xhr.send();
    }

    /**
     * A more raw ajax call if needed.
     * @param {string} url - The url to call
     * @param {string} method - The method to use
     * @param {object} data - The data to send
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     */
    htmlrest.rest.ajax = function (url, method, data, success, fail) {
        if (fail === undefined) {
            fail = success;
        }

        var xhr = new XMLHttpRequest();
        xhr.open(method, url);
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.onload = function () {
            handleResult(xhr, success, fail);
        };
        xhr.send(JSON.stringify(data));
    }

    /**
     * Upload a file to a url
     * @param {string} url - The url to upload to
     * @param {object|FormData} data - The data to upload, if this is already form data it will be used directly, otherwise
     * data will be sent directly as a file.
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     */
    htmlrest.rest.upload = function (url, data, success, fail) {
        if (fail === undefined) {
            fail = success;
        }

        var formData = null;

        if (data instanceof FormData) {
            formData = data;
        }
        else {
            formData = new FormData();
            formData.append('file', data);
        }

        var xhr = new XMLHttpRequest();
        xhr.open('POST', url);
        xhr.onload = function () {
            handleResult(xhr, success, fail);
        };
        xhr.send(formData);
    }
})();<commit_msg>Made it so if there is an error parsing json out of a rest response, the raw response is returned instead.<commit_after>(function () {
    //Helper function to handle results
    function handleResult(xhr, success, fail) {
        if (xhr.status === 200) {
            if (success !== undefined) {
                var data = undefined;
                try {
                    data = JSON.parse(xhr.response);
                }
                catch (err) {
                    data = xhr.response;
                }
                success(data);
            }
        }
        else {
            if (fail !== undefined) {
                try {
                    data = JSON.parse(xhr.response);
                }
                catch (err) {
                    data = xhr.response;
                }
                fail(data);
            }
        }
    }

    //Rest Functions
    htmlrest.rest = htmlrest.rest || {

    }

    /**
     * This callback is called when server communication has occured.
     * @callback htmlrest.rest~resultCallback
     * @param {object} data - The data result from the server.
     */

    /**
     * Post data to a url. Success and fail called depending on result
     * @param {string} url - The url to post to
     * @param {object} data - The data to post
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     */
    htmlrest.rest.post = function (url, data, success, fail) {
        htmlrest.rest.ajax(url, 'POST', data, success, fail);
    }

    /**
     * Put data to a url. Success and fail called depending on result
     * @param {string} url - The url to put to
     * @param {object} data - The data to put
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     */
    htmlrest.rest.put = function (url, data, success, fail) {
        htmlrest.rest.ajax(url, 'PUT', data, success, fail);
    }

    /**
     * Delete data at a url. Success and fail called depending on result
     * @param {string} url - The url to delete to
     * @param {object} data - Data to include
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     */
    htmlrest.rest.delete = function (url, data, success, fail) {
        htmlrest.rest.ajax(url, 'DELETE', data, success, fail);
    }

    /**
     * Get data from a url. Success and fail called depending on result
     * @param {string} url - The url to get data from
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     * @param {type} [cache=false] - True to use cached results, false to always get, default false.
     */
    htmlrest.rest.get = function (url, success, fail, cache) {
        if (fail === undefined) {
            fail = success;
        }
        if (cache === undefined || cache === false) {
            if (url.indexOf('?') > -1) {
                url += '&';
            }
            else {
                url += '?';
            }
            url += 'noCache=' + new Date().getTime();
        }

        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.onload = function () {
            handleResult(xhr, success, fail);
        };
        xhr.send();
    }

    /**
     * A more raw ajax call if needed.
     * @param {string} url - The url to call
     * @param {string} method - The method to use
     * @param {object} data - The data to send
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     */
    htmlrest.rest.ajax = function (url, method, data, success, fail) {
        if (fail === undefined) {
            fail = success;
        }

        var xhr = new XMLHttpRequest();
        xhr.open(method, url);
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.onload = function () {
            handleResult(xhr, success, fail);
        };
        xhr.send(JSON.stringify(data));
    }

    /**
     * Upload a file to a url
     * @param {string} url - The url to upload to
     * @param {object|FormData} data - The data to upload, if this is already form data it will be used directly, otherwise
     * data will be sent directly as a file.
     * @param {htmlrest.rest~resultCallback} success - Called if the operation is successful
     * @param {htmlrest.rest~resultCallback} [fail] - Called if the operation fails, if not provided will call success for this.
     */
    htmlrest.rest.upload = function (url, data, success, fail) {
        if (fail === undefined) {
            fail = success;
        }

        var formData = null;

        if (data instanceof FormData) {
            formData = data;
        }
        else {
            formData = new FormData();
            formData.append('file', data);
        }

        var xhr = new XMLHttpRequest();
        xhr.open('POST', url);
        xhr.onload = function () {
            handleResult(xhr, success, fail);
        };
        xhr.send(formData);
    }
})();<|endoftext|>


<commit_before>'use strict';

angular.module('hackatonAApp')
  .controller('EMarkCtrl', function ($scope, $routeParams, $resource) {
    $scope.awesomeThings = [
      'HTML5 Boilerplate',
      'AngularJS',
      'Karma'
    ];
        console.log($routeParams.id);

        var ListCriteria=$resource("/api/criteria");

        var ListProjCriteria=$resource("/api/ProjectCriteria",{
            query: {method:'GET'},
            post: {method:'POST'},
            update: {method:'PUT'},
            remove: {method:'DELETE'}
        })

        ListProjCriteria.post({},{criteria_id:1},function(){

        })
        $scope.listCriteria=ListCriteria.query();

        $scope.send_mark=function(){

        }
  });
<commit_msg>fixed<commit_after>'use strict';

angular.module('hackatonAApp')
  .controller('EMarkCtrl', function ($scope, $routeParams, $resource) {
    $scope.awesomeThings = [
      'HTML5 Boilerplate',
      'AngularJS',
      'Karma'
    ];
        console.log($routeParams.id);

        var ListCriteria=$resource("/api/criteria");

        $scope.send_mark=function(){

        }
  });
<|endoftext|>


<commit_before>// OSC Bridge by Javi Agenjo @tamat

var WebSocket = require('./node_modules/faye-websocket/lib/faye/websocket');

var fs        = require('fs'),
http      = require('http'),
https     = require('https'),
qs		  = require('querystring'),
url		  = require('url'),
jQuery		= require('jquery');

var debug="development";
//input parameters
var pos = process.argv.indexOf("-port")
var port   = (pos != -1 && (process.argv.length > pos + 1) ? process.argv[pos+1] : 12344);
secure = process.argv.indexOf("-ssl") != -1;
var verbose = (process.argv.indexOf("-v") != -1 ? true : false);
log("verbose mode ON");

var OSC_PORT = port + 1;
//serial
var kProtocolHeaderFirstByte = 0xBA;
var kProtocolHeaderSecondByte = 0xBE;
var kProtocolHeaderLength = 2;
var kProtocolBodyLength = 12;
var kProtocolChecksumLength = 1;
var kNumChannel = 4;
var kChannelBytes = 3;
var byteDataLength = kProtocolHeaderLength+kProtocolBodyLength+kProtocolChecksumLength;
var channels=new Array(kNumChannel);
for(var i = 0 ; i < kNumChannel ; i++)
{
	channels[i] = new Array(kChannelBytes);
	memset(channels[i],0);
}

//Server
var BroadcastServer = {
	clients: [],
	last_id: 1, //0 is reserved for server messages

	init: function()
	{
	},

	//NEW CLIENT
	onConnection: function(ws)
	{
		//initialize
		ws.user_id = this.last_id;
		this.last_id++;
		var path_info = url.parse(ws.url);
		var params = qs.parse(path_info.query);

		this.clients.push(ws);

		//ON MESSAGE CALLBACK
		ws.onmessage = function(event) {
			log(ws.ip + ' = ' + typeof(event.data) + "["+event.data.length+"]:" + event.data );
			dir(event.data); //like var_dump

			//this.send(...);
		};

		//ON CLOSE CALLBACK
		ws.onclose = function(event) {
			log('close', event.code, event.reason);
			BroadcastServer.clients.splice( BroadcastServer.clients.indexOf(ws), 1);
			ws = null;
		};
	},

	sendToAll: function(data, skip_id )
	{
		//broadcast
		for(var i in BroadcastServer.clients)
			if (BroadcastServer.clients[i].user_id != skip_id)
				BroadcastServer.clients[i].send(data);
		}
	};

// OSC SERVER **********************************************
var inport, osc, sock, udp;

osc = require('osc-min');

udp = require("dgram");
sock = udp.createSocket("udp4", function(msg, rinfo) {
	var error;
	try {
  	//send to all socket
  	var jsonVal = osc.fromBuffer(msg);
  	var channelIndex = 0;
  	for(var i = 0 ; i < jsonVal['elements'].length ; i++)
  	{
  		var element = jsonVal['elements'][i];
  		// log(element);
  		if(element['address']=='/channel'+channelIndex)
  		{

  			var args = element['args'];
  			for(var j = 0 ; j < kChannelBytes ; j++)
  			{
  				channels[channelIndex][j] = args[j]['value'];
  			}
  			channelIndex++;

  		}
  	}
writeSerial(channels);
  	BroadcastServer.sendToAll( JSON.stringify(jsonVal) );
  	// return console.log(jsonVal);
  } catch (_error) {
  	error = _error;
  	return console.log("invalid OSC packet");
  }
});
// so let's start to listen on OSC_PORT
log("OSC Server in port: " + OSC_PORT );
sock.bind(OSC_PORT);

//create packet server
var connectionHandler = function(request, socket, head) {
	var ws = new WebSocket(request, socket, head, ['irc', 'xmpp'], {ping: 5});
	log('open', ws.url, ws.version, ws.protocol);
	BroadcastServer.onConnection(ws);
};

// HTTP SERVER  (used for administration) **********************
var staticHandler = function(request, response)
{
	var path = request.url;
	log("http request: " + path);

	function sendResponse(response,status_code,data)
	{
		// response.writeHead(status_code, {'Content-Type': 'text/plain', "Access-Control-Allow-Origin":"*"});
		// if( typeof(data) == "object")
		// 	response.write( JSON.stringify(data) );
		// else
		// 	response.write( data );
		// response.end();
		response.writeHeader(200, {"Content-Type": "text/html"});
		response.write(data);
		response.end();

	}
	if(path=="/")
	{
		if(debug=="development")
		{
			path = "/index_development.html"
		}
		else if(debug=="production")
		{
			path = "/index_production.html"
		}
	}
	fs.readFile(__dirname + path, function(err, content) {
		var status = err ? 404 : 200;

		sendResponse(response, status, content || "file not found");
	});
};

//Prepare server
BroadcastServer.init();

//create the server (if it is SSL then add the cripto keys)
var server = secure
? https.createServer({
	key:  fs.readFileSync(__dirname + '/../spec/server.key'),
	cert: fs.readFileSync(__dirname + '/../spec/server.crt')
})
: http.createServer();
server.addListener('request', staticHandler); //incoming http connections
server.addListener('upgrade', connectionHandler); //incomming websocket connections

//launch the server
log('WebSocket Server in port...', port);
server.listen(port);

//Serial
var SerialPort = require("serialport").SerialPort

var serialPort = require("serialport");
serialPort.list(function (err, ports) {
	ports.forEach(function(port) {

		if(port.comName.indexOf("/dev/cu.usbserial") > -1 || port.comName.indexOf("COM") > -1)
		{
			serialPort = new SerialPort(port.comName, {baudrate: 57600},false);

			serialPort.open(function (error) {
				if ( error ) {
					log('failed to open: '+error);
				} else {
					log('open');
					writeSerial([kProtocolHeaderFirstByte,kProtocolHeaderSecondByte ,0,0,0,0,0,0,0,0,0,0,0]);
				}
			});
			return;
		}
	});
});

function readSerial ()
{
	serialPort.on('data', function(data) {
		log('data received: ' + data);
		writeSerial ();
	});
}
function memset( object, value )
{
   	for ( var i in object ) object[Number(i)]=value;
}
function writeSerial (_channels)
{
	var data = new Buffer(byteDataLength);
	// var daraArray = new Array(byteDataLength);
	// memset(daraArray,0);

	// byteDataLength = kProtocolHeaderLength+kProtocolBodyLength+kProtocolChecksumLength;
	var index = kProtocolHeaderLength;
	for(var i = 0 ; i < kNumChannel ; i++)
	{
		for(var j = 0 ; j < kChannelBytes ; j++)
		{
			data[index] = _channels[i][j];
			index++;
		}
	}
	data[0] = kProtocolHeaderFirstByte;
	data[1] = kProtocolHeaderSecondByte;
	// var data = new Buffer([kProtocolHeaderFirstByte,kProtocolHeaderSecondByte,
	// 	0xFF,0xFF,0xFF, //first color
	// 	0xFF,0xFF,0xFF, // second color
	// 	0xFF,0xFF,0xFF, // third color
	// 	0xFF,0xFF,0xFF, // fourth color
	// 	0x00]);
	var calculatedChecksum = 0;
	for (var i = kProtocolHeaderLength; i < kProtocolBodyLength; i++) {
		calculatedChecksum ^= data[i];
	}
	data[byteDataLength-1]=calculatedChecksum;
	dir(data);

	serialPort.write(data, function(err, results) {
		if(err)
		{
			log('err ' + err);
			log('results ' + results);
		}
    	// readSerial ();
    	// writeSerial ()
    });

}

//helper function

function rgb2hsb(r,g,b)
{
	var hue, saturation, brightness;
 // if (hsbvals == null) {
 //   hsbvals = new float[3];
 // }
 var cmax = (r > g) ? r : g;
 if (b > cmax) cmax = b;
 var cmin = (r < g) ? r : g;
 if (b < cmin) cmin = b;

 brightness = ( cmax) / 255;
 if (cmax != 0)
 	saturation = ( (cmax - cmin)) / ( cmax);
 else
 	saturation = 0;
 if (saturation == 0)
 	hue = 0;
 else {
 	var redc = ( (cmax - r)) / ( (cmax - cmin));
 	var greenc = ( (cmax - g)) / ( (cmax - cmin));
 	var bluec = ( (cmax - b)) / ( (cmax - cmin));
 	if (r == cmax)
 		hue = bluec - greenc;
 	else if (g == cmax)
 		hue = 2 + redc - bluec;
 	else
 		hue = 4 + greenc - redc;
 	hue = hue / 6;
 	if (hue < 0)
 		hue = hue + 1;
 }
 var hsbvals = new Array(0,0,0);
 hsbvals[0] = float2int(hue*360);
 hsbvals[1] = float2int(saturation*100);
 hsbvals[2] = float2int(brightness*100);
 return hsbvals;

}
function float2int (value) {
	return value | 0;
}

function log(msg)
{
	if(verbose)console.log(msg);
}
function dir(msg)
{
	if(verbose)console.dir(msg);
}<commit_msg>fixed serial port not found<commit_after>// OSC Bridge by Javi Agenjo @tamat

var WebSocket = require('./node_modules/faye-websocket/lib/faye/websocket');

var fs        = require('fs'),
http      = require('http'),
https     = require('https'),
qs		  = require('querystring'),
url		  = require('url'),
jQuery		= require('jquery');

var debug="development";
//input parameters
var pos = process.argv.indexOf("-port")
var port   = (pos != -1 && (process.argv.length > pos + 1) ? process.argv[pos+1] : 12344);
secure = process.argv.indexOf("-ssl") != -1;
var verbose = (process.argv.indexOf("-v") != -1 ? true : false);
log("verbose mode ON");

var OSC_PORT = port + 1;
//serial
var kProtocolHeaderFirstByte = 0xBA;
var kProtocolHeaderSecondByte = 0xBE;
var kProtocolHeaderLength = 2;
var kProtocolBodyLength = 12;
var kProtocolChecksumLength = 1;
var kNumChannel = 4;
var kChannelBytes = 3;
var byteDataLength = kProtocolHeaderLength+kProtocolBodyLength+kProtocolChecksumLength;
var channels=new Array(kNumChannel);
for(var i = 0 ; i < kNumChannel ; i++)
{
	channels[i] = new Array(kChannelBytes);
	memset(channels[i],0);
}

//Server
var BroadcastServer = {
	clients: [],
	last_id: 1, //0 is reserved for server messages

	init: function()
	{
	},

	//NEW CLIENT
	onConnection: function(ws)
	{
		//initialize
		ws.user_id = this.last_id;
		this.last_id++;
		var path_info = url.parse(ws.url);
		var params = qs.parse(path_info.query);

		this.clients.push(ws);

		//ON MESSAGE CALLBACK
		ws.onmessage = function(event) {
			log(ws.ip + ' = ' + typeof(event.data) + "["+event.data.length+"]:" + event.data );
			dir(event.data); //like var_dump

			//this.send(...);
		};

		//ON CLOSE CALLBACK
		ws.onclose = function(event) {
			log('close', event.code, event.reason);
			BroadcastServer.clients.splice( BroadcastServer.clients.indexOf(ws), 1);
			ws = null;
		};
	},

	sendToAll: function(data, skip_id )
	{
		//broadcast
		for(var i in BroadcastServer.clients)
			if (BroadcastServer.clients[i].user_id != skip_id)
				BroadcastServer.clients[i].send(data);
		}
	};

// OSC SERVER **********************************************
var inport, osc, sock, udp;

osc = require('osc-min');

udp = require("dgram");
sock = udp.createSocket("udp4", function(msg, rinfo) {
	var error;
	try {
  	//send to all socket
  	var jsonVal = osc.fromBuffer(msg);
  	var channelIndex = 0;
  	for(var i = 0 ; i < jsonVal['elements'].length ; i++)
  	{
  		var element = jsonVal['elements'][i];
  		// log(element);
  		if(element['address']=='/channel'+channelIndex)
  		{

  			var args = element['args'];
  			for(var j = 0 ; j < kChannelBytes ; j++)
  			{
  				channels[channelIndex][j] = args[j]['value'];
  			}
  			channelIndex++;

  		}
  	}
	writeSerial(channels);
  	BroadcastServer.sendToAll( JSON.stringify(jsonVal) );
  	// return console.log(jsonVal);
  } catch (_error) {
  	error = _error;
  	return console.log("invalid OSC packet"+_error);
  }
});
// so let's start to listen on OSC_PORT
log("OSC Server in port: " + OSC_PORT );
sock.bind(OSC_PORT);

//create packet server
var connectionHandler = function(request, socket, head) {
	var ws = new WebSocket(request, socket, head, ['irc', 'xmpp'], {ping: 5});
	log('open', ws.url, ws.version, ws.protocol);
	BroadcastServer.onConnection(ws);
};

// HTTP SERVER  (used for administration) **********************
var staticHandler = function(request, response)
{
	var path = request.url;
	log("http request: " + path);

	function sendResponse(response,status_code,data)
	{
		// response.writeHead(status_code, {'Content-Type': 'text/plain', "Access-Control-Allow-Origin":"*"});
		// if( typeof(data) == "object")
		// 	response.write( JSON.stringify(data) );
		// else
		// 	response.write( data );
		// response.end();
		response.writeHeader(200, {"Content-Type": "text/html"});
		response.write(data);
		response.end();

	}
	if(path=="/")
	{
		if(debug=="development")
		{
			path = "/index_development.html"
		}
		else if(debug=="production")
		{
			path = "/index_production.html"
		}
	}
	fs.readFile(__dirname + path, function(err, content) {
		var status = err ? 404 : 200;

		sendResponse(response, status, content || "file not found");
	});
};

//Prepare server
BroadcastServer.init();

//create the server (if it is SSL then add the cripto keys)
var server = secure
? https.createServer({
	key:  fs.readFileSync(__dirname + '/../spec/server.key'),
	cert: fs.readFileSync(__dirname + '/../spec/server.crt')
})
: http.createServer();
server.addListener('request', staticHandler); //incoming http connections
server.addListener('upgrade', connectionHandler); //incomming websocket connections

//launch the server
log('WebSocket Server in port...', port);
server.listen(port);

//Serial

var SerialPort = require("serialport").SerialPort

var serialPort = require("serialport");

try{
	serialPort.list(function (err, ports) {
		log(err);
		ports.forEach(function(port) {

			if(port.comName.indexOf("/dev/cu.wchusbserial") > -1 || port.comName.indexOf("/dev/cu.usbserial") > -1 || port.comName.indexOf("COM") > -1)
			{
				serialPort = new SerialPort(port.comName, {baudrate: 57600},false);

				serialPort.open(function (error) {
					if ( error ) {
						log('failed to open: '+error);
					} else {
						log('open');
						writeSerial([kProtocolHeaderFirstByte,kProtocolHeaderSecondByte ,0,0,0,0,0,0,0,0,0,0,0]);
					}
				});
				return;
			}
		});
	});
}
catch(err)
{
	log(err);
}
function readSerial ()
{
	if(serialPort!=null)
	{
	serialPort.on('data', function(data) {
		log('data received: ' + data);
		writeSerial ();
	});
	}
}
function writeSerial (_channels)
{
	if(serialPort!=null)
	{
		var data = new Buffer(byteDataLength);
		// var daraArray = new Array(byteDataLength);
		// memset(daraArray,0);

		// byteDataLength = kProtocolHeaderLength+kProtocolBodyLength+kProtocolChecksumLength;
		var index = kProtocolHeaderLength;
		for(var i = 0 ; i < kNumChannel ; i++)
		{
			for(var j = 0 ; j < kChannelBytes ; j++)
			{
				data[index] = _channels[i][j];
				index++;
			}
		}
		data[0] = kProtocolHeaderFirstByte;
		data[1] = kProtocolHeaderSecondByte;
		// var data = new Buffer([kProtocolHeaderFirstByte,kProtocolHeaderSecondByte,
		// 	0xFF,0xFF,0xFF, //first color
		// 	0xFF,0xFF,0xFF, // second color
		// 	0xFF,0xFF,0xFF, // third color
		// 	0xFF,0xFF,0xFF, // fourth color
		// 	0x00]);
		var calculatedChecksum = 0;
		for (var i = kProtocolHeaderLength; i < kProtocolBodyLength; i++) {
			calculatedChecksum ^= data[i];
		}
		data[byteDataLength-1]=calculatedChecksum;
		dir(data);

		serialPort.write(data, function(err, results) {
			if(err)
			{
				log('err ' + err);
				log('results ' + results);
			}
	    	// readSerial ();
	    	// writeSerial ()
	    });
	}
}
function memset( object, value )
{
   	for ( var i in object ) object[Number(i)]=value;
}
//helper function

function rgb2hsb(r,g,b)
{
	var hue, saturation, brightness;
 // if (hsbvals == null) {
 //   hsbvals = new float[3];
 // }
 var cmax = (r > g) ? r : g;
 if (b > cmax) cmax = b;
 var cmin = (r < g) ? r : g;
 if (b < cmin) cmin = b;

 brightness = ( cmax) / 255;
 if (cmax != 0)
 	saturation = ( (cmax - cmin)) / ( cmax);
 else
 	saturation = 0;
 if (saturation == 0)
 	hue = 0;
 else {
 	var redc = ( (cmax - r)) / ( (cmax - cmin));
 	var greenc = ( (cmax - g)) / ( (cmax - cmin));
 	var bluec = ( (cmax - b)) / ( (cmax - cmin));
 	if (r == cmax)
 		hue = bluec - greenc;
 	else if (g == cmax)
 		hue = 2 + redc - bluec;
 	else
 		hue = 4 + greenc - redc;
 	hue = hue / 6;
 	if (hue < 0)
 		hue = hue + 1;
 }
 var hsbvals = new Array(0,0,0);
 hsbvals[0] = float2int(hue*360);
 hsbvals[1] = float2int(saturation*100);
 hsbvals[2] = float2int(brightness*100);
 return hsbvals;

}
function float2int (value) {
	return value | 0;
}

function log(msg)
{
	if(verbose)console.log(msg);
}
function dir(msg)
{
	if(verbose)console.dir(msg);
}<|endoftext|>


<commit_before>import http from 'http';
import util from 'util';
import urlParser from 'url';
import log from './logger';

function findError({ status, value }) {
  const hasError = status || (value && value.error);
  log(
    `Looking for error in status: ${status}, value: ${util.inspect(
      value,
      false,
      10
    )}, hasError: ${hasError}`
  );

  if (!hasError) {
    return null;
  }

  const { message, error } = value;

  return new Error(`WebDriverError(${error || status}): ${message}`);
}

function sendRequest(method, url, body) {
  const jsonBody = JSON.stringify(body);
  const urlParts = urlParser.parse(url);
  const options = {
    hostname: urlParts.hostname,
    port: urlParts.port,
    path: urlParts.path,
    method,
    headers: {}
  };

  if (body) {
    options.headers['Content-Length'] = Buffer.byteLength(jsonBody);
    options.headers['Content-Type'] = 'application/json';
  }

  return new Promise((resolve, reject) => {
    log(`WebDriver request: ${options.url} ${options.body}`);
    const request = http.request(options, response => {
      const chunks = [];
      response.setEncoding('utf8');
      response.on('data', chunk => {
        chunks.push(chunk);
      });
      response.on('end', () => {
        let responseBody;

        try {
          responseBody = JSON.parse(chunks.join(''));
        } catch (err) {
          reject(err);
        }

        log(`WebDriver response: ${chunks.join('')}`);

        const error = findError(responseBody);

        if (error) {
          reject(error);
          return;
        }

        resolve(responseBody);
      });
    });

    request.on('error', error => reject(error));

    if (body) {
      request.write(jsonBody);
    }
    request.end();
  });
}

export const GET = url => sendRequest('GET', url);
export const POST = (url, body) => sendRequest('POST', url, body);
export const DELETE = (url, body) => sendRequest('DELETE', url, body);
<commit_msg>Remove not needed logs<commit_after>import http from 'http';
import util from 'util';
import urlParser from 'url';
import log from './logger';

function findError({ status, value }) {
  const hasError = !!(status || (value && value.error));

  if (!hasError) {
    return null;
  }

  const { message, error } = value;

  return new Error(`WebDriverError(${error || status}): ${message}`);
}

function sendRequest(method, url, body) {
  log(`WebDriver request: ${method} ${url} ${util.inspect(body, false, 10)}`);

  const jsonBody = JSON.stringify(body);
  const urlParts = urlParser.parse(url);
  const options = {
    hostname: urlParts.hostname,
    port: urlParts.port,
    path: urlParts.path,
    method,
    headers: {}
  };

  if (body) {
    options.headers['Content-Length'] = Buffer.byteLength(jsonBody);
    options.headers['Content-Type'] = 'application/json';
  }

  return new Promise((resolve, reject) => {
    const request = http.request(options, response => {
      const chunks = [];
      response.setEncoding('utf8');
      response.on('data', chunk => {
        chunks.push(chunk);
      });
      response.on('end', () => {
        let responseBody;

        try {
          responseBody = JSON.parse(chunks.join(''));
        } catch (err) {
          reject(err);
        }

        log(`WebDriver response: ${chunks.join('')}`);

        const error = findError(responseBody);

        if (error) {
          reject(error);
          return;
        }

        resolve(responseBody);
      });
    });

    request.on('error', error => reject(error));

    if (body) {
      request.write(jsonBody);
    }
    request.end();
  });
}

export const GET = url => sendRequest('GET', url);
export const POST = (url, body) => sendRequest('POST', url, body);
export const DELETE = (url, body) => sendRequest('DELETE', url, body);
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';

import PictureCard from '../PictureCard/PictureCard';

import css from './PlaceListingCard.css';

const PlaceListingCard = (props) => {
  const {
    imageSrc,
    href,
    priceFromLabel,
    price,
    priceUnit,
    name,
    location,
    spaceDetail,
    onClick,
    ...rest,
  } = props;

  const hasCompleteInfo = location && spaceDetail;

  return (
    <PictureCard
      { ...rest }
      href={ href }
      onClick={ onClick }
      className={ css.root }
      src={ imageSrc }
      overlayClassName={ css.overlay }
    >

          { priceFromLabel && { priceFromLabel } }
          { price }
          { '\u00a0' }
          { priceUnit }

{ name }

            { location }

          { hasCompleteInfo ? • : null }

            { spaceDetail }

    </PictureCard>
  );
};

PlaceListingCard.propTypes = {
  imageSrc: PropTypes.string.isRequired,
  href: PropTypes.string,
  priceFromLabel: PropTypes.string,
  price: PropTypes.node,
  priceUnit: PropTypes.node,
  name: PropTypes.node,
  location: PropTypes.node,
  spaceDetail: PropTypes.node,
  onClick: PropTypes.func,
};

PlaceListingCard.defaultProps = {
  priceFromLabel: 'from',
};

export default PlaceListingCard;
<commit_msg>Allow passing of className prop to PlaceListingCard<commit_after>import React, { PropTypes } from 'react';
import cx from 'classnames';

import PictureCard from '../PictureCard/PictureCard';

import css from './PlaceListingCard.css';

const PlaceListingCard = (props) => {
  const {
    imageSrc,
    href,
    priceFromLabel,
    price,
    priceUnit,
    name,
    location,
    spaceDetail,
    onClick,
    className,
    ...rest,
  } = props;

  const hasCompleteInfo = location && spaceDetail;

  return (
    <PictureCard
      { ...rest }
      href={ href }
      onClick={ onClick }
      className={ cx(css.root, className) }
      src={ imageSrc }
      overlayClassName={ css.overlay }
    >

          { priceFromLabel && { priceFromLabel } }
          { price }
          { '\u00a0' }
          { priceUnit }

{ name }

            { location }

          { hasCompleteInfo ? • : null }

            { spaceDetail }

    </PictureCard>
  );
};

PlaceListingCard.propTypes = {
  imageSrc: PropTypes.string.isRequired,
  href: PropTypes.string,
  priceFromLabel: PropTypes.string,
  className: PropTypes.string,
  price: PropTypes.node,
  priceUnit: PropTypes.node,
  name: PropTypes.node,
  location: PropTypes.node,
  spaceDetail: PropTypes.node,
  onClick: PropTypes.func,
};

PlaceListingCard.defaultProps = {
  priceFromLabel: 'from',
};

export default PlaceListingCard;
<|endoftext|>


<commit_before>const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Utils = imports.utils;

/* Module listing */

let getModuleAtPath = function(vpath) {
    let path = Utils.resolvePath(vpath);

    if (!GLib.file_test(path, GLib.FileTest.IS_DIR))
        return null;

    let manifestPath = path + '/component.json';
    if (!GLib.file_test(manifestPath, GLib.FileTest.IS_REGULAR))
        return null;

    let file = Gio.File.new_for_path(manifestPath);
    let [, manifestContent] = file.load_contents(null);
    let manifest;

    try {
        module = JSON.parse('' + manifestContent);
        module.vpath = vpath;
        module.path = path;
    } catch (e) {
        return null;
    }

    /* Quick sanity check */
    if (!module.name ||
        !module.noflo)
        return null;

    return module;
};

let getModulesInPath = function(vpath) {
    let modules = {};
    let path = Utils.resolvePath(vpath);

    if (!GLib.file_test(path, GLib.FileTest.IS_DIR))
        return modules;

    Utils.forEachInDirectory(Gio.File.new_for_path(path), function(child) {
        let module = getModuleAtPath(Utils.buildPath(vpath,
                                                     child.get_basename()));

        if (module)
            modules[module.name] = module;
    });

    return modules;
};

let getModules = function(paths) {
    let modules = {};
    for (let i in paths) {
        Utils.mergeProps(modules, getModulesInPath(paths[i]));
    }
    return modules;
};

/* Component loader to be injected into the runtime base */

let ComponentLoader = function(options) {
    let self = this;

    /* Ensure with have valid options */
    self.options = options;
    if (!self.options)
        self.options = { paths: [ '.' ] };
    if (!self.options.path)
        self.options.path = ['.'];

    self.components = {};
    self.listCallbacks = [];

    let logFunc = function(name) {
        log('calling : ' +  name);
    };

    let normalizeName = function(name) {
        return name.replace('noflo-', '');
    };

    let removeExtension = function(path) {
        let ret = path.replace(/\.coffee$/, '');
        return ret.replace(/\.js$/, '');
    };

    let generateComponentInstance = function(path) {
        return function(metadata) {
            let implementation = require(path);
            let instance = implementation.getComponent(metadata);
            return instance;
        };
    };

    let generateComponentCodeLoader = function(path) {
        return function() {
            let file = Gio.File.new_for_path(path);
            let [, code] = file.load_contents(null);
            return '' + code;
        };
    };

    let getComponentFullPath = function(module, component) {
        return module.vpath + '/' + module.noflo.components[component];
    };

    let getComponentRequirePath = function(module, component) {
        return removeExtension(getComponentFullPath(module, component));
    };

    self.listComponents = function(callback) {
        // List is built already
        if (self.builtList) {
            callback(self.components);
            return;
        }

        self.listCallbacks.push(callback);

        // Building list
        if (self.buildingList)
            return;

        self.buildingList = true;

        Mainloop.timeout_add(0, Lang.bind(this, function() {
            let modules = getModules(self.options.paths);
            self.components = {};
            for (let moduleName in modules) {
                let module = modules[moduleName];
                for (let componentName in module.noflo.components) {
                    let path = normalizeName(moduleName + '/' + componentName);
                    let requirePath = getComponentRequirePath(module, componentName);
                    let fullPath = getComponentFullPath(module, componentName);
                    self.components[path] = {
                        module: module,
                        moduleName: normalizeName(moduleName),
                        name: componentName,
                        create: generateComponentInstance(requirePath),
                        getCode: generateComponentCodeLoader(fullPath),
                        language: Utils.guessLanguageFromFilename(fullPath),
                        path: fullPath
                    };
                }

                if (module.noflo.loader) {
                    let path = module.vpath + '/' + module.noflo.loader;
                    path = removeExtension(path);
                    let loader = require(path);
                    loader(self);
                }
            }

            let callbacks = self.listCallbacks;
            self.listCallbacks = [];
            self.buildingList = false;
            self.builtList = true;
            for (let i in callbacks)
                callbacks[i](self.components);

            return false;
        }));
    };

    self.load = function(name, callback, delayed, metadata) {
        if (!self.components[name])
            throw new Error('Component ' + name + ' not available');

        Mainloop.timeout_add(0, Lang.bind(this, function() {
            callback(self.components[name].create(metadata));
            return false;
        }));
    };

    self.loadGraph = function(name, component, callback, delayed, metadata) {
        log('loadGraph ' + name);
    };

    self.registerComponent = function(packageId, name, cPath, callback) {
        self.components[packageId + '/' + name] = {
            module: packageId,
            name: name,
            create: cPath,
            language: 'javascript'
        };
        log('registerComponent ' + packageId + ' / ' + name);
    };

    self.registerGraph = function(packageId, name, gPath, callback) {
        log('registerGraph ' + packageId + ' / ' + name);
    };

    self.setSource = function(packageId, name, source, language, callback) {
        log('setSource ' + packageId + ' / ' + name);
    };

    self.getSource = function(name, callback) {
        if (self.components[name].getCode) {
            try {
                callback(null,
                         { name: self.components[name].name,
                           library: self.components[name].moduleName,
                           code: self.components[name].getCode(),
                           language: self.components[name].language
                         });
            } catch (e) {
                log('error loading ' + name + ' : ' + e.message);
                callback(new Error("Cannot load source code for " +
                                   name + " : " + e.message));
            }
        } else {
            log('no source code for ' + name);
            callback(new Error("No source code available for " + name));
        }
    };
};
<commit_msg>runtime: componentLoader: fix component code loading<commit_after>const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Utils = imports.utils;

/* Module listing */

let getModuleAtPath = function(vpath) {
    let path = Utils.resolvePath(vpath);

    if (!GLib.file_test(path, GLib.FileTest.IS_DIR))
        return null;

    let manifestPath = path + '/component.json';
    if (!GLib.file_test(manifestPath, GLib.FileTest.IS_REGULAR))
        return null;

    let file = Gio.File.new_for_path(manifestPath);
    let [, manifestContent] = file.load_contents(null);
    let manifest;

    try {
        module = JSON.parse('' + manifestContent);
        module.vpath = vpath;
        module.path = path;
    } catch (e) {
        return null;
    }

    /* Quick sanity check */
    if (!module.name ||
        !module.noflo)
        return null;

    return module;
};

let getModulesInPath = function(vpath) {
    let modules = {};
    let path = Utils.resolvePath(vpath);

    if (!GLib.file_test(path, GLib.FileTest.IS_DIR))
        return modules;

    Utils.forEachInDirectory(Gio.File.new_for_path(path), function(child) {
        let module = getModuleAtPath(Utils.buildPath(vpath,
                                                     child.get_basename()));

        if (module)
            modules[module.name] = module;
    });

    return modules;
};

let getModules = function(paths) {
    let modules = {};
    for (let i in paths) {
        Utils.mergeProps(modules, getModulesInPath(paths[i]));
    }
    return modules;
};

/* Component loader to be injected into the runtime base */

let ComponentLoader = function(options) {
    let self = this;

    /* Ensure with have valid options */
    self.options = options;
    if (!self.options)
        self.options = { paths: [ '.' ] };
    if (!self.options.path)
        self.options.path = ['.'];

    self.components = {};
    self.listCallbacks = [];

    let logFunc = function(name) {
        log('calling : ' +  name);
    };

    let normalizeName = function(name) {
        return name.replace('noflo-', '');
    };

    let removeExtension = function(path) {
        let ret = path.replace(/\.coffee$/, '');
        return ret.replace(/\.js$/, '');
    };

    let generateComponentInstance = function(path) {
        return function(metadata) {
            let implementation = require(path);
            let instance = implementation.getComponent(metadata);
            return instance;
        };
    };

    let generateComponentCodeLoader = function(path) {
        return function() {
            let file = Gio.File.new_for_path(Utils.resolvePath(path));
            let [, code] = file.load_contents(null);
            return '' + code;
        };
    };

    let getComponentFullPath = function(module, component) {
        return module.vpath + '/' + module.noflo.components[component];
    };

    let getComponentRequirePath = function(module, component) {
        return removeExtension(getComponentFullPath(module, component));
    };

    self.listComponents = function(callback) {
        // List is built already
        if (self.builtList) {
            callback(self.components);
            return;
        }

        self.listCallbacks.push(callback);

        // Building list
        if (self.buildingList)
            return;

        self.buildingList = true;

        Mainloop.timeout_add(0, Lang.bind(this, function() {
            let modules = getModules(self.options.paths);
            self.components = {};
            for (let moduleName in modules) {
                let module = modules[moduleName];
                for (let componentName in module.noflo.components) {
                    let path = normalizeName(moduleName + '/' + componentName);
                    let requirePath = getComponentRequirePath(module, componentName);
                    let fullPath = getComponentFullPath(module, componentName);
                    self.components[path] = {
                        module: module,
                        moduleName: normalizeName(moduleName),
                        name: componentName,
                        create: generateComponentInstance(requirePath),
                        getCode: generateComponentCodeLoader(fullPath),
                        language: Utils.guessLanguageFromFilename(fullPath),
                        path: fullPath
                    };
                }

                if (module.noflo.loader) {
                    let path = module.vpath + '/' + module.noflo.loader;
                    path = removeExtension(path);
                    let loader = require(path);
                    loader(self);
                }
            }

            let callbacks = self.listCallbacks;
            self.listCallbacks = [];
            self.buildingList = false;
            self.builtList = true;
            for (let i in callbacks)
                callbacks[i](self.components);

            return false;
        }));
    };

    self.load = function(name, callback, delayed, metadata) {
        if (!self.components[name])
            throw new Error('Component ' + name + ' not available');

        Mainloop.timeout_add(0, Lang.bind(this, function() {
            callback(self.components[name].create(metadata));
            return false;
        }));
    };

    self.loadGraph = function(name, component, callback, delayed, metadata) {
        log('loadGraph ' + name);
    };

    self.registerComponent = function(packageId, name, cPath, callback) {
        self.components[packageId + '/' + name] = {
            module: packageId,
            name: name,
            create: cPath,
            language: 'javascript'
        };
        log('registerComponent ' + packageId + ' / ' + name);
    };

    self.registerGraph = function(packageId, name, gPath, callback) {
        log('registerGraph ' + packageId + ' / ' + name);
    };

    self.setSource = function(packageId, name, source, language, callback) {
        log('setSource ' + packageId + ' / ' + name);
    };

    self.getSource = function(name, callback) {
        if (self.components[name].getCode) {
            try {
                callback(null,
                         { name: self.components[name].name,
                           library: self.components[name].moduleName,
                           code: self.components[name].getCode(),
                           language: self.components[name].language
                         });
            } catch (e) {
                log('error loading ' + name + ' : ' + e.message);
                callback(new Error("Cannot load source code for " +
                                   name + " : " + e.message));
            }
        } else {
            log('no source code for ' + name);
            callback(new Error("No source code available for " + name));
        }
    };
};
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import thunkMiddleware from 'redux-thunk'
import { createStore, applyMiddleware } from 'redux'
import { connect } from 'react-redux'

import BuildReducer from '../redux/BuildReducer'
import * as actions from '../redux/actions'
import Utils from '../utils'
import Tree, { makeNode } from '../utils/Tree'

/* ---------------------------- Helper Methods ----------------------------- */

/* ----- Recursive Check to see if form is valid  ----- */

const isInvalid = errors => {
  if (Array.isArray(errors)) {
    return errors.some(k => isInvalid(k))
  } else if (errors !== null && typeof errors === 'object') {
    return Object.keys(errors).some(k => isInvalid(errors[k]))
  }
  return errors
}

/* -------------- Generates a new state ------------- */

// TODO figure out way to make state immutable
const newState = state => JSON.parse(JSON.stringify(state))

/* ----------------- Form Component ---------------- */

class Form extends Component {
  constructor (props) {
    super(props)
    this.tree = new Tree({
      nested: true,
      children: {},
      api: {
        ...this.getFormApi(),
        validate: opts => this.validate(undefined, opts),
        preValidate: opts => this.preValidate(undefined, opts),
        asyncValidate: opts => this.asyncValidate(undefined, opts)
      },
      getProps: () => this.props
    })
    this.node = this.tree.root
    this.validationPromiseIDs = new Map()
  }

  getChildContext () {
    return {
      formApi: this.getFormApi(),
      formState: this.getFormState(),
      formProps: this.props
    }
  }

  componentWillMount () {
    if (this.props.getApi) {
      this.props.getApi(this.getFormApi())
    }
  }

  componentDidMount () {
    if (this.props.validateOnMount) {
      this.preValidateAll()
      this.validateAll()
      this.asyncValidateAll()
    }
  }

  componentWillReceiveProps (nextProps) {
    const didUpdate = !Utils.isDeepEqual(nextProps.formState, this.props.formState)
    if (this.props.onChange && didUpdate) {
      this.props.onChange(newState(nextProps.formState), this.getFormApi())
    }
    if (!Utils.isDeepEqual(nextProps.values, this.props.values)) {
      this.setAllValues(nextProps.values)
    }
  }

  getFormApi () {
    return {
      submitForm: this.submitForm,
      setValue: this.setValue,
      getValue: this.getValue,
      setTouched: this.setTouched,
      getTouched: this.getTouched,
      getWarning: this.getWarning,
      getError: this.getError,
      getSuccess: this.getSuccess,
      getFormState: this.getFormState,
      setFormState: this.setFormState,
      setError: this.setError,
      setWarning: this.setWarning,
      setSuccess: this.setSuccess,
      resetAll: this.resetAll,
      reset: this.reset,
      clearAll: this.clearAll,
      addValue: this.addValue,
      removeValue: this.removeValue,
      setAllValues: this.setAllValues,
      setAllTouched: this.setAllTouched,
      swapValues: this.swapValues,
      register: this.register,
      deregister: this.deregister,
      asyncValidate: this.asyncValidate,
      validate: this.validate,
      preValidate: this.preValidate,
      getFullField: this.getFullField
    }
  }

  // Utils

  getFormState = () => newState(this.props.formState)

  recurseUpFromNode = (field, cb) => {
    // Find the node using the field
    const target = this.tree.getNodeByField(field, { closest: true })

    // If there is no target at all, stop
    if (!target) {
      return
    }

    // Define recur function
    const recurse = async node => {
      // Call the cb with the node
      await cb(node)
      // If we have parent recur up
      if (node.parent) {
        recurse(node.parent)
      }
    }

    // start recursion from the target
    try {
      return recurse(target)
    } catch (err) {
      throw err
    }
  }

  recurseUpAllNodes = cb => {
    // Define recur function

    const recurse = async node => {
      // If we have children recurse down
      if (node.children) {
        await Promise.all(Utils.mapObject(node.children, recurse))
      }
      // Call the cb with the node
      await cb(node)
    }

    // start recursion from the target
    try {
      return recurse(this.node)
    } catch (err) {
      throw err
    }
  }

  getFieldProps = field => {
    const node = field ? this.tree.getNodeByField(field) || makeNode() : this.node
    return node.getProps()
  }

  // Public Api

  setValue = (field, value) => {
    this.props.dispatch(actions.setValue({ field, value }))
    // Validate up the tree
    this.recurseUpFromNode(field, node => node.api.preValidate())
    this.recurseUpFromNode(field, node => node.api.validate())
    this.recurseUpFromNode(field, node => node.api.asyncValidate())
  }

  setTouched = (field, value = true) => {
    this.props.dispatch(actions.setTouched({ field, value }))
    // Validate up the tree
    this.recurseUpFromNode(field, node => node.api.preValidate())
    this.recurseUpFromNode(field, node => node.api.validate())
    this.recurseUpFromNode(field, node => node.api.asyncValidate())
  }

  setError = (field, value) => {
    this.props.dispatch(actions.setError({ field, value }))
  }

  setWarning = (field, value) => {
    this.props.dispatch(actions.setWarning({ field, value }))
  }

  setSuccess = (field, value) => {
    this.props.dispatch(actions.setSuccess({ field, value }))
  }

  preValidate = (field, opts = {}) => {
    // Get the preValidate prop from the field node
    const { preValidate } = this.getFieldProps(field)
    if (preValidate === Utils.noop || (!opts.submitting && this.props.validateOnSubmit)) {
      return
    }
    this.props.dispatch(actions.preValidate({ field, validator: preValidate }))
  }

  validate = (field, opts = {}) => {
    // Get the validate prop from the field node
    const { validate } = this.getFieldProps(field)
    if (validate === Utils.noop || (!opts.submitting && this.props.validateOnSubmit)) {
      return
    }
    this.props.dispatch(actions.validate({ field, validator: validate }))
  }

  asyncValidate = (field, opts = {}) => {
    // Get the asyncValidate prop from the field node
    const { asyncValidate } = this.getFieldProps(field)
    if (asyncValidate === Utils.noop || (!opts.submitting && this.props.validateOnSubmit)) {
      return
    }
    this.props.dispatch(
      actions.asyncValidate({
        field,
        validator: asyncValidate,
        validationPromiseIDs: this.validationPromiseIDs
      })
    )
  }

  // TODO: array syntax does not work well here
  setAllTouched = () => {
    // Set touched is unique because we dont want to set touched on nested fields
    // We also dont want to call the internal setTouched because that would
    // Execute validation.
    this.recurseUpAllNodes(node => {
      if (node.nested) {
        return
      }
      if (node.fullField) {
        this.props.dispatch(actions.setTouched({ field: node.fullField, value: true }))
      }
    })
  }

  setAllValues = (values = {}) =>
    this.props.dispatch(
      actions.setAllValues({
        ...this.props.defaultValues,
        ...values
      })
    )

  preValidateAll = () => {
    this.recurseUpAllNodes(node => {
      if (node.api.preValidate) {
        node.api.preValidate({ submitting: true })
      }
    })
  }

  validateAll = () => {
    this.recurseUpAllNodes(node => {
      if (node.api.validate) {
        node.api.validate({ submitting: true })
      }
    })
  }

  asyncValidateAll = () =>
    this.recurseUpAllNodes(node => {
      if (node.api.asyncValidate) {
        return node.api.asyncValidate({ submitting: true })
      }
    })

  setFormState = formState => {
    this.props.dispatch(actions.setFormState(formState))
  }

  getTouched = field => Utils.get(this.props.formState.touched, field)

  getValue = field => Utils.get(this.props.formState.values, field)

  getError = field => Utils.get(this.props.formState.errors, field)

  getWarning = field => Utils.get(this.props.formState.warnings, field)

  getSuccess = field => Utils.get(this.props.formState.successes, field)

  getFullField = field => field

  addValue = (field, value) => {
    this.props.dispatch(
      actions.setValue({
        field,
        value: [...(Utils.get(this.props.formState.values, field) || []), value]
      })
    )
  }

  removeValue = (field, index) => {
    const fieldValue = Utils.get(this.props.formState.values, field) || []
    this.props.dispatch(
      actions.setValue({
        field,
        value: [...fieldValue.slice(0, index), ...fieldValue.slice(index + 1)]
      })
    )
    const fieldTouched = Utils.get(this.props.formState.touched, field) || []
    this.props.dispatch(
      actions.setTouched({
        field,
        value: [...fieldTouched.slice(0, index), ...fieldTouched.slice(index + 1)]
      })
    )
  }

  swapValues = (field, index, destIndex) => {
    const min = Math.min(index, destIndex)
    const max = Math.max(index, destIndex)

    const fieldValues = Utils.get(this.props.formState.values, field) || []

    this.props.dispatch(
      actions.setValue({
        field,
        value: [
          ...fieldValues.slice(0, min),
          fieldValues[max],
          ...fieldValues.slice(min + 1, max),
          fieldValues[min],
          ...fieldValues.slice(max + 1)
        ]
      })
    )
  }

  register = node => this.tree.addNode(node)

  deregister = node => this.tree.removeNode(node)

  reset = field => {
    this.props.dispatch(actions.reset({ field }))
  }

  resetAll = () => {
    this.props.dispatch(actions.resetAll())
  }

  clearAll = () => {
    this.props.dispatch(actions.clearAll())
  }

  submitForm = async e => {
    this.props.dispatch(actions.submitting(true))
    this.props.dispatch(actions.submits())
    this.setAllTouched()
    this.preValidateAll()
    this.validateAll()

    // We prevent default, by default, unless override is passed
    if (e && e.preventDefault && this.props.preventDefault) {
      e.preventDefault(e)
    }
    // We need to prevent default if override is passed and form is invalid
    if (!this.props.preventDefault) {
      // Pull off errors from form state
      const { errors, asyncErrors } = this.props.formState
      // Check to see if its invalid
      const invalid = isInvalid(errors) || isInvalid(asyncErrors)
      // Prevent default becaues form is invalid
      if (invalid && e && e.preventDefault) {
        e.preventDefault(e)
      }
    }

    // Call asynchronous validators
    try {
      await this.asyncValidateAll()
    } catch (err) {
      // Let the user know we are done submitting
      this.props.dispatch(actions.submitting(false))
      throw err
    }
    // Pull off errors from form state
    const { errors, asyncErrors } = this.props.formState
    // Only submit if we have no errors
    const invalid = isInvalid(errors)
    const asyncInvalid = isInvalid(asyncErrors)
    // Call on validation fail if we are invalid
    if ((invalid || asyncInvalid) && this.props.onSubmitFailure) {
      this.props.onSubmitFailure(errors, null, this.getFormApi())
    }
    // Only update submitted if we are not invalid
    // And there are no active asynchronous validations
    if (!(invalid || asyncInvalid) && this.props.formState.asyncValidations === 0) {
      let values = JSON.parse(JSON.stringify(this.props.formState.values))
      // Call pre submit
      if (this.props.preSubmit) {
        values = this.props.preSubmit(values)
      }
      // Update submitted
      this.props.dispatch(actions.submitted())
      // If onSubmit was passed then call it
      if (this.props.onSubmit) {
        try {
          await this.props.onSubmit(values, e, this.getFormApi())
        } catch (error) {
          if (this.props.onSubmitFailure) {
            this.props.onSubmitFailure({}, error, this.getFormApi())
          } else {
            throw error
          }
        }
      }
    }
    // Let the user know we are done submitting
    this.props.dispatch(actions.submitting(false))
  }

  render () {
    const { children, component, render } = this.props

    const formApi = this.getFormApi()
    const formState = this.getFormState()

    const inlineProps = {
      ...formApi,
      ...formState
    }

    const componentProps = {
      formApi: {
        ...formApi,
        ...formState
      }
    }

    if (component) {
      return React.createElement(component, componentProps, children)
    }
    if (render) {
      return render(inlineProps)
    }
    if (typeof children === 'function') {
      return children(inlineProps)
    }
    return children
  }
}

Form.childContextTypes = {
  formApi: PropTypes.object,
  formState: PropTypes.object,
  formProps: PropTypes.object
}

Form.defaultProps = {
  pure: true,
  preventDefault: true,
  defaultValues: {}
}

/* ---------- Container ---------- */

const mapStateToProps = state => ({
  formState: state
})

const mapDispatchToProps = dispatch => ({
  dispatch
})

const FormContainer = connect(mapStateToProps, mapDispatchToProps)(Form)

/* ---------- Exports ---------- */
class ReactForm extends Component {
  constructor (props) {
    super(props)

    const { defaultValues, values } = props

    this.store = createStore(
      BuildReducer({
        defaultValues,
        values
      }),
      applyMiddleware(
        thunkMiddleware // lets us dispatch() functions
        // createLogger() // neat middleware that logs actions
      )
    )
  }

  render () {
    const { children, ...rest } = this.props

    return (
      <FormContainer store={this.store} {...rest}>
        {children}
      </FormContainer>
    )
  }
}

export default ReactForm
<commit_msg>recurseUpFromNode can now optionally be synchronous<commit_after>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import thunkMiddleware from 'redux-thunk'
import { createStore, applyMiddleware } from 'redux'
import { connect } from 'react-redux'

import BuildReducer from '../redux/BuildReducer'
import * as actions from '../redux/actions'
import Utils from '../utils'
import Tree, { makeNode } from '../utils/Tree'

/* ---------------------------- Helper Methods ----------------------------- */

/* ----- Recursive Check to see if form is valid  ----- */

const isInvalid = errors => {
  if (Array.isArray(errors)) {
    return errors.some(k => isInvalid(k))
  } else if (errors !== null && typeof errors === 'object') {
    return Object.keys(errors).some(k => isInvalid(errors[k]))
  }
  return errors
}

/* -------------- Generates a new state ------------- */

// TODO figure out way to make state immutable
const newState = state => JSON.parse(JSON.stringify(state))

/* ----------------- Form Component ---------------- */

class Form extends Component {
  constructor (props) {
    super(props)
    this.tree = new Tree({
      nested: true,
      children: {},
      api: {
        ...this.getFormApi(),
        validate: opts => this.validate(undefined, opts),
        preValidate: opts => this.preValidate(undefined, opts),
        asyncValidate: opts => this.asyncValidate(undefined, opts)
      },
      getProps: () => this.props
    })
    this.node = this.tree.root
    this.validationPromiseIDs = new Map()
  }

  getChildContext () {
    return {
      formApi: this.getFormApi(),
      formState: this.getFormState(),
      formProps: this.props
    }
  }

  componentWillMount () {
    if (this.props.getApi) {
      this.props.getApi(this.getFormApi())
    }
  }

  componentDidMount () {
    if (this.props.validateOnMount) {
      this.preValidateAll()
      this.validateAll()
      this.asyncValidateAll()
    }
  }

  componentWillReceiveProps (nextProps) {
    const didUpdate = !Utils.isDeepEqual(nextProps.formState, this.props.formState)
    if (this.props.onChange && didUpdate) {
      this.props.onChange(newState(nextProps.formState), this.getFormApi())
    }
    if (!Utils.isDeepEqual(nextProps.values, this.props.values)) {
      this.setAllValues(nextProps.values)
    }
  }

  getFormApi () {
    return {
      submitForm: this.submitForm,
      setValue: this.setValue,
      getValue: this.getValue,
      setTouched: this.setTouched,
      getTouched: this.getTouched,
      getWarning: this.getWarning,
      getError: this.getError,
      getSuccess: this.getSuccess,
      getFormState: this.getFormState,
      setFormState: this.setFormState,
      setError: this.setError,
      setWarning: this.setWarning,
      setSuccess: this.setSuccess,
      resetAll: this.resetAll,
      reset: this.reset,
      clearAll: this.clearAll,
      addValue: this.addValue,
      removeValue: this.removeValue,
      setAllValues: this.setAllValues,
      setAllTouched: this.setAllTouched,
      swapValues: this.swapValues,
      register: this.register,
      deregister: this.deregister,
      asyncValidate: this.asyncValidate,
      validate: this.validate,
      preValidate: this.preValidate,
      getFullField: this.getFullField
    }
  }

  // Utils

  getFormState = () => newState(this.props.formState)

  recurseUpFromNode = (field, cb, sync) => {
    // Find the node using the field
    const target = this.tree.getNodeByField(field, { closest: true })

    // If there is no target at all, stop
    if (!target) {
      return
    }

    // Define recur function
    const recurse = sync
      ? node => {
        // Call the cb with the node
        cb(node)
        // If we have parent recur up
        if (node.parent) {
          recurse(node.parent)
        }
      }
      : async node => {
        // Call the cb with the node
        await cb(node)
        // If we have parent recur up
        if (node.parent) {
          recurse(node.parent)
        }
      }

    // start recursion from the target
    try {
      return recurse(target)
    } catch (err) {
      throw err
    }
  }

  recurseUpAllNodes = cb => {
    // Define recur function

    const recurse = async node => {
      // If we have children recurse down
      if (node.children) {
        await Promise.all(Utils.mapObject(node.children, recurse))
      }
      // Call the cb with the node
      await cb(node)
    }

    // start recursion from the target
    try {
      return recurse(this.node)
    } catch (err) {
      throw err
    }
  }

  getFieldProps = field => {
    const node = field ? this.tree.getNodeByField(field) || makeNode() : this.node
    return node.getProps()
  }

  // Public Api

  setValue = (field, value) => {
    this.props.dispatch(actions.setValue({ field, value }))
    // Validate up the tree
    this.recurseUpFromNode(field, node => node.api.preValidate())
    this.recurseUpFromNode(field, node => node.api.validate())
    this.recurseUpFromNode(field, node => node.api.asyncValidate())
  }

  setTouched = (field, value = true) => {
    this.props.dispatch(actions.setTouched({ field, value }))
    // Validate up the tree
    this.recurseUpFromNode(field, node => node.api.preValidate())
    this.recurseUpFromNode(field, node => node.api.validate())
    this.recurseUpFromNode(field, node => node.api.asyncValidate())
  }

  setError = (field, value) => {
    this.props.dispatch(actions.setError({ field, value }))
  }

  setWarning = (field, value) => {
    this.props.dispatch(actions.setWarning({ field, value }))
  }

  setSuccess = (field, value) => {
    this.props.dispatch(actions.setSuccess({ field, value }))
  }

  preValidate = (field, opts = {}) => {
    // Get the preValidate prop from the field node
    const { preValidate } = this.getFieldProps(field)
    if (preValidate === Utils.noop || (!opts.submitting && this.props.validateOnSubmit)) {
      return
    }
    this.props.dispatch(actions.preValidate({ field, validator: preValidate }))
  }

  validate = (field, opts = {}) => {
    // Get the validate prop from the field node
    const { validate } = this.getFieldProps(field)
    if (validate === Utils.noop || (!opts.submitting && this.props.validateOnSubmit)) {
      return
    }
    this.props.dispatch(actions.validate({ field, validator: validate }))
  }

  asyncValidate = (field, opts = {}) => {
    // Get the asyncValidate prop from the field node
    const { asyncValidate } = this.getFieldProps(field)
    if (asyncValidate === Utils.noop || (!opts.submitting && this.props.validateOnSubmit)) {
      return
    }
    this.props.dispatch(
      actions.asyncValidate({
        field,
        validator: asyncValidate,
        validationPromiseIDs: this.validationPromiseIDs
      })
    )
  }

  // TODO: array syntax does not work well here
  setAllTouched = () => {
    // Set touched is unique because we dont want to set touched on nested fields
    // We also dont want to call the internal setTouched because that would
    // Execute validation.
    this.recurseUpAllNodes(node => {
      if (node.nested) {
        return
      }
      if (node.fullField) {
        this.props.dispatch(actions.setTouched({ field: node.fullField, value: true }))
      }
    })
  }

  setAllValues = (values = {}) =>
    this.props.dispatch(
      actions.setAllValues({
        ...this.props.defaultValues,
        ...values
      })
    )

  preValidateAll = () => {
    this.recurseUpAllNodes(node => {
      if (node.api.preValidate) {
        node.api.preValidate({ submitting: true })
      }
    })
  }

  validateAll = () => {
    this.recurseUpAllNodes(node => {
      if (node.api.validate) {
        node.api.validate({ submitting: true })
      }
    })
  }

  asyncValidateAll = () =>
    this.recurseUpAllNodes(node => {
      if (node.api.asyncValidate) {
        return node.api.asyncValidate({ submitting: true })
      }
    })

  setFormState = formState => {
    this.props.dispatch(actions.setFormState(formState))
  }

  getTouched = field => Utils.get(this.props.formState.touched, field)

  getValue = field => Utils.get(this.props.formState.values, field)

  getError = field => Utils.get(this.props.formState.errors, field)

  getWarning = field => Utils.get(this.props.formState.warnings, field)

  getSuccess = field => Utils.get(this.props.formState.successes, field)

  getFullField = field => field

  addValue = (field, value) => {
    this.props.dispatch(
      actions.setValue({
        field,
        value: [...(Utils.get(this.props.formState.values, field) || []), value]
      })
    )
  }

  removeValue = (field, index) => {
    const fieldValue = Utils.get(this.props.formState.values, field) || []
    this.props.dispatch(
      actions.setValue({
        field,
        value: [...fieldValue.slice(0, index), ...fieldValue.slice(index + 1)]
      })
    )
    const fieldTouched = Utils.get(this.props.formState.touched, field) || []
    this.props.dispatch(
      actions.setTouched({
        field,
        value: [...fieldTouched.slice(0, index), ...fieldTouched.slice(index + 1)]
      })
    )
  }

  swapValues = (field, index, destIndex) => {
    const min = Math.min(index, destIndex)
    const max = Math.max(index, destIndex)

    const fieldValues = Utils.get(this.props.formState.values, field) || []

    this.props.dispatch(
      actions.setValue({
        field,
        value: [
          ...fieldValues.slice(0, min),
          fieldValues[max],
          ...fieldValues.slice(min + 1, max),
          fieldValues[min],
          ...fieldValues.slice(max + 1)
        ]
      })
    )
  }

  register = node => this.tree.addNode(node)

  deregister = node => this.tree.removeNode(node)

  reset = field => {
    this.props.dispatch(actions.reset({ field }))
  }

  resetAll = () => {
    this.props.dispatch(actions.resetAll())
  }

  clearAll = () => {
    this.props.dispatch(actions.clearAll())
  }

  submitForm = async e => {
    this.props.dispatch(actions.submitting(true))
    this.props.dispatch(actions.submits())
    this.setAllTouched()
    this.preValidateAll()
    this.validateAll()

    // We prevent default, by default, unless override is passed
    if (e && e.preventDefault && this.props.preventDefault) {
      e.preventDefault(e)
    }
    // We need to prevent default if override is passed and form is invalid
    if (!this.props.preventDefault) {
      // Pull off errors from form state
      const { errors, asyncErrors } = this.props.formState
      // Check to see if its invalid
      const invalid = isInvalid(errors) || isInvalid(asyncErrors)
      // Prevent default becaues form is invalid
      if (invalid && e && e.preventDefault) {
        e.preventDefault(e)
      }
    }

    // Call asynchronous validators
    try {
      await this.asyncValidateAll()
    } catch (err) {
      // Let the user know we are done submitting
      this.props.dispatch(actions.submitting(false))
      throw err
    }
    // Pull off errors from form state
    const { errors, asyncErrors } = this.props.formState
    // Only submit if we have no errors
    const invalid = isInvalid(errors)
    const asyncInvalid = isInvalid(asyncErrors)
    // Call on validation fail if we are invalid
    if ((invalid || asyncInvalid) && this.props.onSubmitFailure) {
      this.props.onSubmitFailure(errors, null, this.getFormApi())
    }
    // Only update submitted if we are not invalid
    // And there are no active asynchronous validations
    if (!(invalid || asyncInvalid) && this.props.formState.asyncValidations === 0) {
      let values = JSON.parse(JSON.stringify(this.props.formState.values))
      // Call pre submit
      if (this.props.preSubmit) {
        values = this.props.preSubmit(values)
      }
      // Update submitted
      this.props.dispatch(actions.submitted())
      // If onSubmit was passed then call it
      if (this.props.onSubmit) {
        try {
          await this.props.onSubmit(values, e, this.getFormApi())
        } catch (error) {
          if (this.props.onSubmitFailure) {
            this.props.onSubmitFailure({}, error, this.getFormApi())
          } else {
            throw error
          }
        }
      }
    }
    // Let the user know we are done submitting
    this.props.dispatch(actions.submitting(false))
  }

  render () {
    const { children, component, render } = this.props

    const formApi = this.getFormApi()
    const formState = this.getFormState()

    const inlineProps = {
      ...formApi,
      ...formState
    }

    const componentProps = {
      formApi: {
        ...formApi,
        ...formState
      }
    }

    if (component) {
      return React.createElement(component, componentProps, children)
    }
    if (render) {
      return render(inlineProps)
    }
    if (typeof children === 'function') {
      return children(inlineProps)
    }
    return children
  }
}

Form.childContextTypes = {
  formApi: PropTypes.object,
  formState: PropTypes.object,
  formProps: PropTypes.object
}

Form.defaultProps = {
  pure: true,
  preventDefault: true,
  defaultValues: {}
}

/* ---------- Container ---------- */

const mapStateToProps = state => ({
  formState: state
})

const mapDispatchToProps = dispatch => ({
  dispatch
})

const FormContainer = connect(mapStateToProps, mapDispatchToProps)(Form)

/* ---------- Exports ---------- */
class ReactForm extends Component {
  constructor (props) {
    super(props)

    const { defaultValues, values } = props

    this.store = createStore(
      BuildReducer({
        defaultValues,
        values
      }),
      applyMiddleware(
        thunkMiddleware // lets us dispatch() functions
        // createLogger() // neat middleware that logs actions
      )
    )
  }

  render () {
    const { children, ...rest } = this.props

    return (
      <FormContainer store={this.store} {...rest}>
        {children}
      </FormContainer>
    )
  }
}

export default ReactForm
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import { MAPS_JS_API_KEY, GA_TRACKING_ID } from '../config';

function Html({ title, description, style, script, children, lang, state }) {

  return (

        <meta charSet="utf-8" />
        <meta httpEquiv="x-ua-compatible" content="ie=edge" />
        <title>{title}</title>
        <meta name="description" content={description} />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="apple-touch-icon" href="apple-touch-icon.png" />
        <link rel="stylesheet" href="/css/material-icons.css" />
        <link rel="stylesheet" href="/css/common.css" />


<commit_before>import React, { Component } from 'react'
import { Link } from 'react-router-dom'

const capitalize = require('capitalize')

class Post extends Component {

  voteClicker(id, vote){
    this.props.votePost({id, vote});
  }

  render() {
    const { post, removePost, votePost } = this.props
    const id = post.id

    return(

        <Link to={`/${post.category}/${post.id}`}>

{post.title}

        </Link>

          posted by {post.author} on {post.timestamp} in <Link to={`/${post.category}`}>{capitalize(post.category)}</Link> category
          [#] comments

            <button onClick={() => this.voteClicker(id, 'downVote')} className="btn btn-primary">↓</button>
            {post.voteScore}
            <button onClick={() => this.voteClicker(id, 'upVote')} className="btn btn-primary">↑</button>

          <button onClick={() => removePost({id})} className="btn btn-primary">Delete</button>

    )
  }

}

export default Post
<commit_msg>Fix date output in category view<commit_after>import React, { Component } from 'react'
import { Link } from 'react-router-dom'

const capitalize = require('capitalize')

class Post extends Component {

  voteClicker(id, vote){
    this.props.votePost({id, vote});
  }

  render() {
    const { post, removePost, votePost } = this.props
    const id = post.id

    let timestamp = new Date(post.timestamp)

    let options = {
        year: "numeric", month: "short", day: "numeric", hour: "2-digit", minute: "2-digit"
    }

    let postDate = timestamp.toLocaleTimeString("en-us", options)

    return(

        <Link to={`/${post.category}/${post.id}`}>

{post.title}

        </Link>

          posted by {post.author} on {postDate} in <Link to={`/${post.category}`}>{capitalize(String(post.category))}</Link> category
          [#] comments

            <button onClick={() => this.voteClicker(id, 'downVote')} className="btn btn-primary">↓</button>
            {post.voteScore}
            <button onClick={() => this.voteClicker(id, 'upVote')} className="btn btn-primary">↑</button>

          <button onClick={() => removePost({id})} className="btn btn-primary">Delete</button>

    )
  }

}

export default Post
<|endoftext|>


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

const Book = ({ volumeInfo, parentComponent, clickedAddToWishlist, clickedRemoveFromWishlist, id, clickedAddToCurrentlyReading, clickedRemoveFromCurrentlyReading, clickedAddToCompleted, clickedRemoveFromCompleted }) => {
  return(

{volumeInfo.title}

        { volumeInfo.imageLinks ?  : null }

{volumeInfo.authors[0]}

        { parentComponent === 'wishlist' ?

            <button className="btn btn-info btn-block" onClick={ () => clickedRemoveFromWishlist(id)}>Remove From WishList</button>
            <button className="btn btn-info btn-block" onClick={ () => clickedAddToCurrentlyReading(id)}>Add To Currently Reading</button>
            <button className="btn btn-info btn-block" onClick={ () => clickedAddToCompleted(id)}>Add To Completed</button>

          : null
        }
        { parentComponent === 'home' ?

            <button className="btn btn-info btn-block" onClick={ () => clickedAddToCurrentlyReading(id)}>Add To Currently Reading</button>
            <button className="btn btn-info btn-block" onClick={ () => clickedAddToWishlist(id)}>Add To WishList</button>
            <button className="btn btn-info btn-block" onClick={ () => clickedAddToCompleted(id)}>Add To Completed</button>

          : null
        }
        { parentComponent === 'currently_reading' ?

            <button className="btn btn-info btn-block" onClick={ () => clickedAddToWishlist(id)}>Add To WishList</button>
            <button className="btn btn-info btn-block" onClick={ () => clickedAddToCompleted(id)}>Add To Completed</button>
            <button className="btn btn-info btn-block" onClick={ () => clickedRemoveFromCurrentlyReading(id)}>Remove From Currently Reading</button>

          : null
        }
        { parentComponent === 'completed' ?

            <button className="btn btn-info btn-block" onClick={ () => clickedAddToWishlist(id)}>Add To WishList</button>
            <button className="btn btn-info btn-block" onClick={ () => clickedAddToCurrentlyReading(id)}>Add To Currently Reading</button>
            <button className="btn btn-info btn-block" onClick={ () => clickedRemoveFromCompleted(id)}>Remove From Completed</button>

          : null
        }

  )
}

export default Book<commit_msg>reformatted book component and added styling classes<commit_after>import React, { PropTypes } from 'react'

const Book = ({ volumeInfo, parentComponent, clickedAddToWishlist, clickedRemoveFromWishlist, id, clickedAddToCurrentlyReading, clickedRemoveFromCurrentlyReading, clickedAddToCompleted, clickedRemoveFromCompleted }) => {
  return(

          { volumeInfo.imageLinks ?  : null }

{volumeInfo.title}

{volumeInfo.authors[0]}

                    { parentComponent === 'wishlist' ?

                        <button className="btn btn-success" onClick={ () => clickedRemoveFromWishlist(id)}>Remove From WishList</button>
                        <button className="btn btn-success" onClick={ () => clickedAddToCurrentlyReading(id)}>Add To Currently Reading</button>
                        <button className="btn btn-success" onClick={ () => clickedAddToCompleted(id)}>Add To Completed</button>

                      : null
                    }
                    { parentComponent === 'home' ?

                        <button className="btn btn-success" onClick={ () => clickedAddToCurrentlyReading(id)}>Add To Currently Reading</button>
                        <button className="btn btn-success" onClick={ () => clickedAddToWishlist(id)}>Add To WishList</button>
                        <button className="btn btn-success" onClick={ () => clickedAddToCompleted(id)}>Add To Completed</button>

                      : null
                    }
                    { parentComponent === 'currently_reading' ?

                        <button className="btn btn-success" onClick={ () => clickedAddToWishlist(id)}>Add To WishList</button>
                        <button className="btn btn-success" onClick={ () => clickedAddToCompleted(id)}>Add To Completed</button>
                        <button className="btn btn-success" onClick={ () => clickedRemoveFromCurrentlyReading(id)}>Remove From Currently Reading</button>

                      : null
                    }
                    { parentComponent === 'completed' ?

                        <button className="btn btn-success" onClick={ () => clickedAddToWishlist(id)}>Add To WishList</button>
                        <button className="btn btn-success" onClick={ () => clickedAddToCurrentlyReading(id)}>Add To Currently Reading</button>
                        <button className="btn btn-success" onClick={ () => clickedRemoveFromCompleted(id)}>Remove From Completed</button>

                      : null
                    }

  )
}

export default Book<|endoftext|>