<commit_before>/*---------------------------------------------------------------------------/
 *
 *  textselect.js
 *
 *  Author: Declan de Wet <declandewet@me.com>
 *  Version: 0.0.1
 *  License: MIT
 *
 *  This script will trigger an event `textselect` when text is highlighted
 *  on the page. It's only dependency is jQuery.
 *
 *--------------------------------------------------------------------------*/

// enclose code in top-level function scope to prevent creation of globals
(function() {

  /**
   * @function getSelectedTextContent
   * @return {String} Content within a highlighted selection, if any present.
   *
   * Immediately-invoked self-modifying function.
   * Executes instantly and uses feature detection to determine the text
   * selection method the browser supports, then modifies itself to return
   * the value returned by that method any time it is manually called.
   */
  var getSelectedTextContent = (function() {
    if (window.getSelection) {
      return function() {
        return window.getSelection().toString();
      };
    } else if (document.getSelection) {
      return function() {
        return document.getSelection();
      };
    } else if (document.selection) {
      return function() {
        return document.selection.createRange().text;
      };
    }
  }).apply(this);

  /**
   * @function getSelectionInformation
   * @return {Object} Contains coordinate and size properties of selection.
   *
   * Immediately-invoked self-modifying function.
   * Executes instantly and uses feature detection to determine the
   * method to use to get location and size information about the current
   * selection, if any - then modifes itself to return the output of
   * that method.
   *
   * N.B. - Temporary implementation until more research is done on
   * supporting more browsers.
   */
  var getSelectionInformation = (function(){
    if (window.getSelection) {
      return function() {
        return window.getSelection().getRangeAt(0).getBoundingClientRect();
      };
    }
  }).apply(this);

  // the below 3 variables are used to prevent triggering the event
  // when selected text is deselected on mouse click, as well as to
  // ensure that text is actually selected before triggering the event

  // stores selection text content
  var selectionText = '',
  // used to determine active state of selection
  isTextSelected = false,
  // used to ensure current selection content is not same as the previous one
  previousSelection;

  /**
   * @function triggerSelectedTextEvent
   * @param  {Object} $el [a jQuery DOM Element object]
   * @returns nothing
   *
   * Determines current state of the selection and triggers the `textselect`
   * event on the element passed to it
   */
  var triggerSelectedTextEvent = function($el) {

    // get the selection text
    selectionText = getSelectedTextContent();

    // store the selection coords/size in this
    var selectionInformation;

    // sugary syntax for easy reading
    var selectionNotEmpty = (selectionText !== ''),
        uniqueSelection = (selectionText !== previousSelection);

    // we do not want to trigger the `textselect` event if the selection
    // is empty, if the user is clicking off a selection, or if the user
    // is clicking on a selection to unselect it
    if (selectionNotEmpty && uniqueSelection) {

      // get the coordinates and size of the selection
      selectionInformation = getSelectionInformation();

      // trigger the event and attach selection object parameters
      $el.trigger('textselect', {
        top: selectionInformation.top,
        bottom: selectionInformation.bottom,
        left: selectionInformation.left,
        right: selectionInformation.right,
        width: selectionInformation.width,
        height: selectionInformation.height,
        text: selectionText
      });

    }

    // store the most recent selection for the next check
    previousSelection = selectionText;

    // reset selection content
    selectionText = '';

  };

  /**
   * @function attachSelectedTextEvent
   * @param  {Object} event
   *
   * This is a jQuery event callback that listens for mouseup/keyup events and
   * passes an element to triggerSelectedTextEvent which then determines
   * whether or not to trigger a `textselect` event.
   */
  var attachSelectedTextEvent = function(event) {

    var keyup = (event.type === 'keyup'),
        shiftKey = (event.which === 16),
        mouseup = (event.type === 'mouseup'),
        $el = $(event.target);

    // if the event was a keyup, and that key was the shift key,
    // or if the event was a mouseup, call triggerSelectedTextEvent
    // and pass the element the event was triggered on as a parameter
    if ((keyup && shiftKey) || mouseup) {
      triggerSelectedTextEvent($el);
    }

  };

  // check if jQuery is loaded
  if (window.$) {

    // jQuery is loaded, let's wait until the dom is ready...
    $(function() {

      // ...and attach the selected text event listener to the document
      $(document).on('mouseup keyup', attachSelectedTextEvent);

    });

  // uhoh, jQuery isn't loaded.
  } else {

    // we'd better warn the user
    var errorMessage = "textselect.js depends on jQuery in order to " +
                       "function. Please ensure that you have loaded " +
                       "jQuery and that this script is loaded afterwards.";

    throw new Error(errorMessage);

  }

}).call(this);
<commit_msg>Make getSelectionInformation work <IE9<commit_after>/*---------------------------------------------------------------------------/
 *
 *  textselect.js
 *
 *  Author: Declan de Wet <declandewet@me.com>
 *  Version: 0.0.1
 *  License: MIT
 *
 *  This script will trigger an event `textselect` when text is highlighted
 *  on the page. It's only dependency is jQuery.
 *
 *--------------------------------------------------------------------------*/

// enclose code in top-level function scope to prevent creation of globals
(function() {

  /**
   * @function getSelectedTextContent
   * @return {String} Content within a highlighted selection, if any present.
   *
   * Immediately-invoked self-modifying function.
   * Executes instantly and uses feature detection to determine the text
   * selection method the browser supports, then modifies itself to return
   * the value returned by that method any time it is manually called.
   */
  var getSelectedTextContent = (function() {
    if (window.getSelection) {
      return function() {
        return window.getSelection().toString();
      };
    } else if (document.getSelection) {
      return function() {
        return document.getSelection();
      };
    } else if (document.selection) {
      return function() {
        return document.selection.createRange().text;
      };
    }
  }).apply(this);

  /**
   * @function getSelectionInformation
   * @return {Object} Contains coordinate and size properties of selection.
   *
   * Immediately-invoked self-modifying function.
   * Executes instantly and uses feature detection to determine the
   * method to use to get location and size information about the current
   * selection, if any - then modifes itself to return the output of
   * that method.
   *
   * N.B. - Temporary implementation until more research is done on
   * supporting more browsers.
   */
  var getSelectionInformation = (function(){
    if (window.getSelection) {
      return function() {
        return window.getSelection().getRangeAt(0).getBoundingClientRect();
      };
    } else if (document.selection) {
      return function() {
        var rect = document.selection.createRange().getBoundingClientRect(),
            obj = {
              top: rect.top,
              bottom: rect.bottom,
              left: rect.left,
              right: rect.right,
              width: rect.right - rect.left,
              height: rect.bottom - rect.top
            };

        return obj;
      };
    }
  }).apply(this);

  // the below 3 variables are used to prevent triggering the event
  // when selected text is deselected on mouse click, as well as to
  // ensure that text is actually selected before triggering the event

  // stores selection text content
  var selectionText = '',
  // used to determine active state of selection
  isTextSelected = false,
  // used to ensure current selection content is not same as the previous one
  previousSelection;

  /**
   * @function triggerSelectedTextEvent
   * @param  {Object} $el [a jQuery DOM Element object]
   * @returns nothing
   *
   * Determines current state of the selection and triggers the `textselect`
   * event on the element passed to it
   */
  var triggerSelectedTextEvent = function($el) {

    // get the selection text
    selectionText = getSelectedTextContent();

    // store the selection coords/size in this
    var selectionInformation;

    // sugary syntax for easy reading
    var selectionNotEmpty = (selectionText !== ''),
        uniqueSelection = (selectionText !== previousSelection);

    // we do not want to trigger the `textselect` event if the selection
    // is empty, if the user is clicking off a selection, or if the user
    // is clicking on a selection to unselect it
    if (selectionNotEmpty && uniqueSelection) {

      // get the coordinates and size of the selection
      selectionInformation = getSelectionInformation();

      // trigger the event and attach selection object parameters
      $el.trigger('textselect', {
        top: selectionInformation.top,
        bottom: selectionInformation.bottom,
        left: selectionInformation.left,
        right: selectionInformation.right,
        width: selectionInformation.width,
        height: selectionInformation.height,
        text: selectionText
      });

    }

    // store the most recent selection for the next check
    previousSelection = selectionText;

    // reset selection content
    selectionText = '';

  };

  /**
   * @function attachSelectedTextEvent
   * @param  {Object} event
   *
   * This is a jQuery event callback that listens for mouseup/keyup events and
   * passes an element to triggerSelectedTextEvent which then determines
   * whether or not to trigger a `textselect` event.
   */
  var attachSelectedTextEvent = function(event) {

    var keyup = (event.type === 'keyup'),
        shiftKey = (event.which === 16),
        mouseup = (event.type === 'mouseup'),
        $el = $(event.target);

    // if the event was a keyup, and that key was the shift key,
    // or if the event was a mouseup, call triggerSelectedTextEvent
    // and pass the element the event was triggered on as a parameter
    if ((keyup && shiftKey) || mouseup) {
      triggerSelectedTextEvent($el);
    }

  };

  // check if jQuery is loaded
  if (window.$) {

    // jQuery is loaded, let's wait until the dom is ready...
    $(function() {

      // ...and attach the selected text event listener to the document
      $(document).on('mouseup keyup', attachSelectedTextEvent);

    });

  // uhoh, jQuery isn't loaded.
  } else {

    // we'd better warn the user
    var errorMessage = "textselect.js depends on jQuery in order to " +
                       "function. Please ensure that you have loaded " +
                       "jQuery and that this script is loaded afterwards.";

    throw new Error(errorMessage);

  }

}).call(this);
<|endoftext|>


<commit_before>var express = require("express");
var multer = require("multer");
var path = require('path');
var bodyParser = require('body-parser');

var low = require('lowdb');
var lowdbStorage = require('lowdb/file-async');

var app = express();

var fileStorage = multer.diskStorage({
    destination: function (req, file, callback) {
        callback(null, './app/assets/images');
    },
    filename: function (req, file, callback) {
        callback(null, file.fieldname + '-' + Date.now() + '.jpg');
    }
});

var db = low('./app/assets/db.json', { storage: lowdbStorage });
var upload = multer({ storage: fileStorage }).single('userPhoto');

app.use(bodyParser.json());                         // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // to support URL-encoded bodies
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    next();
});
app.use(express.static(path.join(__dirname, '/')));

// == API ============================================================================
app.get('/', function (req, res) {
    res.sendFile('/index.html');
});

// Upload profile picture
app.post('/api/upload', function (req, res) {
    upload(req, res, function (err) {
        if (err) {
            return res.end("Error uploading file.");
        }
        res.end("File is uploaded");
    });
});

// Get all users defined in json lowdb file
app.get('/getAllUsers/:name?', function (req, res) {
    if (req.params.name != undefined) {
        res.send(db('users').find({ name: req.params.name }));
    } else {
        res.send(db('users').value());
    }
});

// Add new user in the json lowdb file
app.post('/addUser', function (req, res) {
    db('users').push(req.body)
               .then(post => res.send(post));
});

// Delete user from json lowdb file
app.get('/deleteUser/:name', function (req, res) {
    db('users').remove({ name: req.params.name });
    res.send(db('users').value());
});

// == API ============================================================================

app.listen(3000, function () {
    console.log("Working on port 3000");
});<commit_msg>server.js<commit_after>var express = require("express");
var multer = require("multer");
var path = require('path');
var bodyParser = require('body-parser');

var low = require('lowdb');
var lowdbStorage = require('lowdb/file-async');

var app = express();

var fileStorage = multer.diskStorage({
    destination: function (req, file, callback) {
        callback(null, path.join(__dirname, '/app/assets/images'));
    },
    filename: function (req, file, callback) {
        callback(null, file.fieldname + '-' + Date.now() + '.jpg');
    }
});

var db = low(path.join(__dirname, '/app/assets/db.json'), { storage: lowdbStorage });
var upload = multer({ storage: fileStorage }).single('userPhoto');

app.use(bodyParser.json());                         // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // to support URL-encoded bodies
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    next();
});
app.use(express.static(path.join(__dirname, '/')));

// == API ============================================================================
app.get('/', function (req, res) {
    res.sendFile(path.join(__dirname, '/index.html'));
});

// Upload profile picture
app.post('/api/upload', function (req, res) {
    upload(req, res, function (err) {
        if (err) {
            return res.end("Error uploading file.");
        }
        res.end("File is uploaded");
    });
});

// Get all users defined in json lowdb file
app.get('/getAllUsers/:name?', function (req, res) {
    if (req.params.name != undefined) {
        res.send(db('users').find({ name: req.params.name }));
    } else {
        res.send(db('users').value());
    }
});

// Add new user in the json lowdb file
app.post('/addUser', function (req, res) {
    db('users').push(req.body)
               .then(post => res.send(post));
});

// Delete user from json lowdb file
app.get('/deleteUser/:name', function (req, res) {
    db('users').remove({ name: req.params.name });
    res.send(db('users').value());
});

// == API ============================================================================

app.listen(3000, function () {
    console.log("Working on port 3000");
});<|endoftext|>


<commit_before>'use strict';

var React = require('react');
var ReactNative = require('react-native');
var {
  PropTypes
} = React;
var {
  StyleSheet,
  PanResponder,
  View,
  TouchableHighlight
} = ReactNative;

var converter = require('./converter.js');
var mockProps = require('./mockProps.js');

var sliderProps = {
  values: PropTypes.arrayOf(PropTypes.number),

  onValuesChangeStart: PropTypes.func,
  onValuesChange: PropTypes.func,
  onValuesChangeFinish: PropTypes.func,

  sliderLength: PropTypes.number,
  sliderOrientation: PropTypes.string,
  touchDimensions: PropTypes.object,

  customMarker: PropTypes.func,

  min: PropTypes.number,
  max: PropTypes.number,
  step: PropTypes.number,

  optionsArray: PropTypes.array,

  containerStyle: View.propTypes.style,
  trackStyle: View.propTypes.style,
  selectedStyle: View.propTypes.style,
  unselectedStyle: View.propTypes.style,
  markerStyle: View.propTypes.style,
  pressedMarkerStyle: View.propTypes.style
};

var Slider = React.createClass({

  propTypes: sliderProps,

  getDefaultProps: function() {
    return mockProps;
  },

  getInitialState() {
    this.optionsArray = this.props.optionsArray || converter.createArray(this.props.min,this.props.max,this.props.step);
    this.stepLength = this.props.sliderLength/this.optionsArray.length;

    var initialValues = this.props.values.map(value => converter.valueToPosition(value,this.optionsArray,this.props.sliderLength));

    return {
      pressedOne: true,
      valueOne: this.props.values[0],
      valueTwo: this.props.values[1],
      pastOne: initialValues[0],
      pastTwo: initialValues[1],
      positionOne: initialValues[0],
      positionTwo: initialValues[1]
    };
  },

  componentWillMount() {
    var customPanResponder = function (start,move,end) {
      return PanResponder.create({
        onStartShouldSetPanResponder: (evt, gestureState) => true,
        onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
        onMoveShouldSetPanResponder: (evt, gestureState) => true,
        onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
        onPanResponderGrant: (evt, gestureState) => start(),
        onPanResponderMove: (evt, gestureState) => move(gestureState),
        onPanResponderTerminationRequest: (evt, gestureState) => true,
        onPanResponderRelease: (evt, gestureState) => end(gestureState),
        onPanResponderTerminate: (evt, gestureState) => end(gestureState),
        onShouldBlockNativeResponder: (evt, gestureState) => true
      })
    };

    this._panResponderOne = customPanResponder(this.startOne, this.moveOne, this.endOne);
    this._panResponderTwo = customPanResponder(this.startTwo, this.moveTwo, this.endTwo);

  },

  componentWillReceiveProps(nextProps) {
    var { values } = this.props;
    if (nextProps.values.join() !== values.join()) {
      this.set(nextProps);
    }
  },

  set(config) {
    var { max, min, optionsArray, step, values } = config || this.props;
    this.optionsArray = optionsArray || converter.createArray(min, max, step);
    this.stepLength = this.props.sliderLength/this.optionsArray.length;

    var initialValues = values.map(value => converter.valueToPosition(value,this.optionsArray,this.props.sliderLength));

    this.setState({
      pressedOne: true,
      valueOne: values[0],
      valueTwo: values[1],
      pastOne: initialValues[0],
      pastTwo: initialValues[1],
      positionOne: initialValues[0],
      positionTwo: initialValues[1]
    });
  },

  startOne () {
    this.props.onValuesChangeStart();
    this.setState({
      onePressed: !this.state.onePressed
    });
  },

  startTwo () {
    this.props.onValuesChangeStart();
    this.setState({
      twoPressed: !this.state.twoPressed
    });
  },

  moveOne(gestureState) {
    var unconfined = gestureState.dx + this.state.pastOne;
    var bottom     = 0;
    var top        = (this.state.positionTwo - this.stepLength) || this.props.sliderLength;
    var confined   = unconfined < bottom ? bottom : (unconfined > top ? top : unconfined);
    var value      = converter.positionToValue(this.state.positionOne, this.optionsArray, this.props.sliderLength);

    var slipDisplacement = this.props.touchDimensions.slipDisplacement;

    if (Math.abs(gestureState.dy) < slipDisplacement || !slipDisplacement) {
      this.setState({
        positionOne: confined
      });
    }
    if ( value !== this.state.valueOne ) {
      this.setState({
        valueOne: value
      }, function () {
        var change = [this.state.valueOne];
        if (this.state.valueTwo) {
          change.push(this.state.valueTwo);
        }
        this.props.onValuesChange(change);
      });
    }
  },

  moveTwo(gestureState) {
    var unconfined  = gestureState.dx + this.state.pastTwo;
    var bottom      = this.state.positionOne + this.stepLength;
    var top         = this.props.sliderLength;
    var confined    = unconfined < bottom ? bottom : (unconfined > top ? top : unconfined);
    var value       = converter.positionToValue(this.state.positionTwo, this.optionsArray, this.props.sliderLength);
    var slipDisplacement = this.props.touchDimensions.slipDisplacement;

    if (Math.abs(gestureState.dy) < slipDisplacement || !slipDisplacement) {
      this.setState({
        positionTwo: confined
      });
    }
    if ( value !== this.state.valueTwo ) {
      this.setState({
        valueTwo: value
      }, function () {
        this.props.onValuesChange([this.state.valueOne,this.state.valueTwo]);
      });
    }
  },

  endOne(gestureState) {
    this.setState({
      pastOne: this.state.positionOne,
      onePressed: !this.state.onePressed
    }, function () {
      var change = [this.state.valueOne];
      if (this.state.valueTwo) {
        change.push(this.state.valueTwo);
      }
      this.props.onValuesChangeFinish(change);
    });
  },

  endTwo(gestureState) {
    this.setState({
      twoPressed: !this.state.twoPressed,
      pastTwo: this.state.positionTwo,
    }, function () {
      this.props.onValuesChangeFinish([this.state.valueOne,this.state.valueTwo]);
    });
  },

  render() {

    var {positionOne, positionTwo} = this.state;
    var {selectedStyle, unselectedStyle, sliderLength} = this.props;
    var twoMarkers = positionTwo;

    var trackOneLength = positionOne;
    var trackOneStyle = twoMarkers ? unselectedStyle : selectedStyle;
    var trackThreeLength = twoMarkers ? sliderLength - (positionTwo) : 0;
    var trackThreeStyle = unselectedStyle;
    var trackTwoLength = sliderLength - trackOneLength - trackThreeLength;
    var trackTwoStyle = twoMarkers ? selectedStyle : unselectedStyle;
    var Marker = this.props.customMarker;
    var {slipDisplacement, height, width, borderRadius} = this.props.touchDimensions;
    var touchStyle = {
      height: height,
      width: width,
      left: -width/2,
      borderRadius: borderRadius || 0
    };

    return (
      <View style={[styles.container, this.props.containerStyle]}>
        <View style={[styles.fullTrack, {width:sliderLength}]}>
          <View style={[this.props.trackStyle, styles.track, trackOneStyle, {width: trackOneLength}]} />
          <View style={[this.props.trackStyle, styles.track, trackTwoStyle, {width: trackTwoLength}]}>
            <View
              style={[styles.touch,touchStyle]}
              ref={component => this._markerOne = component}
              {...this._panResponderOne.panHandlers}
            >
              <Marker
                pressed={this.state.onePressed}
                markerStyle={this.props.markerStyle}
                pressedMarkerStyle={this.props.pressedMarkerStyle}
              />
            </View>
          </View>
          {twoMarkers && (
            <View style={[this.props.trackStyle, styles.track, trackThreeStyle, {width: trackThreeLength}]}>
              {(positionOne !== this.props.sliderLength) && (
                <View
                  style={[styles.touch,touchStyle]}
                  ref={component => this._markerTwo = component}
                  {...this._panResponderTwo.panHandlers}
                >
                  <Marker
                    pressed={this.state.twoPressed}
                    markerStyle={this.props.markerStyle}
                    pressedMarkerStyle={this.props.pressedMarkerStyle}
                  />
                </View>
              )}
            </View>
          )}
        </View>
      </View>
    );
  }
});

module.exports = Slider;

var styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
  },
  fullTrack: {
    flexDirection: 'row',
  },
  track: {
    justifyContent: 'center'
  },
  touch: {
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'transparent'
  }
});
<commit_msg>fix(Markers): remove clipping on android<commit_after>'use strict';

var React = require('react');
var ReactNative = require('react-native');
var {
  PropTypes
} = React;
var {
  StyleSheet,
  PanResponder,
  View,
  TouchableHighlight
} = ReactNative;

var converter = require('./converter.js');
var mockProps = require('./mockProps.js');

var sliderProps = {
  values: PropTypes.arrayOf(PropTypes.number),

  onValuesChangeStart: PropTypes.func,
  onValuesChange: PropTypes.func,
  onValuesChangeFinish: PropTypes.func,

  sliderLength: PropTypes.number,
  sliderOrientation: PropTypes.string,
  touchDimensions: PropTypes.object,

  customMarker: PropTypes.func,

  min: PropTypes.number,
  max: PropTypes.number,
  step: PropTypes.number,

  optionsArray: PropTypes.array,

  containerStyle: View.propTypes.style,
  trackStyle: View.propTypes.style,
  selectedStyle: View.propTypes.style,
  unselectedStyle: View.propTypes.style,
  markerStyle: View.propTypes.style,
  pressedMarkerStyle: View.propTypes.style
};

var Slider = React.createClass({

  propTypes: sliderProps,

  getDefaultProps: function() {
    return mockProps;
  },

  getInitialState() {
    this.optionsArray = this.props.optionsArray || converter.createArray(this.props.min,this.props.max,this.props.step);
    this.stepLength = this.props.sliderLength/this.optionsArray.length;

    var initialValues = this.props.values.map(value => converter.valueToPosition(value,this.optionsArray,this.props.sliderLength));

    return {
      pressedOne: true,
      valueOne: this.props.values[0],
      valueTwo: this.props.values[1],
      pastOne: initialValues[0],
      pastTwo: initialValues[1],
      positionOne: initialValues[0],
      positionTwo: initialValues[1]
    };
  },

  componentWillMount() {
    var customPanResponder = function (start,move,end) {
      return PanResponder.create({
        onStartShouldSetPanResponder: (evt, gestureState) => true,
        onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
        onMoveShouldSetPanResponder: (evt, gestureState) => true,
        onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
        onPanResponderGrant: (evt, gestureState) => start(),
        onPanResponderMove: (evt, gestureState) => move(gestureState),
        onPanResponderTerminationRequest: (evt, gestureState) => true,
        onPanResponderRelease: (evt, gestureState) => end(gestureState),
        onPanResponderTerminate: (evt, gestureState) => end(gestureState),
        onShouldBlockNativeResponder: (evt, gestureState) => true
      })
    };

    this._panResponderOne = customPanResponder(this.startOne, this.moveOne, this.endOne);
    this._panResponderTwo = customPanResponder(this.startTwo, this.moveTwo, this.endTwo);

  },

  componentWillReceiveProps(nextProps) {
    var { values } = this.props;
    if (nextProps.values.join() !== values.join()) {
      this.set(nextProps);
    }
  },

  set(config) {
    var { max, min, optionsArray, step, values } = config || this.props;
    this.optionsArray = optionsArray || converter.createArray(min, max, step);
    this.stepLength = this.props.sliderLength/this.optionsArray.length;

    var initialValues = values.map(value => converter.valueToPosition(value,this.optionsArray,this.props.sliderLength));

    this.setState({
      pressedOne: true,
      valueOne: values[0],
      valueTwo: values[1],
      pastOne: initialValues[0],
      pastTwo: initialValues[1],
      positionOne: initialValues[0],
      positionTwo: initialValues[1]
    });
  },

  startOne () {
    this.props.onValuesChangeStart();
    this.setState({
      onePressed: !this.state.onePressed
    });
  },

  startTwo () {
    this.props.onValuesChangeStart();
    this.setState({
      twoPressed: !this.state.twoPressed
    });
  },

  moveOne(gestureState) {
    var unconfined = gestureState.dx + this.state.pastOne;
    var bottom     = 0;
    var top        = (this.state.positionTwo - this.stepLength) || this.props.sliderLength;
    var confined   = unconfined < bottom ? bottom : (unconfined > top ? top : unconfined);
    var value      = converter.positionToValue(this.state.positionOne, this.optionsArray, this.props.sliderLength);

    var slipDisplacement = this.props.touchDimensions.slipDisplacement;

    if (Math.abs(gestureState.dy) < slipDisplacement || !slipDisplacement) {
      this.setState({
        positionOne: confined
      });
    }
    if ( value !== this.state.valueOne ) {
      this.setState({
        valueOne: value
      }, function () {
        var change = [this.state.valueOne];
        if (this.state.valueTwo) {
          change.push(this.state.valueTwo);
        }
        this.props.onValuesChange(change);
      });
    }
  },

  moveTwo(gestureState) {
    var unconfined  = gestureState.dx + this.state.pastTwo;
    var bottom      = this.state.positionOne + this.stepLength;
    var top         = this.props.sliderLength;
    var confined    = unconfined < bottom ? bottom : (unconfined > top ? top : unconfined);
    var value       = converter.positionToValue(this.state.positionTwo, this.optionsArray, this.props.sliderLength);
    var slipDisplacement = this.props.touchDimensions.slipDisplacement;

    if (Math.abs(gestureState.dy) < slipDisplacement || !slipDisplacement) {
      this.setState({
        positionTwo: confined
      });
    }
    if ( value !== this.state.valueTwo ) {
      this.setState({
        valueTwo: value
      }, function () {
        this.props.onValuesChange([this.state.valueOne,this.state.valueTwo]);
      });
    }
  },

  endOne(gestureState) {
    this.setState({
      pastOne: this.state.positionOne,
      onePressed: !this.state.onePressed
    }, function () {
      var change = [this.state.valueOne];
      if (this.state.valueTwo) {
        change.push(this.state.valueTwo);
      }
      this.props.onValuesChangeFinish(change);
    });
  },

  endTwo(gestureState) {
    this.setState({
      twoPressed: !this.state.twoPressed,
      pastTwo: this.state.positionTwo,
    }, function () {
      this.props.onValuesChangeFinish([this.state.valueOne,this.state.valueTwo]);
    });
  },

  render() {
    var {positionOne, positionTwo} = this.state;
    var {selectedStyle, unselectedStyle, sliderLength} = this.props;
    var twoMarkers = positionTwo;

    var fixedPositionOne = Math.floor(positionOne / this.stepLength) * this.stepLength;
    var fixedPositionTwo = Math.floor(positionTwo / this.stepLength) * this.stepLength;

    var trackOneLength = fixedPositionOne;
    var trackOneStyle = twoMarkers ? unselectedStyle : selectedStyle;
    var trackThreeLength = twoMarkers ? sliderLength - (fixedPositionTwo) : 0;
    var trackThreeStyle = unselectedStyle;
    var trackTwoLength = sliderLength - trackOneLength - trackThreeLength;
    var trackTwoStyle = twoMarkers ? selectedStyle : unselectedStyle;
    var Marker = this.props.customMarker;
    var {slipDisplacement, height, width, borderRadius} = this.props.touchDimensions;
    var touchStyle = {
      height: height,
      width: width,
      borderRadius: borderRadius || 0
    };

    return (
      <View style={[styles.container, this.props.containerStyle]}>
        <View style={[styles.fullTrack, { width: sliderLength }]}>
          <View style={[this.props.trackStyle, styles.track, trackOneStyle, { width: trackOneLength }]} />
          <View style={[this.props.trackStyle, styles.track, trackTwoStyle, { width: trackTwoLength }]} />
          { twoMarkers && (
            <View style={[this.props.trackStyle, styles.track, trackThreeStyle, { width: trackThreeLength }]} />
          ) }

          <View
            style={[styles.touch, touchStyle, {left: -(trackTwoLength + trackThreeLength + width / 2)}]}
            ref={component => this._markerOne = component}
            {...this._panResponderOne.panHandlers}
            >
            <Marker
              pressed={this.state.onePressed}
              value={this.state.valueOne}
              markerStyle={this.props.markerStyle}
              pressedMarkerStyle={this.props.pressedMarkerStyle}
              />
          </View>

          { twoMarkers && (positionOne !== this.props.sliderLength) && (
            <View
              style={[styles.touch, touchStyle, {left: -(trackThreeLength + width * 1.5)}]}
              ref={component => this._markerTwo = component}
              {...this._panResponderTwo.panHandlers}
              >
              <Marker
                pressed={this.state.twoPressed}
                value={this.state.valueOne}
                markerStyle={this.props.markerStyle}
                pressedMarkerStyle={this.props.pressedMarkerStyle}
                />
            </View>
          ) }

        </View>
      </View>
    );
  }
});

module.exports = Slider;

var styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
  },
  fullTrack: {
    flexDirection: 'row',
  },
  track: {
    justifyContent: 'center'
  },
  touch: {
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'transparent'
  }
});
<|endoftext|>


<commit_before>var Noonworks = Noonworks || {};

Noonworks.IndentString = function(s){
    this._s = s;
    this._part = '';
    if (s.length > 1) {
        this._part = s.substring(0, 1);
        for (var i = 1; i < s.length; i++) {
            if (this._part !== s.substring(i, i + 1)) {
                this._part = '';
                break;
            }
        }
    }
    if (this._part.length === 0) {
        this._unindent_reg = new RegExp('^' + this._s, 'gim');
    } else {
        this._unindent_reg = new RegExp(
            '^(' + this._part + '{1,' + this._s.length + '})', 'gim');
    }
};

Noonworks.IndentString.prototype = {
    multiply: function(n) {
        var s = '';
        for (var i = 0; i < n; i++) {
            s += this._s;
        }
        return s;
    },

    indent: function(level, str) {
        if (level === 0) {
            return str;
        }
        if (level < 0) {
            return this.unindent(level * -1, str);
        }
        var s = this.multiply(level);
        return s + (str.replace(/\n/g, '\n' + s));
    },

    unindent: function(level, str) {
        if (level === 0) {
            return str;
        }
        if (level < 0) {
            return this.indent(level * -1, str);
        }
        for (var i = 0; i < level; i++) {
            str = str.replace(this._unindent_reg, '');
        }
        return str;
    }
};

Noonworks.String = function(s){
    this._s = s;
};

Noonworks.String.prototype = new String();

Noonworks.String.prototype.valueOf =
Noonworks.String.prototype.toString = function() {
    return this._s.toString();
};

Noonworks.String.prototype.multiply = function(n) {
    var s = '';
    for (var i = 0; i < n; i++) {
        s += this._s;
    }
    return new Noonworks.String(s);
};

Noonworks.String.prototype.indent = function(level, indent_string) {
    var i = (typeof indent_string === 'undefined')
        ? new Noonworks.IndentString('    ')
        : new Noonworks.IndentString(indent_string);
    return new Noonworks.String(i.indent(level, this._s));
};

Noonworks.String.prototype.unindent = function(level, indent_string) {
    var i = (typeof indent_string === 'undefined')
        ? new Noonworks.IndentString('    ')
        : new Noonworks.IndentString(indent_string);
    return new Noonworks.String(i.unindent(level, this._s));
};

Noonworks.String.prototype.stripQuote = function(q_start, q_end) {
    q_end = (typeof q_end === 'undefined') ? q_start : q_end;
    if (this._s.length < q_start.length || this._s.length < q_end.length) {
        return this;
    }
    if (this._s.substring(0, q_start.length) === q_start &&
        this._s.substring(this._s.length - q_end.length, this._s.length) === q_end) {
        return new Noonworks.String(this._s.substring(
            q_start.length, this._s.length - q_end.length));
    }
    return this;
};

Noonworks.String.prototype.offsetMatch = function(offset, reg) {
    if (this._s.length < offset) {
        return null;
    }
    return this._s.substring(offset, this._s.length).match(reg);
};

Noonworks.String.prototype.allExec = function(reg) {
    if (!reg.global) {
        reg = new RegExp(reg.source,
            'g' + (reg.ignoreCase ? 'i' : '') + (reg.multiline ? 'm' : ''));
    }
    RegExp.lastIndex = 0;
    var ret = new Array();
    while(true) {
        var m = reg.exec(this._s);
        if (m === null) {
            return ret;
        }
        ret.push(m);
    }
};

Noonworks.String.prototype.firstExec = function(reg) {
    if (reg.global) {
        RegExp.lastIndex = 0;
    }
    return reg.exec(this._s);
};

Noonworks.String.prototype.lastExec = function(reg) {
    if (!reg.global) {
        reg = new RegExp(reg.source,
            'g' + (reg.ignoreCase ? 'i' : '') + (reg.multiline ? 'm' : ''));
    }
    RegExp.lastIndex = 0;
    var ret = null;
    while(true) {
        var m = reg.exec(this._s);
        if (m === null) {
            return ret;
        }
        ret = m;
    }
};

Noonworks.String.prototype.stripRegex = function(r_start, r_end) {
    r_start = (typeof r_start === 'string') ? new RegExp(r_start, 'ig') : r_start;
    r_end = (typeof r_end === 'undefined') ? r_start : r_end;
    r_end = (typeof r_end === 'string') ? new RegExp(r_end, 'ig') : r_end;
    var m_start = this.firstExec(r_start);
    if (m_start === null || m_start.index !== 0) {
        return this;
    }
    var m_end = this.lastExec(r_end);
    if (m_end === null || (this._s.length !== (m_end.index + m_end[0].length))) {
        return this;
    }
    return new Noonworks.String(this._s.substring(m_start[0].length, m_end.index));
};

Noonworks.String.prototype.pickup = function(index, r_start, r_end, quoted) {
    quoted = (typeof quoted === 'undefined') ? false : quoted;
    index = (index < 0) ? this._s.length + index : index;
    if (this._s.length < index || index < 0) {
        return new Noonworks.String('');
    }
    r_start = (typeof r_start === 'string') ? new RegExp(r_start, 'ig') : r_start;
    r_end = (typeof r_end === 'undefined') ? r_start : r_end;
    r_end = (typeof r_end === 'string') ? new RegExp(r_end, 'ig') : r_end;
    var left = this._s.substring(0, index);
    var right = this._s.substring(index, this._s.length);
    if (quoted && (left.length === 0 || right.length === 0)) {
        return new Noonworks.String('');
    }
    if (left.length > 0) {
        var last_sep = (new Noonworks.String(left)).lastExec(r_start);
        if (last_sep !== null) {
            left = left.substring(last_sep.index + last_sep[0].length, left.length);
        } else if (quoted) {
            return new Noonworks.String('');
        }
    }
    if (right.length > 0) {
        var first_sep = (new Noonworks.String(right)).firstExec(r_end);
        if (first_sep !== null) {
            right = right.substring(0, first_sep.index);
        } else if (quoted) {
            return new Noonworks.String('');
        }
    }
    return new Noonworks.String(left + right);
};

Noonworks.String.prototype.pickupIndexOf = function(cur_pos, arr) {
    cur_pos = (cur_pos < 0) ? this._s.length + cur_pos : cur_pos;
    if (this._s.length < cur_pos || cur_pos < 0) {
        return -1;
    }
    var search_index = 0;
    for (var i = 0; i < arr.length; i++) {
        var elem_i = this._s.indexOf(arr[i], search_index);
        if (elem_i < 0 || elem_i > cur_pos) {
            return -1;
        }
        if (elem_i <= cur_pos && (elem_i + arr[i].length) >= cur_pos) {
            return i;
        }
        search_index = elem_i + arr[i].length;
    }
    return -1;
};

Noonworks.String.prototype.curIndexOf = function(cur_pos, str) {
    if (this._s.length < str.length || str.length === 0) {
        return -1;
    }
    cur_pos = (cur_pos < 0) ? this._s.length + cur_pos : cur_pos;
    if (this._s.length < cur_pos || cur_pos < 0) {
        return -1;
    }
    var search_index = (cur_pos <= str.length) ? 0 : cur_pos - str.length;
    while (true) {
        var i = this._s.indexOf(str, search_index);
        if (i < 0 || i > cur_pos) {
            return -1;
        }
        if (i <= cur_pos && (i + str.length) >= cur_pos) {
            return i;
        }
    }
};
<commit_msg>Fix selection bug at the end of line.<commit_after>var Noonworks = Noonworks || {};

Noonworks.IndentString = function(s){
    this._s = s;
    this._part = '';
    if (s.length > 1) {
        this._part = s.substring(0, 1);
        for (var i = 1; i < s.length; i++) {
            if (this._part !== s.substring(i, i + 1)) {
                this._part = '';
                break;
            }
        }
    }
    if (this._part.length === 0) {
        this._unindent_reg = new RegExp('^' + this._s, 'gim');
    } else {
        this._unindent_reg = new RegExp(
            '^(' + this._part + '{1,' + this._s.length + '})', 'gim');
    }
};

Noonworks.IndentString.prototype = {
    multiply: function(n) {
        var s = '';
        for (var i = 0; i < n; i++) {
            s += this._s;
        }
        return s;
    },

    indent: function(level, str) {
        if (level === 0) {
            return str;
        }
        if (level < 0) {
            return this.unindent(level * -1, str);
        }
        var s = this.multiply(level);
        return s + (str.replace(/\n/g, '\n' + s));
    },

    unindent: function(level, str) {
        if (level === 0) {
            return str;
        }
        if (level < 0) {
            return this.indent(level * -1, str);
        }
        for (var i = 0; i < level; i++) {
            str = str.replace(this._unindent_reg, '');
        }
        return str;
    }
};

Noonworks.String = function(s){
    this._s = s;
};

Noonworks.String.prototype = new String();

Noonworks.String.prototype.valueOf =
Noonworks.String.prototype.toString = function() {
    return this._s.toString();
};

Noonworks.String.prototype.multiply = function(n) {
    var s = '';
    for (var i = 0; i < n; i++) {
        s += this._s;
    }
    return new Noonworks.String(s);
};

Noonworks.String.prototype.indent = function(level, indent_string) {
    var i = (typeof indent_string === 'undefined')
        ? new Noonworks.IndentString('    ')
        : new Noonworks.IndentString(indent_string);
    return new Noonworks.String(i.indent(level, this._s));
};

Noonworks.String.prototype.unindent = function(level, indent_string) {
    var i = (typeof indent_string === 'undefined')
        ? new Noonworks.IndentString('    ')
        : new Noonworks.IndentString(indent_string);
    return new Noonworks.String(i.unindent(level, this._s));
};

Noonworks.String.prototype.stripQuote = function(q_start, q_end) {
    q_end = (typeof q_end === 'undefined') ? q_start : q_end;
    if (this._s.length < q_start.length || this._s.length < q_end.length) {
        return this;
    }
    if (this._s.substring(0, q_start.length) === q_start &&
        this._s.substring(this._s.length - q_end.length, this._s.length) === q_end) {
        return new Noonworks.String(this._s.substring(
            q_start.length, this._s.length - q_end.length));
    }
    return this;
};

Noonworks.String.prototype.offsetMatch = function(offset, reg) {
    if (this._s.length < offset) {
        return null;
    }
    return this._s.substring(offset, this._s.length).match(reg);
};

Noonworks.String.prototype.allExec = function(reg) {
    if (!reg.global) {
        reg = new RegExp(reg.source,
            'g' + (reg.ignoreCase ? 'i' : '') + (reg.multiline ? 'm' : ''));
    }
    RegExp.lastIndex = 0;
    var ret = new Array();
    while(true) {
        var m = reg.exec(this._s);
        if (m === null) {
            return ret;
        }
        ret.push(m);
    }
};

Noonworks.String.prototype.firstExec = function(reg) {
    if (reg.global) {
        RegExp.lastIndex = 0;
    }
    return reg.exec(this._s);
};

Noonworks.String.prototype.lastExec = function(reg) {
    if (!reg.global) {
        reg = new RegExp(reg.source,
            'g' + (reg.ignoreCase ? 'i' : '') + (reg.multiline ? 'm' : ''));
    }
    RegExp.lastIndex = 0;
    var ret = null;
    while(true) {
        var m = reg.exec(this._s);
        if (m === null) {
            return ret;
        }
        ret = m;
    }
};

Noonworks.String.prototype.stripRegex = function(r_start, r_end) {
    r_start = (typeof r_start === 'string') ? new RegExp(r_start, 'ig') : r_start;
    r_end = (typeof r_end === 'undefined') ? r_start : r_end;
    r_end = (typeof r_end === 'string') ? new RegExp(r_end, 'ig') : r_end;
    var m_start = this.firstExec(r_start);
    if (m_start === null || m_start.index !== 0) {
        return this;
    }
    var m_end = this.lastExec(r_end);
    if (m_end === null || (this._s.length !== (m_end.index + m_end[0].length))) {
        return this;
    }
    return new Noonworks.String(this._s.substring(m_start[0].length, m_end.index));
};

Noonworks.String.prototype.pickup = function(index, r_start, r_end, quoted) {
    quoted = (typeof quoted === 'undefined') ? false : quoted;
    index = (index < 0) ? this._s.length + index : index;
    if (this._s.length < index || index < 0) {
        return new Noonworks.String('');
    }
    r_start = (typeof r_start === 'string') ? new RegExp(r_start, 'ig') : r_start;
    r_end = (typeof r_end === 'undefined') ? r_start : r_end;
    r_end = (typeof r_end === 'string') ? new RegExp(r_end, 'ig') : r_end;
    var left = this._s.substring(0, index);
    var right = this._s.substring(index, this._s.length);
    if (quoted && (left.length === 0 || right.length === 0)) {
        return new Noonworks.String('');
    }
    if (left.length > 0) {
        var last_sep = (new Noonworks.String(left)).lastExec(r_start);
        if (last_sep !== null) {
            left = left.substring(last_sep.index + last_sep[0].length, left.length);
        } else if (quoted) {
            return new Noonworks.String('');
        }
    }
    if (right.length > 0) {
        var first_sep = (new Noonworks.String(right)).firstExec(r_end);
        if (first_sep !== null) {
            right = right.substring(0, first_sep.index);
        } else if (quoted) {
            return new Noonworks.String('');
        }
    }
    return new Noonworks.String(left + right);
};

Noonworks.String.prototype.pickupIndexOf = function(cur_pos, arr) {
    cur_pos = (cur_pos < 0) ? this._s.length + cur_pos : cur_pos;
    if (this._s.length < cur_pos || cur_pos < 0) {
        return -1;
    }
    var search_index = 0;
    for (var i = 0; i < arr.length; i++) {
        var elem_i = this._s.indexOf(arr[i], search_index);
        if (elem_i < 0 || elem_i > cur_pos) {
            return -1;
        }
        if (elem_i <= cur_pos && (elem_i + arr[i].length) >= cur_pos) {
            return i;
        }
        search_index = elem_i + arr[i].length;
    }
    return -1;
};

Noonworks.String.prototype.curIndexOf = function(cur_pos, str) {
    if (this._s.length < str.length || str.length === 0) {
        return -1;
    }
    cur_pos = (cur_pos < 0) ? this._s.length + cur_pos : cur_pos;
    if (this._s.length + 1 == cur_pos) return this._s.lastIndexOf(str);
    if (this._s.length < cur_pos || cur_pos < 0) return -1;
    var search_index = (cur_pos <= str.length) ? 0 : cur_pos - str.length;
    while (true) {
        var i = this._s.indexOf(str, search_index);
        if (i < 0 || i > cur_pos) {
            return -1;
        }
        if (i <= cur_pos && (i + str.length) >= cur_pos) {
            return i;
        }
    }
};
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Owner: david@famo.us
 * @license MPL 2.0
 * @copyright Famous Industries, Inc. 2014
 */

define(function(require, exports, module) {

    /**
     * Three-element floating point vector.
     *
     * @class Vector
     * @constructor
     *
     * @param {number} x x element value
     * @param {number} y y element value
     * @param {number} z z element value
     */
    function Vector(x,y,z) {
        if (arguments.length === 1) this.set(x);
        else {
            this.x = x || 0;
            this.y = y || 0;
            this.z = z || 0;
        }
        return this;
    }

    var _register = new Vector(0,0,0);

    /**
     * Add this element-wise to another Vector, element-wise.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method add
     * @param {Vector} v addend
     * @return {Vector} vector sum
     */
    Vector.prototype.add = function add(v) {
        return _setXYZ.call(_register,
            this.x + v.x,
            this.y + v.y,
            this.z + v.z
        );
    };

    /**
     * Subtract another vector from this vector, element-wise.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method sub
     * @param {Vector} v subtrahend
     * @return {Vector} vector difference
     */
    Vector.prototype.sub = function sub(v) {
        return _setXYZ.call(_register,
            this.x - v.x,
            this.y - v.y,
            this.z - v.z
        );
    };

    /**
     * Scale Vector by floating point r.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method mult
     *
     * @param {number} r scalar
     * @return {Vector} vector result
     */
    Vector.prototype.mult = function mult(r) {
        return _setXYZ.call(_register,
            r * this.x,
            r * this.y,
            r * this.z
        );
    };

    /**
     * Scale Vector by floating point 1/r.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method div
     *
     * @param {number} r scalar
     * @return {Vector} vector result
     */
    Vector.prototype.div = function div(r) {
        return this.mult(1 / r);
    };

    /**
     * Given another vector v, return cross product (v)x(this).
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method cross
     * @param {Vector} v Left Hand Vector
     * @return {Vector} vector result
     */
    Vector.prototype.cross = function cross(v) {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var vx = v.x;
        var vy = v.y;
        var vz = v.z;

        return _setXYZ.call(_register,
            z * vy - y * vz,
            x * vz - z * vx,
            y * vx - x * vy
        );
    };

    /**
     * Component-wise equality test between this and Vector v.
     * @method equals
     * @param {Vector} v vector to compare
     * @return {boolean}
     */
    Vector.prototype.equals = function equals(v) {
        return (v.x === this.x && v.y === this.y && v.z === this.z);
    };

    /**
     * Rotate clockwise around x-axis by theta radians.
     *   Note: This sets the internal result register, so other references to that vector will change.
     * @method rotateX
     * @param {number} theta radians
     * @return {Vector} rotated vector
     */
    Vector.prototype.rotateX = function rotateX(theta) {
        var x = this.x;
        var y = this.y;
        var z = this.z;

        var cosTheta = Math.cos(theta);
        var sinTheta = Math.sin(theta);

        return _setXYZ.call(_register,
            x,
            y * cosTheta - z * sinTheta,
            y * sinTheta + z * cosTheta
        );
    };

    /**
     * Rotate clockwise around y-axis by theta radians.
     *   Note: This sets the internal result register, so other references to that vector will change.
     * @method rotateY
     * @param {number} theta radians
     * @return {Vector} rotated vector
     */
    Vector.prototype.rotateY = function rotateY(theta) {
        var x = this.x;
        var y = this.y;
        var z = this.z;

        var cosTheta = Math.cos(theta);
        var sinTheta = Math.sin(theta);

        return _setXYZ.call(_register,
            z * sinTheta + x * cosTheta,
            y,
            z * cosTheta - x * sinTheta
        );
    };

    /**
     * Rotate clockwise around z-axis by theta radians.
     *   Note: This sets the internal result register, so other references to that vector will change.
     * @method rotateZ
     * @param {number} theta radians
     * @return {Vector} rotated vector
     */
    Vector.prototype.rotateZ = function rotateZ(theta) {
        var x = this.x;
        var y = this.y;
        var z = this.z;

        var cosTheta = Math.cos(theta);
        var sinTheta = Math.sin(theta);

        return _setXYZ.call(_register,
            x * cosTheta - y * sinTheta,
            x * sinTheta + y * cosTheta,
            z
        );
    };

    /**
     * Return dot product of this with a second Vector
     * @method dot
     * @param {Vector} v second vector
     * @return {number} dot product
     */
    Vector.prototype.dot = function dot(v) {
        return this.x * v.x + this.y * v.y + this.z * v.z;
    };

    /**
     * Return squared length of this vector
     * @method normSquared
     * @return {number} squared length
     */
    Vector.prototype.normSquared = function normSquared() {
        return this.dot(this);
    };

    /**
     * Return length of this vector
     * @method norm
     * @return {number} length
     */
    Vector.prototype.norm = function norm() {
        return Math.sqrt(this.normSquared());
    };

    /**
     * Scale Vector to specified length.
     *   If length is less than internal tolerance, set vector to [length, 0, 0].
     *   Note: This sets the internal result register, so other references to that vector will change.
     * @method normalize
     *
     * @param {number} length target length, default 1.0
     * @return {Vector}
     */
    Vector.prototype.normalize = function normalize(length) {
        if (arguments.length === 0) length = 1;
        var norm = this.norm();

        if (norm > 1e-7) return _setFromVector.call(_register, this.mult(length / norm));
        else return _setXYZ.call(_register, length, 0, 0);
    };

    /**
     * Make a separate copy of the Vector.
     *
     * @method clone
     *
     * @return {Vector}
     */
    Vector.prototype.clone = function clone() {
        return new Vector(this);
    };

    /**
     * True if and only if every value is 0 (or falsy)
     *
     * @method isZero
     *
     * @return {boolean}
     */
    Vector.prototype.isZero = function isZero() {
        return !(this.x || this.y || this.z);
    };

    function _setXYZ(x,y,z) {
        this.x = x;
        this.y = y;
        this.z = z;
        return this;
    }

    function _setFromArray(v) {
        return _setXYZ.call(this,v[0],v[1],v[2] || 0);
    }

    function _setFromVector(v) {
        return _setXYZ.call(this, v.x, v.y, v.z);
    }

    function _setFromNumber(x) {
        return _setXYZ.call(this,x,0,0);
    }

    /**
     * Set this Vector to the values in the provided Array or Vector.
     *
     * @method set
     * @param {object} v array, Vector, or number
     * @return {Vector} this
     */
    Vector.prototype.set = function set(v) {
        if (v instanceof Array)    return _setFromArray.call(this, v);
        if (v instanceof Vector)   return _setFromVector.call(this, v);
        if (typeof v === 'number') return _setFromNumber.call(this, v);
    };

    Vector.prototype.setXYZ = function(x,y,z) {
        return _setXYZ.apply(this, arguments);
    };

    Vector.prototype.set1D = function(x) {
        return _setFromNumber.call(this, x);
    };

    /**
     * Put result of last internal register calculation in specified output vector.
     *
     * @method put
     * @param {Vector} v destination vector
     * @return {Vector} destination vector
     */

    Vector.prototype.put = function put(v) {
        _setFromVector.call(v, _register);
    };

    /**
     * Set this vector to [0,0,0]
     *
     * @method clear
     */
    Vector.prototype.clear = function clear() {
        return _setXYZ.call(this,0,0,0);
    };

    /**
     * Scale this Vector down to specified "cap" length.
     *   If Vector shorter than cap, or cap is Infinity, do nothing.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method cap
     * @return {Vector} capped vector
     */
    Vector.prototype.cap = function cap(cap) {
        if (cap === Infinity) return _setFromVector.call(_register, this);
        var norm = this.norm();
        if (norm > cap) return _setFromVector.call(_register, this.mult(cap / norm));
        else return _setFromVector.call(_register, this);
    };

    /**
     * Return projection of this Vector onto another.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method project
     * @param {Vector} n vector to project upon
     * @return {Vector} projected vector
     */
    Vector.prototype.project = function project(n) {
        return n.mult(this.dot(n));
    };

    /**
     * Reflect this Vector across provided vector.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method reflectAcross
     * @param {Vector} n vector to reflect across
     * @return {Vector} reflected vector
     */
    Vector.prototype.reflectAcross = function reflectAcross(n) {
        n.normalize().put(n);
        return _setFromVector(_register, this.sub(this.project(n).mult(2)));
    };

    /**
     * Convert Vector to three-element array.
     *
     * @method get
     * @return {array<number>} three-element array
     */
    Vector.prototype.get = function get() {
        return [this.x, this.y, this.z];
    };

    Vector.prototype.get1D = function() {
        return this.x;
    };

    module.exports = Vector;

});
<commit_msg>Update .put when called from vector<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Owner: david@famo.us
 * @license MPL 2.0
 * @copyright Famous Industries, Inc. 2014
 */

define(function(require, exports, module) {

    /**
     * Three-element floating point vector.
     *
     * @class Vector
     * @constructor
     *
     * @param {number} x x element value
     * @param {number} y y element value
     * @param {number} z z element value
     */
    function Vector(x,y,z) {
        if (arguments.length === 1) this.set(x);
        else {
            this.x = x || 0;
            this.y = y || 0;
            this.z = z || 0;
        }
        return this;
    }

    var _register = new Vector(0,0,0);

    /**
     * Add this element-wise to another Vector, element-wise.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method add
     * @param {Vector} v addend
     * @return {Vector} vector sum
     */
    Vector.prototype.add = function add(v) {
        return _setXYZ.call(_register,
            this.x + v.x,
            this.y + v.y,
            this.z + v.z
        );
    };

    /**
     * Subtract another vector from this vector, element-wise.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method sub
     * @param {Vector} v subtrahend
     * @return {Vector} vector difference
     */
    Vector.prototype.sub = function sub(v) {
        return _setXYZ.call(_register,
            this.x - v.x,
            this.y - v.y,
            this.z - v.z
        );
    };

    /**
     * Scale Vector by floating point r.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method mult
     *
     * @param {number} r scalar
     * @return {Vector} vector result
     */
    Vector.prototype.mult = function mult(r) {
        return _setXYZ.call(_register,
            r * this.x,
            r * this.y,
            r * this.z
        );
    };

    /**
     * Scale Vector by floating point 1/r.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method div
     *
     * @param {number} r scalar
     * @return {Vector} vector result
     */
    Vector.prototype.div = function div(r) {
        return this.mult(1 / r);
    };

    /**
     * Given another vector v, return cross product (v)x(this).
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method cross
     * @param {Vector} v Left Hand Vector
     * @return {Vector} vector result
     */
    Vector.prototype.cross = function cross(v) {
        var x = this.x;
        var y = this.y;
        var z = this.z;
        var vx = v.x;
        var vy = v.y;
        var vz = v.z;

        return _setXYZ.call(_register,
            z * vy - y * vz,
            x * vz - z * vx,
            y * vx - x * vy
        );
    };

    /**
     * Component-wise equality test between this and Vector v.
     * @method equals
     * @param {Vector} v vector to compare
     * @return {boolean}
     */
    Vector.prototype.equals = function equals(v) {
        return (v.x === this.x && v.y === this.y && v.z === this.z);
    };

    /**
     * Rotate clockwise around x-axis by theta radians.
     *   Note: This sets the internal result register, so other references to that vector will change.
     * @method rotateX
     * @param {number} theta radians
     * @return {Vector} rotated vector
     */
    Vector.prototype.rotateX = function rotateX(theta) {
        var x = this.x;
        var y = this.y;
        var z = this.z;

        var cosTheta = Math.cos(theta);
        var sinTheta = Math.sin(theta);

        return _setXYZ.call(_register,
            x,
            y * cosTheta - z * sinTheta,
            y * sinTheta + z * cosTheta
        );
    };

    /**
     * Rotate clockwise around y-axis by theta radians.
     *   Note: This sets the internal result register, so other references to that vector will change.
     * @method rotateY
     * @param {number} theta radians
     * @return {Vector} rotated vector
     */
    Vector.prototype.rotateY = function rotateY(theta) {
        var x = this.x;
        var y = this.y;
        var z = this.z;

        var cosTheta = Math.cos(theta);
        var sinTheta = Math.sin(theta);

        return _setXYZ.call(_register,
            z * sinTheta + x * cosTheta,
            y,
            z * cosTheta - x * sinTheta
        );
    };

    /**
     * Rotate clockwise around z-axis by theta radians.
     *   Note: This sets the internal result register, so other references to that vector will change.
     * @method rotateZ
     * @param {number} theta radians
     * @return {Vector} rotated vector
     */
    Vector.prototype.rotateZ = function rotateZ(theta) {
        var x = this.x;
        var y = this.y;
        var z = this.z;

        var cosTheta = Math.cos(theta);
        var sinTheta = Math.sin(theta);

        return _setXYZ.call(_register,
            x * cosTheta - y * sinTheta,
            x * sinTheta + y * cosTheta,
            z
        );
    };

    /**
     * Return dot product of this with a second Vector
     * @method dot
     * @param {Vector} v second vector
     * @return {number} dot product
     */
    Vector.prototype.dot = function dot(v) {
        return this.x * v.x + this.y * v.y + this.z * v.z;
    };

    /**
     * Return squared length of this vector
     * @method normSquared
     * @return {number} squared length
     */
    Vector.prototype.normSquared = function normSquared() {
        return this.dot(this);
    };

    /**
     * Return length of this vector
     * @method norm
     * @return {number} length
     */
    Vector.prototype.norm = function norm() {
        return Math.sqrt(this.normSquared());
    };

    /**
     * Scale Vector to specified length.
     *   If length is less than internal tolerance, set vector to [length, 0, 0].
     *   Note: This sets the internal result register, so other references to that vector will change.
     * @method normalize
     *
     * @param {number} length target length, default 1.0
     * @return {Vector}
     */
    Vector.prototype.normalize = function normalize(length) {
        if (arguments.length === 0) length = 1;
        var norm = this.norm();

        if (norm > 1e-7) return _setFromVector.call(_register, this.mult(length / norm));
        else return _setXYZ.call(_register, length, 0, 0);
    };

    /**
     * Make a separate copy of the Vector.
     *
     * @method clone
     *
     * @return {Vector}
     */
    Vector.prototype.clone = function clone() {
        return new Vector(this);
    };

    /**
     * True if and only if every value is 0 (or falsy)
     *
     * @method isZero
     *
     * @return {boolean}
     */
    Vector.prototype.isZero = function isZero() {
        return !(this.x || this.y || this.z);
    };

    function _setXYZ(x,y,z) {
        this.x = x;
        this.y = y;
        this.z = z;
        return this;
    }

    function _setFromArray(v) {
        return _setXYZ.call(this,v[0],v[1],v[2] || 0);
    }

    function _setFromVector(v) {
        return _setXYZ.call(this, v.x, v.y, v.z);
    }

    function _setFromNumber(x) {
        return _setXYZ.call(this,x,0,0);
    }

    /**
     * Set this Vector to the values in the provided Array or Vector.
     *
     * @method set
     * @param {object} v array, Vector, or number
     * @return {Vector} this
     */
    Vector.prototype.set = function set(v) {
        if (v instanceof Array)    return _setFromArray.call(this, v);
        if (v instanceof Vector)   return _setFromVector.call(this, v);
        if (typeof v === 'number') return _setFromNumber.call(this, v);
    };

    Vector.prototype.setXYZ = function(x,y,z) {
        return _setXYZ.apply(this, arguments);
    };

    Vector.prototype.set1D = function(x) {
        return _setFromNumber.call(this, x);
    };

    /**
     * Put result of last internal register calculation in specified output vector.
     *
     * @method put
     * @param {Vector} v destination vector
     * @return {Vector} destination vector
     */

    Vector.prototype.put = function put(v) {
        if (this === _register) _setFromVector.call(v, _register);
        else _setFromVector.call(v, this);
    };

    /**
     * Set this vector to [0,0,0]
     *
     * @method clear
     */
    Vector.prototype.clear = function clear() {
        return _setXYZ.call(this,0,0,0);
    };

    /**
     * Scale this Vector down to specified "cap" length.
     *   If Vector shorter than cap, or cap is Infinity, do nothing.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method cap
     * @return {Vector} capped vector
     */
    Vector.prototype.cap = function cap(cap) {
        if (cap === Infinity) return _setFromVector.call(_register, this);
        var norm = this.norm();
        if (norm > cap) return _setFromVector.call(_register, this.mult(cap / norm));
        else return _setFromVector.call(_register, this);
    };

    /**
     * Return projection of this Vector onto another.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method project
     * @param {Vector} n vector to project upon
     * @return {Vector} projected vector
     */
    Vector.prototype.project = function project(n) {
        return n.mult(this.dot(n));
    };

    /**
     * Reflect this Vector across provided vector.
     *   Note: This sets the internal result register, so other references to that vector will change.
     *
     * @method reflectAcross
     * @param {Vector} n vector to reflect across
     * @return {Vector} reflected vector
     */
    Vector.prototype.reflectAcross = function reflectAcross(n) {
        n.normalize().put(n);
        return _setFromVector(_register, this.sub(this.project(n).mult(2)));
    };

    /**
     * Convert Vector to three-element array.
     *
     * @method get
     * @return {array<number>} three-element array
     */
    Vector.prototype.get = function get() {
        return [this.x, this.y, this.z];
    };

    Vector.prototype.get1D = function() {
        return this.x;
    };

    module.exports = Vector;

});
<|endoftext|>


<commit_before>// BRICO

var through = require('through')
var proc = process.title // node or browser

module.exports = function bricoleur (data) {
  var conf
  var _ = {}

  // get config!
  data.get('config', function handleConfig (e, d) {
    e ? interface.emit('error', e) : conf = JSON.parse(d)
  })

  // DATA
  var dataFilter = through(function write(d) {
    if (d.type == 'del') fil.rm(d)

    if (d.type === 'put') {
      var path = d.key.split(':')
      var action = path[0]
      var loc = path[1]
      var id = path[2]
      if (typeof d.value === 'string' && d.value[0] === '{') d.value = JSON.parse(d.value)

      switch (action) {
        case config.spaces.active : fil.put(d); break;
        default : interface.emit('error', new Error('unable to handle action: '+action))
      }
    }
  }, function end () {
    this.emit('end')
  })

  var fil = {
    put: function (mod) {
      // a way to insert options?
      var m = mod.key.split(':')[1]
      var mPath = config.dir_wilds+m
      _[m] = require(mPath)(m.value)
      console.log(_)
    },
    rm: function (mod) {
      // unpipe? close stream!?
      _[mod.key].emit('close')
      delete _[mod.key]
      console.log(_)
    },
    conn: function (mods) {
      var mods = con.split('-')
      _[mods[0]].pipe(_[mods[1]])
    },
    disconn: function (mods) {
      var mods = con.split('-')
      _[mods[0]].unpipe(_[mods[1]])
    }
  }

  var liveStream = data.liveStream({old:false})
  liveStream.pipe(dataFilter)

  // WILDS / RUNNING MODULES
  var api = { // use prefixes from config
    put: function (args) {
      var match = false
      var opts = {}

      // check module exists
      var ks = data.createKeyStream()
      ks.on('data', function (d) {
        var path = d.split(':')
        if (args[1]===path[1]) {
          match = true
          for (var i=2; i<args.length;i++) {
            var pair = args[i].split('=')
            var key = pair[0]
            var val = pair[1]
            opts[key] = val
          }
          if (opts === {}) opts = null
          data.put(config.spaces.active+':'+args[1],JSON.stringify(opts))
        }
        // what prefix?
      })
      ks.on('end', function () {
        if (match!==true) interface.emit('error', new Error('could not find module'))
      })
    },
    rm: function (mod) {
      data.del(mod[1], function (e) {
        if (e) interface.emit('error',e)
      })
    }
  }

  // METHODS / API
  var interface = through(function (input) {
    var args = input.split(' ')
    var cmd = args[0]
    api[cmd] ? api[cmd](args) : this.emit('error', new Error('no such command'))
  }, function end () {
    this.emit('end')
  })

  return interface
}
<commit_msg>move streaming search into its own function<commit_after>// BRICO

var through = require('through')
var proc = process.title // node or browser

module.exports = function bricoleur (data) {
  var conf
  var _ = {}

  // get config!
  data.get('config', function handleConfig (e, d) {
    e ? interface.emit('error', e) : conf = JSON.parse(d)
  })

  // DATA
  var dataFilter = through(function write(d) {
    if (d.type == 'del') fil.rm(d)

    if (d.type === 'put') {
      var path = d.key.split(':')
      var action = path[0]
      var loc = path[1]
      var id = path[2]
      if (typeof d.value === 'string' && d.value[0] === '{') d.value = JSON.parse(d.value)

      switch (action) {
        case config.spaces.active : fil.put(d); break;
        default : interface.emit('error', new Error('unable to handle action: '+action))
      }
    }
  }, function end () {
    this.emit('end')
  })

  var fil = {
    put: function (mod) {
      // a way to insert options?
      var m = mod.key.split(':')[1]
      var mPath = config.dir_wilds+m
      _[m] = require(mPath)(m.value)
      console.log(_)
    },
    rm: function (mod) {
      // unpipe? close stream!?
      _[mod.key].emit('close')
      delete _[mod.key]
      console.log(_)
    },
    conn: function (mods) {
      var mods = con.split('-')
      _[mods[0]].pipe(_[mods[1]])
    },
    disconn: function (mods) {
      var mods = con.split('-')
      _[mods[0]].unpipe(_[mods[1]])
    }
  }

  var liveStream = data.liveStream({old:false})
  liveStream.pipe(dataFilter)

  // WILDS / RUNNING MODULES
  var api = { // use prefixes from config
    put: function (args) {
      var opts = {}
      search(args, function () {
        // data.put(
      })
    },
    rm: function (mod) {
      data.del(mod[1], function (e) {
        if (e) interface.emit('error',e)
      })
    }
  }

  function search (args, cb) {
    var match = false
    // check module exists // move this to a search function
    var ks = data.createKeyStream()
    ks.on('data', function (d) {
      var path = d.split(':')
      if (args[1]===path[1]) {
        match = true
        for (var i=2; i<args.length;i++) {
          var pair = args[i].split('=')
          var key = pair[0]
          var val = pair[1]
          opts[key] = val
        }
        if (opts === {}) opts = null
        data.put(config.spaces.active+':'+args[1],JSON.stringify(opts))
      }
    }) // what prefix?
    ks.on('end', function () {
      if (match!==true) interface.emit('error', new Error('could not find module'))
    })
  }

  // METHODS / API
  var interface = through(function (input) {
    var args = input.split(' ')
    var cmd = args[0]
    api[cmd] ? api[cmd](args) : this.emit('error', new Error('no such command'))
  }, function end () {
    this.emit('end')
  })

  return interface
}
<|endoftext|>


<commit_before>var telepath = require('tele')
, stream = require('stream')
, async = require ('async')

module.exports = function (usr) { // BRICOLEUR
  var self = this
  , map = null
  , _ = {} // module scope
  telepath(this)

  // detect if running in node or browser
  if (global.process && global.process.title === 'node') self.scope = 'server'
  if (!global.process) self.scope = 'client'

  if (usr) self.usr = usr

  this.recv = function (buffer) {
    var data = JSON.parse(buffer.toString())

    if (data.meta === 'module_map') { // add map
      map = data[self.scope]
      self.build()
    }
  }

  this.build = function () { // load modules
    if (!map) throw new Error('no map')

    async.forEach(map, match, function () {
      console.log(usr.host+' modules loaded')
    })

    function match (mod, cb) {
      var modules = self.usr.modules
      for (var i=0;i<modules.length;i++) {
        if (modules[i]===mod.id) {
          self.loadModule(mod)
          cb()
          break
        } else cb()
      }
    }
  }

  this.connModule = function (connect) { // ['modA>modB','modB>modC']

  }

  this.disconnModule = function (disconnect) {

  }

  this.loadModule = function (mod) { // load module!
    _[mod.id.toUpperCase()] = require(mod.filePath)
    _[mod.id] = new _[mod.id.toUpperCase()]()
    if (mod.html) _[mod.id].template = mod.html
  }

  this.unloadModule = function (mod) {

  }

  // ----------------------------------------------------
  this.addConnection = function (key) {
    self[key] = {}
    var s = self[key]

    // add write stream
    s.in = new stream.Writable()
    s.in._write = function (chunk, encoding, cb) {
      self.recv(chunk)
      cb()
    }

    // add read stream
    s.out = new stream()
    s.out.readable = true
    s.send = function (data) {
      s.out.emit('data',JSON.stringify(data))
    }
  }

  this.removeConnection = function (key) {
    self[key].out.emit('close')
    delete self[key]
  }// ---------------------------------------------------
}
<commit_msg>update connModule method in brico<commit_after>var telepath = require('tele')
, stream = require('stream')
, async = require ('async')

module.exports = function (usr) { // BRICOLEUR
  var self = this
  , map = null
  , _ = {} // module scope
  telepath(this)

  // detect if running in node or browser
  if (global.process && global.process.title === 'node') self.scope = 'server'
  if (!global.process) self.scope = 'client'

  if (usr) self.usr = usr

  this.recv = function (buffer) {
    var data = JSON.parse(buffer.toString())

    if (data.meta === 'module_map') { // add map
      map = data[self.scope]
      self.build()
    }
  }

  this.build = function () { // load modules
    if (!map) throw new Error('no map')

    async.forEach(map, match, function () {
      console.log(usr.host+' modules loaded')
    })

    function match (mod, cb) {
      var modules = self.usr.modules
      for (var i=0;i<modules.length;i++) {
        if (modules[i]===mod.id) {
          self.loadModule(mod)
          cb()
          break
        } else cb()
      }
    }
  }

  this.connModule = function (conn) { // ['modA>modB','modB>modC']
    var modA = null
    , modB = null

    for (key in conn) {
      modA = _[conn[key].split('>')[0]]
      modB = _[conn[key].split('>')[1]]
     if (!modA.out || !modB.in) throw new Error(modA+','+modB+' :no .out or .in connections')
     if (modA.out && modB.in) modA.out.pipe(modB.in)
    }
  }

  this.disconnModule = function (disconn) {

  }

  this.loadModule = function (mod) { // load module!
    _[mod.id.toUpperCase()] = require(mod.filePath)
    _[mod.id] = new _[mod.id.toUpperCase()]()
    if (mod.html) _[mod.id].template = mod.html
  }

  this.unloadModule = function (mod) {

  }

  // ----------------------------------------------------
  this.addConnection = function (key) {
    self[key] = {}
    var s = self[key]

    // add write stream
    s.in = new stream.Writable()
    s.in._write = function (chunk, encoding, cb) {
      self.recv(chunk)
      cb()
    }

    // add read stream
    s.out = new stream()
    s.out.readable = true
    s.send = function (data) {
      s.out.emit('data',JSON.stringify(data))
    }
  }

  this.removeConnection = function (key) {
    self[key].out.emit('close')
    delete self[key]
  }// ---------------------------------------------------
}
<|endoftext|>


<commit_before>// BROWSER ENVIRONMENT
if(!Function.prototype.bind) require('bindshim') //kindle jalopy doesn't have bind
var host = window.document.location.host.replace(/:.*/, '')
var ws = require('websocket-stream')
var wss = ws('ws://'+host)

wss.onopen = function () {
  console.log('connected')
}
wss.on('data', function (d) {
  console.log(d)
})
wss.on('close', function () {
  console.log('server close')
})
<commit_msg>fix open event listener<commit_after>// BROWSER ENVIRONMENT
if(!Function.prototype.bind) require('bindshim') //kindle jalopy doesn't have bind
var host = window.document.location.host.replace(/:.*/, '')
var ws = require('websocket-stream')
var wss = ws('ws://'+host)

wss.on('open', function () {
  console.log('connected')
})
wss.on('data', function (d) {
  console.log(d)
})
wss.on('close', function () {
  console.log('server close')
})
<|endoftext|>


<commit_before>var fs = require('fs')
var url = require('url')
var http = require('http')
var https = require('https')
var level = require('level')
var _ = require('underscore')
var emitter = require('events').EventEmitter
var livestream = require('level-live-stream')
var engineServer = require('engine.io-stream')
var websocServer = require('ws').Server
var wsStream = require('websocket-stream')
var asyncMap = require('slide').asyncMap
var hash = require('crypto').createHash
var multiLevel = require('multilevel')
var browserify = require('browserify')
var formidable = require('formidable')
var uglify = require('uglify-js')
var through = require('through2')
var path = require('path')
var cuid = require('cuid')
var st = require('st')

var sessions = {edit:[]}
var users = {}
var pass

// allow websock \ swap (engine.io or ws)
module.exports.boot = boot
module.exports.cli = through.obj(cli) // new brico then pipe into process
module.exports.compile = compile
module.exports.upload = fileUpload
module.exports.auth = auth

var db

function cli (d, enc, n) {}

function auth (user, cb) { // client makes id
  if (!user.pass||!user.name) {
    var e = new Error('bad login!')
    e.code = 1
    cb(e, null)
    return false
  }
  if (!isCuid(user.pass)) {
    var sess = cuid()
    sessions[user.name].push(sess)
    cb(null, {key:'@'+user.name,value:sess})
  } else {
    if (_.find(sessions[user.name],function (s){return s===user.pass})) {
      cb(null, {key:'@'+user.name,value:user.pass})
    } else {
      var e = new Error('bad login!')
      e.code = 1
      cb(e, null)
    }
  }
}

function boot (conf, cb) {
  if (!fs.existsSync(__dirname+'/static')) fs.mkdir(__dirname+'/static')
  if (!fs.existsSync(__dirname+'/static/files'))fs.mkdir(__dirname+'/static/files')

  db = level(__dirname+'/'+conf.host)
             .on('error', handleErrs)
  livestream.install(db)
  multiLevel.writeManifest(db, __dirname+'/static/manifest.json')

  var h = hash('SHA256').update('nimoy').digest('hex')

  // write index
  fs.writeFileSync(__dirname+'/static/index.html',
    '<!doctype html>' +
    '' +
    '<meta charset="utf-8">' +
    '' +
    '<title></title>' +
    '<link rel="stylesheet" href="/style.css">' +
    '' +
    '' +
    '' +
    '' +
    ''
  )

  startServer(conf, db, function () {
    cb(server.close)
  })
}

function compile (conf, cb) {
  var IN = __dirname + '/_client.js'
  var OUT = __dirname + '/'+conf.path_static+'/bundle.js'
  var MODULES = __dirname + '/' + conf.path_modules
  var b = browserify(IN)
  var library  = {}

  var folders = fs.readdirSync(MODULES)

  // also compile the core lib
  asyncMap(folders, function compileModule (dir, next) {
    var folder = __dirname +'/'+conf.path_modules+dir
    if (!fs.statSync(folder).isDirectory()) {next();return false}
    if (dir[0]!=='.') {
      var pkg = (fs.existsSync(folder))
        ? JSON.parse(fs.readFileSync(folder+'/package.json',{encoding:'utf8'}))
        : null

      if (pkg && pkg.nimoy) {
        library[pkg.name] = pkg
        b.require(folder+'/'+pkg.main, {expose: pkg.name})
      }
    }
    next()
  }, function end () {
    library.env = {port: conf.port, host: conf.host}
    fs.writeFileSync(__dirname+'/library.json', JSON.stringify(library))
    var bundleJS = fs.createWriteStream(OUT)
    b.transform('brfs')
    b.bundle().pipe(bundleJS)
    bundleJS.on('finish', cb)
  })
}

function startServer (conf, db, cb) {
  var mount = st({
    index: 'index.html',
    path: __dirname+'/'+conf.path_static,
    url: '/',
    passthrough: true
  })

  if (!conf.ssl) {
    server = http.createServer(handleHttp)
  } else {
    server = https.createServer({
      honorCipherOrder : true,
      key : fs.readFileSync(conf.ssl.key),
      cert : fs.readFileSync(conf.ssl.cert),
      cipher : 'ecdh+aesgcm:dh+aesgcm:ecdh+aes256:dh+aes256:' +
               'ecdh+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:' +
               'RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'
    }, handleHttp)
  }

  function handleHttp (req, res) {
    res.setHeader('X-Frame-Options', 'Deny')
    if (conf.ssl)
      res.setHeader('Strict-Transport-Security','max-age=31536000')
    if (req.url === '/upload' && req.method === 'POST') {
      fileUpload(req, res)
    } else {
      mount(req, res, function err () {
        res.end('')
      })
    }
  }

  function handleSoc (soc) {
    soc.pipe(multiLevel.server(db, {
    auth: auth,
    access: function access (user, db, method, args) {
      if (!user || user.name !== 'edit') {
        if (/^put|^del|^batch|write/i.test(method)) { // no write access!
          throw new Error('read-only access');
        }
      }
    }})).pipe(soc)
    soc.on('error', console.error)
  }

  server.listen(conf.port, conf.host, cb)

  if (conf.soc==='engine') {
    engineServer(handleSoc, {cookie:false})
      .attach(server, '/ws')
  } else if (conf.soc==='ws' || !conf.soc) {
    var wss = new websocServer({server:server})
    wss.on('connection', function (soc) {
      var s = wsStream(soc)
      handleSoc(s)
    })
  }
}

function fileUpload (req, res) { // replace w. external!?
  var form = new formidable.IncomingForm()
  form.parse(req, function(err, fields, files) {
    var filePath = __dirname+'/static/files/'+fields.file
    var blob = fields.blob.split(',')[1]
    res.writeHead(200, {'content-type': 'text/plain'})
    res.write('received upload:\n\n')
    res.end()
    fs.writeFile(filePath, blob, {encoding:'base64'}, function (e) {
      if (!e) db.put('file:'+fields.id, '/files/'+fields.file)
    })
  })
}

function handleErrs (e) { console.error(e) }

function isCuid (id) {
  var r = (typeof id==='string' && id.length===25 && id[0]==='c')
    ? true : false
  return r
}
<commit_msg>use mkdirsync to create static / files path in nimoy.compile<commit_after>var fs = require('fs')
var url = require('url')
var http = require('http')
var https = require('https')
var level = require('level')
var _ = require('underscore')
var emitter = require('events').EventEmitter
var livestream = require('level-live-stream')
var engineServer = require('engine.io-stream')
var websocServer = require('ws').Server
var wsStream = require('websocket-stream')
var asyncMap = require('slide').asyncMap
var hash = require('crypto').createHash
var multiLevel = require('multilevel')
var browserify = require('browserify')
var formidable = require('formidable')
var uglify = require('uglify-js')
var through = require('through2')
var path = require('path')
var cuid = require('cuid')
var st = require('st')

var sessions = {edit:[]}
var users = {}
var pass

// allow websock \ swap (engine.io or ws)
module.exports.boot = boot
module.exports.cli = through.obj(cli) // new brico then pipe into process
module.exports.compile = compile
module.exports.upload = fileUpload
module.exports.auth = auth

var db

function cli (d, enc, n) {}

function auth (user, cb) { // client makes id
  if (!user.pass||!user.name) {
    var e = new Error('bad login!')
    e.code = 1
    cb(e, null)
    return false
  }
  if (!isCuid(user.pass)) {
    var sess = cuid()
    sessions[user.name].push(sess)
    cb(null, {key:'@'+user.name,value:sess})
  } else {
    if (_.find(sessions[user.name],function (s){return s===user.pass})) {
      cb(null, {key:'@'+user.name,value:user.pass})
    } else {
      var e = new Error('bad login!')
      e.code = 1
      cb(e, null)
    }
  }
}

function boot (conf, cb) {
  if (!fs.existsSync(__dirname+'/static'))
    fs.mkdirSync(__dirname+'/static')

  if (!fs.existsSync(__dirname+'/static/files'))
    fs.mkdirSync(__dirname+'/static/files')

  db = level(__dirname+'/'+conf.host)
             .on('error', handleErrs)
  livestream.install(db)
  multiLevel.writeManifest(db, __dirname+'/static/manifest.json')

  var h = hash('SHA256').update('nimoy').digest('hex')

  // write index
  fs.writeFileSync(__dirname+'/static/index.html',
    '<!doctype html>' +
    '' +
    '<meta charset="utf-8">' +
    '' +
    '<title></title>' +
    '<link rel="stylesheet" href="/style.css">' +
    '' +
    '' +
    '' +
    '' +
    ''
  )

  startServer(conf, db, function () {
    cb(server.close)
  })
}

function compile (conf, cb) {
  var IN = __dirname + '/_client.js'
  var OUT = __dirname + '/'+conf.path_static+'/bundle.js'
  var MODULES = __dirname + '/' + conf.path_modules
  var b = browserify(IN)
  var library  = {}

  var folders = fs.readdirSync(MODULES)

  // also compile the core lib
  asyncMap(folders, function compileModule (dir, next) {
    var folder = __dirname +'/'+conf.path_modules+dir
    if (!fs.statSync(folder).isDirectory()) {next();return false}
    if (dir[0]!=='.') {
      var pkg = (fs.existsSync(folder))
        ? JSON.parse(fs.readFileSync(folder+'/package.json',{encoding:'utf8'}))
        : null

      if (pkg && pkg.nimoy) {
        library[pkg.name] = pkg
        b.require(folder+'/'+pkg.main, {expose: pkg.name})
      }
    }
    next()
  }, function end () {
    library.env = {port: conf.port, host: conf.host}
    fs.writeFileSync(__dirname+'/library.json', JSON.stringify(library))
    var bundleJS = fs.createWriteStream(OUT)
    b.transform('brfs')
    b.bundle().pipe(bundleJS)
    bundleJS.on('finish', cb)
  })
}

function startServer (conf, db, cb) {
  var mount = st({
    index: 'index.html',
    path: __dirname+'/'+conf.path_static,
    url: '/',
    passthrough: true
  })

  if (!conf.ssl) {
    server = http.createServer(handleHttp)
  } else {
    server = https.createServer({
      honorCipherOrder : true,
      key : fs.readFileSync(conf.ssl.key),
      cert : fs.readFileSync(conf.ssl.cert),
      cipher : 'ecdh+aesgcm:dh+aesgcm:ecdh+aes256:dh+aes256:' +
               'ecdh+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:' +
               'RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'
    }, handleHttp)
  }

  function handleHttp (req, res) {
    res.setHeader('X-Frame-Options', 'Deny')
    if (conf.ssl)
      res.setHeader('Strict-Transport-Security','max-age=31536000')
    if (req.url === '/upload' && req.method === 'POST') {
      fileUpload(req, res)
    } else {
      mount(req, res, function err () {
        res.end('')
      })
    }
  }

  function handleSoc (soc) {
    soc.pipe(multiLevel.server(db, {
    auth: auth,
    access: function access (user, db, method, args) {
      if (!user || user.name !== 'edit') {
        if (/^put|^del|^batch|write/i.test(method)) { // no write access!
          throw new Error('read-only access');
        }
      }
    }})).pipe(soc)
    soc.on('error', console.error)
  }

  server.listen(conf.port, conf.host, cb)

  if (conf.soc==='engine') {
    engineServer(handleSoc, {cookie:false})
      .attach(server, '/ws')
  } else if (conf.soc==='ws' || !conf.soc) {
    var wss = new websocServer({server:server})
    wss.on('connection', function (soc) {
      var s = wsStream(soc)
      handleSoc(s)
    })
  }
}

function fileUpload (req, res) { // replace w. external!?
  var form = new formidable.IncomingForm()
  form.parse(req, function(err, fields, files) {
    var filePath = __dirname+'/static/files/'+fields.file
    var blob = fields.blob.split(',')[1]
    res.writeHead(200, {'content-type': 'text/plain'})
    res.write('received upload:\n\n')
    res.end()
    fs.writeFile(filePath, blob, {encoding:'base64'}, function (e) {
      if (!e) db.put('file:'+fields.id, '/files/'+fields.file)
    })
  })
}

function handleErrs (e) { console.error(e) }

function isCuid (id) {
  var r = (typeof id==='string' && id.length===25 && id[0]==='c')
    ? true : false
  return r
}
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc component
 * @name mcp.directive:modal
 * @description
 * # modal
 */
angular.module('mobileControlPanelApp').directive('modal', function($timeout) {
  return {
    template: `<button class="btn launch" ng-class={{ngClass}}>{{launch}}</button>

                      <button type="button" class="close icon" aria-hidden="true">

                      </button>

{{modalTitle}}

                      <ng-transclude></ng-transclude>

                      <button type="button" class="btn btn-default cancel">Cancel</button>
                      <button type="button" class="btn btn-primary ok">Create</button>

`,
    scope: {
      displayControls: '=?',
      modalOpen: '=?',
      launch: '=?',
      modalTitle: '=?',
      cancel: '&?',
      ok: '&?',
      ngClass: '=?',
      modalClass: '=?'
    },
    transclude: true,
    link: function(scope, element, attrs) {
      element.removeClass();

      const modalContainer = $('.modal.container', element);
      modalContainer.addClass(scope.modalClass);
      scope.modal = modalContainer.modal({
        show: false,
        keyboard: true
      });

      scope.modalOpen = scope.modalOpen || false;

      $timeout(() => {
        const launchButton = $('.launch', element);
        const okButton = $('.ok', modalContainer);
        const cancelButton = $('.cancel', modalContainer);
        const closeIcon = $('.close', modalContainer);

        modalContainer.detach();

        launchButton.addClass(attrs.class);
        launchButton.on('click', () => {
          $timeout(() => {
            scope.modalOpen = true;
          });
        });

        okButton.on('click', () => {
          $timeout(() => {
            scope.ok && scope.ok()();
            scope.modalOpen = false;
          });
        });

        cancelButton.on('click', () => {
          $timeout(() => {
            scope.cancel && scope.cancel()();
            scope.modalOpen = false;
          });
        });

        closeIcon.on('click', () => {
          $timeout(() => {
            scope.cancel && scope.cancel()();
            scope.modalOpen = false;
          });
        });

        scope.modal.on('hidden.bs.modal', () => {
          if (!scope.modalOpen) {
            return;
          }

          $timeout(() => {
            scope.modalOpen = false;
          });
        });

        scope.$watch('modalOpen', value => {
          if (value) {
            scope.modal.modal('show');
          } else {
            scope.modal.modal('hide');
            $('.modal-backdrop').remove();
          }
        });
      });
    }
  };
});
<commit_msg>Annotate dependencies for minification<commit_after>'use strict';

/**
 * @ngdoc component
 * @name mcp.directive:modal
 * @description
 * # modal
 */
angular.module('mobileControlPanelApp').directive('modal', [
  '$timeout',
  function($timeout) {
    return {
      template: `<button class="btn launch" ng-class={{ngClass}}>{{launch}}</button>

                      <button type="button" class="close icon" aria-hidden="true">

                      </button>

{{modalTitle}}

                      <ng-transclude></ng-transclude>

                      <button type="button" class="btn btn-default cancel">Cancel</button>
                      <button type="button" class="btn btn-primary ok">Create</button>

`,
      scope: {
        displayControls: '=?',
        modalOpen: '=?',
        launch: '=?',
        modalTitle: '=?',
        cancel: '&?',
        ok: '&?',
        ngClass: '=?',
        modalClass: '=?'
      },
      transclude: true,
      link: function(scope, element, attrs) {
        element.removeClass();

        const modalContainer = $('.modal.container', element);
        modalContainer.addClass(scope.modalClass);
        scope.modal = modalContainer.modal({
          show: false,
          keyboard: true
        });

        scope.modalOpen = scope.modalOpen || false;

        $timeout(() => {
          const launchButton = $('.launch', element);
          const okButton = $('.ok', modalContainer);
          const cancelButton = $('.cancel', modalContainer);
          const closeIcon = $('.close', modalContainer);

          modalContainer.detach();

          launchButton.addClass(attrs.class);
          launchButton.on('click', () => {
            $timeout(() => {
              scope.modalOpen = true;
            });
          });

          okButton.on('click', () => {
            $timeout(() => {
              scope.ok && scope.ok()();
              scope.modalOpen = false;
            });
          });

          cancelButton.on('click', () => {
            $timeout(() => {
              scope.cancel && scope.cancel()();
              scope.modalOpen = false;
            });
          });

          closeIcon.on('click', () => {
            $timeout(() => {
              scope.cancel && scope.cancel()();
              scope.modalOpen = false;
            });
          });

          scope.modal.on('hidden.bs.modal', () => {
            if (!scope.modalOpen) {
              return;
            }

            $timeout(() => {
              scope.modalOpen = false;
            });
          });

          scope.$watch('modalOpen', value => {
            if (value) {
              scope.modal.modal('show');
            } else {
              scope.modal.modal('hide');
              $('.modal-backdrop').remove();
            }
          });
        });
      }
    };
  }
]);
<|endoftext|>