<commit_before>import {AutocompleteList} from './autocomplete-list';
import {AutocompleteInput} from './autocomplete-input';
import classnames from 'classnames';
import Cursor from 'pui-cursor';
import from from 'from';
import {default as mixin} from '../mixins';
import React from 'react';
import scrollIntoView from 'scroll-into-view';
import Scrim from '../mixins/mixins/scrim_mixin';
import through from 'through';
import TrieSearch from 'trie-search';
import PropTypes from 'prop-types';

const trieFromSearchableItems = (searchableItems, trieOptions) => {
  return new Promise(resolve => {
    let trie;
    from(function (count, callback) {
      if (searchableItems && count >= searchableItems.length) this.emit('end');
      this.emit('data', searchableItems[count]);
      callback();
    }).pipe(through(value => {
      if (typeof value === 'object') {
        if (!trie) trie = new TrieSearch(null, trieOptions);
        trie.addFromObject(value);
        resolve(trie);
        return;
      }
      if (!trie) trie = new TrieSearch('value', trieOptions);
      trie.add({value});
      resolve(trie);
    }));
  });
};

export class Autocomplete extends mixin(React.Component).with(Scrim) {
  static propTypes = {
    className: PropTypes.string,
    disabled: PropTypes.bool,
    input: PropTypes.object,
    maxItems: PropTypes.number,
    onClick: PropTypes.func,
    onFilter: PropTypes.func,
    onFocus: PropTypes.func,
    onInitializeItems: PropTypes.func,
    onPick: PropTypes.func,
    onSearch: PropTypes.func,
    placeholder: PropTypes.string,
    selectedSuggestion: PropTypes.any,
    trieOptions: PropTypes.object,
    value: PropTypes.string,
    showNoSearchResults: PropTypes.bool
  };

  static defaultProps = {
    maxItems: 50,
    onInitializeItems: done => done([]),
    input: <AutocompleteInput/>,
    placeholder: 'Search',
    showNoSearchResults: false
  };

  constructor(props, context) {
    super(props, context);
    const value = this.props.value || '';
    this.state = {hidden: true, highlightedSuggestion: 0, suggestedValues: [], trie: null, value};
  }

  componentWillReceiveProps({value}) {
    if (value !== this.props.value) {
      this.setState({value});
    }
  }

  componentDidMount() {
    super.componentDidMount();
    require('../../css/autocomplete');
    this.props.onInitializeItems((searchableItems = []) => {
      return trieFromSearchableItems(searchableItems, this.props.trieOptions).then(trie => {
        this.setState({searchableItems, trie});
      });
    });
  }

  searchItemsInOrder = () => {
    const {searchableItems} = this.state;
    if (searchableItems.every(item => typeof item === 'string')) return searchableItems.map(value => ({value}));

    return searchableItems.map(item => {
      const key = Object.keys(item)[0];
      return {_key_: key, value: item[key]};
    });
  };

  onSearch = (value, callback) => {
    if (this.props.onSearch) return this.props.onSearch(value, callback);
    const {maxItems} = this.props;
    const {trie} = this.state;
    if (!trie) return callback([]);
    value = value.trim();
    let result = value ? trie.get(value) : this.searchItemsInOrder();

    if (this.props.onFilter) {
      result = this.props.onFilter(result);
    }
    callback(result.slice(0, maxItems));
  };

  updateList = (defaultValue = null) => {
    const value = defaultValue === null ? this.state.value : defaultValue;
    this.onSearch(value, (suggestedValues) => {
      this.setState({suggestedValues: suggestedValues});
    });
  };

  showList = (defaultValue = null) => {
    const value = defaultValue === null ? this.state.value : defaultValue;
    this.onSearch(value, (suggestedValues) => {
      this.setState({hidden: false, suggestedValues: suggestedValues});
    });
  };

  onPick = value => {
    this.props.onPick && this.props.onPick(value);
    this.hideList();
  };

  scrollIntoViewFn = () => {
    if (!this.autocomplete) return;
    Array.from(this.autocomplete.querySelectorAll('.highlighted'))
      .map(el => scrollIntoView(el, {validTarget: target => target !== window}));
  };

  hideList = () => this.setState({hidden: true});
  scrimClick = () => this.hideList();

  render() {
    const $autocomplete = new Cursor(this.state, state => this.setState(state));
    const {
      className, maxItems, onFocus, onClick, disabled, selectedSuggestion, placeholder, input, children,
      onInitializeItems: __IGNORE1, onFilter: __IGNORE2, onPick: __IGNORE3, onSearch: __IGNORE4,
      trieOptions: __IGNORE5, showNoSearchResults, ...props
    } = this.props;
    const {scrollIntoViewFn, onPick, onSearch} = this;
    const clonedInput = React.cloneElement(
      input,
      {$autocomplete, onPick, scrollIntoView: scrollIntoViewFn, onSearch, disabled, onFocus, onClick, placeholder}
    );

    return (

 this.autocomplete = ref} {...props}>
        {clonedInput}
        <AutocompleteList {...{$autocomplete, onPick, maxItems, selectedSuggestion, showNoSearchResults}}>
          {children}
        </AutocompleteList>

    );
  }
}
<commit_msg>Lock trie-search to version 1.1.0 for IE compatibility [#158801137]<commit_after>import {AutocompleteList} from './autocomplete-list';
import {AutocompleteInput} from './autocomplete-input';
import classnames from 'classnames';
import Cursor from 'pui-cursor';
import from from 'from';
import {default as mixin} from '../mixins';
import React from 'react';
import scrollIntoView from 'scroll-into-view';
import Scrim from '../mixins/mixins/scrim_mixin';
import through from 'through';
import TrieSearch from 'trie-search';
import PropTypes from 'prop-types';

const trieFromSearchableItems = (searchableItems, trieOptions) => {
  return new Promise(resolve => {
    let trie;
    from(function (count, callback) {
      if (searchableItems && count >= searchableItems.length) this.emit('end');
      this.emit('data', searchableItems[count]);
      callback();
    }).pipe(through(value => {
      if (typeof value === 'object') {
        if (!trie) trie = new TrieSearch(null, trieOptions);
        trie.addFromObject(value);
        resolve(trie);
        return;
      }
      if (!trie) trie = new TrieSearch('value', trieOptions);
      trie.add({value});
      resolve(trie);
    }));
  });
};

export class Autocomplete extends mixin(React.Component).with(Scrim) {
  static propTypes = {
    className: PropTypes.string,
    disabled: PropTypes.bool,
    input: PropTypes.object,
    maxItems: PropTypes.number,
    onClick: PropTypes.func,
    onFilter: PropTypes.func,
    onFocus: PropTypes.func,
    onInitializeItems: PropTypes.func,
    onPick: PropTypes.func,
    onSearch: PropTypes.func,
    placeholder: PropTypes.string,
    selectedSuggestion: PropTypes.any,
    trieOptions: PropTypes.object,
    value: PropTypes.string,
    showNoSearchResults: PropTypes.bool
  };

  static defaultProps = {
    maxItems: 50,
    onInitializeItems: done => done([]),
    input: <AutocompleteInput/>,
    placeholder: 'Search',
    showNoSearchResults: false
  };

  constructor(props, context) {
    super(props, context);
    const value = this.props.value || '';
    this.state = {hidden: true, highlightedSuggestion: 0, suggestedValues: [], trie: null, value};
  }

  componentWillReceiveProps({value}) {
    if (value !== this.props.value) {
      this.setState({value});
    }
  }

  componentDidMount() {
    super.componentDidMount();
    require('../../css/autocomplete');
    this.props.onInitializeItems((searchableItems = []) => {
      return trieFromSearchableItems(searchableItems, this.props.trieOptions).then(trie => {
        this.setState({searchableItems, trie});
      });
    });
  }

  searchItemsInOrder = () => {
    const {searchableItems} = this.state;
    if (searchableItems.every(item => typeof item === 'string')) return searchableItems.map(value => ({value}));

    return searchableItems.map(item => {
      const key = Object.keys(item)[0];
      return {_key_: key, value: item[key]};
    });
  };

  onSearch = (value, callback) => {
    if (this.props.onSearch) return this.props.onSearch(value, callback);
    const {maxItems} = this.props;
    const {trie} = this.state;
    if (!trie) return callback([]);
    value = value.trim();
    let result = value ? trie.get(value) : this.searchItemsInOrder();

    if (this.props.onFilter) {
      result = this.props.onFilter(result);
    }
    callback(result.slice(0, maxItems));
  };

  updateList = (defaultValue = null) => {
    const value = defaultValue === null ? this.state.value : defaultValue;
    this.onSearch(value, (suggestedValues) => {
      this.setState({suggestedValues: suggestedValues});
    });
  };

  showList = (defaultValue = null) => {
    const value = defaultValue === null ? this.state.value : defaultValue;
    this.onSearch(value, (suggestedValues) => {
      this.setState({hidden: false, suggestedValues: suggestedValues});
    });
  };

  onPick = value => {
    this.props.onPick && this.props.onPick(value);
    this.hideList();
  };

  scrollIntoViewFn = () => {
    if (!this.autocomplete) return;
    Array.from(this.autocomplete.querySelectorAll('.highlighted'))
      .map(el => scrollIntoView(el, {validTarget: target => target !== window}));
  };

  hideList = () => this.setState({hidden: true});
  scrimClick = () => this.hideList();

  render() {
    const $autocomplete = new Cursor(this.state, state => this.setState(state));
    const {
      className, maxItems, onFocus, onClick, disabled, selectedSuggestion, placeholder, input, children,
      onInitializeItems: __IGNORE1, onFilter: __IGNORE2, onPick: __IGNORE3, onSearch: __IGNORE4,
      trieOptions: __IGNORE5, showNoSearchResults, ...props
    } = this.props;
    const {scrollIntoViewFn, onPick, onSearch} = this;
    const clonedInput = React.cloneElement(
      input,
      {$autocomplete, onPick, scrollIntoView: scrollIntoViewFn, onSearch, disabled, onFocus, onClick, placeholder}
    );

    return (

 this.autocomplete = ref} {...props}>
        {clonedInput}
        <AutocompleteList {...{
          $autocomplete, onPick, maxItems, selectedSuggestion, showNoSearchResults
        }}>
          {children}
        </AutocompleteList>

    );
  }
}
<|endoftext|>


<commit_before>var binary = require('node-pre-gyp');
var path = require('path');
var binding_path = binary.find(path.resolve(path.join(__dirname,'./package.json')));

var usb = exports = module.exports = require(binding_path);
var events = require('events')
var util = require('util')

// Check that libusb was initialized.
if (usb.INIT_ERROR) {
	throw new Error('Could not initialize libusb. Check that your system has a usb controller.');
}

Object.keys(events.EventEmitter.prototype).forEach(function (key) {
	exports[key] = events.EventEmitter.prototype[key];
});

// convenience method for finding a device by vendor and product id
exports.findByIds = function(vid, pid) {
	var devices = usb.getDeviceList()

	for (var i = 0; i < devices.length; i++) {
		var deviceDesc = devices[i].deviceDescriptor
		if ((deviceDesc.idVendor == vid) && (deviceDesc.idProduct == pid)) {
			return devices[i]
		}
	}
}

usb.Device.prototype.timeout = 1000

usb.Device.prototype.open = function(defaultConfig){
	this.__open()
	if (defaultConfig === false) return
	this.interfaces = []
	var len = this.configDescriptor.interfaces.length
	for (var i=0; i<len; i++){
		this.interfaces[i] = new Interface(this, i)
	}
}

usb.Device.prototype.close = function(){
	this.__close()
	this.interfaces = null
}

Object.defineProperty(usb.Device.prototype, "configDescriptor", {
	get: function() {
		return this._configDescriptor || (this._configDescriptor = this.__getConfigDescriptor())
	}
});

Object.defineProperty(usb.Device.prototype, "allConfigDescriptors", {
	get: function() {
		return this._allConfigDescriptors || (this._allConfigDescriptors = this.__getAllConfigDescriptors())
	}
});

Object.defineProperty(usb.Device.prototype, "parent", {
	get: function() {
		return this._parent || (this._parent = this.__getParent())
	}
});

usb.Device.prototype.interface = function(addr){
	if (!this.interfaces){
		throw new Error("Device must be open before searching for interfaces")
	}
	addr = addr || 0
	for (var i=0; i<this.interfaces.length; i++){
		if (this.interfaces[i].interfaceNumber == addr){
			return this.interfaces[i]
		}
	}
}

var SETUP_SIZE = usb.LIBUSB_CONTROL_SETUP_SIZE

usb.Device.prototype.controlTransfer =
function(bmRequestType, bRequest, wValue, wIndex, data_or_length, callback){
	var self = this
	var isIn = !!(bmRequestType & usb.LIBUSB_ENDPOINT_IN)
	var wLength

	if (isIn){
		if (!(data_or_length >= 0)){
			throw new TypeError("Expected size number for IN transfer (based on bmRequestType)")
		}
		wLength = data_or_length
	}else{
		if (!Buffer.isBuffer(data_or_length)){
			throw new TypeError("Expected buffer for OUT transfer (based on bmRequestType)")
		}
		wLength = data_or_length.length
	}

	// Buffer for the setup packet
	// http://libusbx.sourceforge.net/api-1.0/structlibusb__control__setup.html
	var buf = new Buffer(wLength + SETUP_SIZE)
	buf.writeUInt8(   bmRequestType, 0)
	buf.writeUInt8(   bRequest,      1)
	buf.writeUInt16LE(wValue,        2)
	buf.writeUInt16LE(wIndex,        4)
	buf.writeUInt16LE(wLength,       6)

	if (!isIn){
		data_or_length.copy(buf, SETUP_SIZE)
	}

	var transfer = new usb.Transfer(this, 0, usb.LIBUSB_TRANSFER_TYPE_CONTROL, this.timeout,
		function(error, buf, actual){
			if (callback){
				if (isIn){
					callback.call(self, error, buf.slice(SETUP_SIZE, SETUP_SIZE + actual))
				}else{
					callback.call(self, error)
				}
			}
		}
	)

	try {
		transfer.submit(buf)
	} catch (e) {
		if (callback){
			process.nextTick(function() { callback.call(self, e); });
		}
	}
	return this;
}

usb.Device.prototype.getStringDescriptor = function (desc_index, callback) {
	var langid = 0x0409;
	var length = 255;
	this.controlTransfer(
		usb.LIBUSB_ENDPOINT_IN,
		usb.LIBUSB_REQUEST_GET_DESCRIPTOR,
		((usb.LIBUSB_DT_STRING << 8) | desc_index),
		langid,
		length,
		function (error, buf) {
			if (error) return callback(error);
			callback(undefined, buf.toString('utf16le', 2));
		}
	);
}

usb.Device.prototype.setConfiguration = function(desired, cb) {
	var self = this;
	this.__setConfiguration(desired, function(err) {
		if (!err) {
			this.interfaces = []
			var len = this.configDescriptor.interfaces.length
			for (var i=0; i<len; i++) {
				this.interfaces[i] = new Interface(this, i)
			}
		}
		cb.call(self, err)
	});
}

function Interface(device, id){
	this.device = device
	this.id = id
	this.altSetting = 0;
	this.__refresh()
}

Interface.prototype.__refresh = function(){
	this.descriptor = this.device.configDescriptor.interfaces[this.id][this.altSetting]
	this.interfaceNumber = this.descriptor.bInterfaceNumber
	this.endpoints = []
	var len = this.descriptor.endpoints.length
	for (var i=0; i<len; i++){
		var desc = this.descriptor.endpoints[i]
		var c = (desc.bEndpointAddress&usb.LIBUSB_ENDPOINT_IN)?InEndpoint:OutEndpoint
		this.endpoints[i] = new c(this.device, desc)
	}
}

Interface.prototype.claim = function(){
	this.device.__claimInterface(this.id)
}

Interface.prototype.release = function(closeEndpoints, cb){
	var self = this;
	if (typeof closeEndpoints == 'function') {
		cb = closeEndpoints;
		closeEndpoints = null;
	}

	if (!closeEndpoints || this.endpoints.length == 0) {
		next();
	} else {
		var n = self.endpoints.length;
		self.endpoints.forEach(function (ep, i) {
			if (ep.pollActive) {
				ep.once('end', function () {
					if (--n == 0) next();
				});
				ep.stopPoll();
			} else {
				if (--n == 0) next();
			}
		});
	}

	function next () {
		self.device.__releaseInterface(self.id, function(err){
			if (!err){
				self.altSetting = 0;
				self.__refresh()
			}
			cb.call(self, err)
		})
	}
}

Interface.prototype.isKernelDriverActive = function(){
	return this.device.__isKernelDriverActive(this.id)
}

Interface.prototype.detachKernelDriver = function() {
	return this.device.__detachKernelDriver(this.id)
};

Interface.prototype.attachKernelDriver = function() {
	return this.device.__attachKernelDriver(this.id)
};

Interface.prototype.setAltSetting = function(altSetting, cb){
	var self = this;
	this.device.__setInterface(this.id, altSetting, function(err){
		if (!err){
			self.altSetting = altSetting;
			self.__refresh();
		}
		cb.call(self, err)
	})

}

Interface.prototype.endpoint = function(addr){
	for (var i=0; i<this.endpoints.length; i++){
		if (this.endpoints[i].address == addr){
			return this.endpoints[i]
		}
	}
}

function Endpoint(device, descriptor){
	this.device = device
	this.descriptor = descriptor
	this.address = descriptor.bEndpointAddress
	this.transferType = descriptor.bmAttributes&0x03
}
util.inherits(Endpoint, events.EventEmitter)

Endpoint.prototype.timeout = 0

Endpoint.prototype.makeTransfer = function(timeout, callback){
	return new usb.Transfer(this.device, this.address, this.transferType, timeout, callback)
}

Endpoint.prototype.startPoll = function(nTransfers, transferSize, callback){
	if (this.pollTransfers){
		throw new Error("Polling already active")
	}

	nTransfers = nTransfers || 3;
	this.pollTransferSize = transferSize || this.descriptor.wMaxPacketSize;
	this.pollActive = true
	this.pollPending = 0

	var transfers = []
	for (var i=0; i<nTransfers; i++){
		transfers[i] = this.makeTransfer(0, callback)
	}
	return transfers;
}

Endpoint.prototype.stopPoll = function(cb){
	if (!this.pollTransfers) {
		throw new Error('Polling is not active.');
	}
	for (var i=0; i<this.pollTransfers.length; i++){
		try {
			this.pollTransfers[i].cancel()
		} catch (err) {
			this.emit('error', err);
		}
	}
	this.pollActive = false
	if (cb) this.once('end', cb);
}

function InEndpoint(device, descriptor){
	Endpoint.call(this, device, descriptor)
}

exports.InEndpoint = InEndpoint
util.inherits(InEndpoint, Endpoint)
InEndpoint.prototype.direction = "in"

InEndpoint.prototype.transfer = function(length, cb){
	var self = this
	var buffer = new Buffer(length)

	function callback(error, buf, actual){
		cb.call(self, error, buffer.slice(0, actual))
	}

	try {
		this.makeTransfer(this.timeout, callback).submit(buffer)
	} catch (e) {
		process.nextTick(function() { cb.call(self, e); });
	}
	return this;
}

InEndpoint.prototype.startPoll = function(nTransfers, transferSize){
	var self = this
	this.pollTransfers = InEndpoint.super_.prototype.startPoll.call(this, nTransfers, transferSize, transferDone)

	function transferDone(error, buf, actual){
		if (!error){
			self.emit("data", buf.slice(0, actual))
		}else if (error.errno != usb.LIBUSB_TRANSFER_CANCELLED){
			self.emit("error", error)
			self.stopPoll()
		}

		if (self.pollActive){
			startTransfer(this)
		}else{
			self.pollPending--

			if (self.pollPending == 0){
				self.emit('end')
			}
		}
	}

	function startTransfer(t){
		try {
			t.submit(new Buffer(self.pollTransferSize), transferDone);
		} catch (e) {
			self.emit("error", e);
			self.stopPoll();
		}
	}

	this.pollTransfers.forEach(startTransfer)
	self.pollPending = this.pollTransfers.length
}

function OutEndpoint(device, descriptor){
	Endpoint.call(this, device, descriptor)
}
exports.OutEndpoint = OutEndpoint
util.inherits(OutEndpoint, Endpoint)
OutEndpoint.prototype.direction = "out"

OutEndpoint.prototype.transfer = function(buffer, cb){
	var self = this
	if (!buffer){
		buffer = new Buffer(0)
	}else if (!Buffer.isBuffer(buffer)){
		buffer = new Buffer(buffer)
	}

	function callback(error, buf, actual){
		if (cb) cb.call(self, error)
	}

	try {
		this.makeTransfer(this.timeout, callback).submit(buffer);
	} catch (e) {
		process.nextTick(function() { callback(e); });
	}

	return this;
}

OutEndpoint.prototype.transferWithZLP = function (buf, cb) {
	if (buf.length % this.descriptor.wMaxPacketSize == 0) {
		this.transfer(buf);
		this.transfer(new Buffer(0), cb);
	} else {
		this.transfer(buf, cb);
	}
}

var hotplugListeners = 0;
exports.on('newListener', function(name) {
	if (name !== 'attach' && name !== 'detach') return;
	if (++hotplugListeners === 1) usb._enableHotplugEvents();
});

exports.on('removeListener', function(name) {
	if (name !== 'attach' && name !== 'detach') return;
	if (--hotplugListeners === 0) usb._disableHotplugEvents();
});
<commit_msg>Allow loading module in environments without usb<commit_after>var binary = require('node-pre-gyp');
var path = require('path');
var binding_path = binary.find(path.resolve(path.join(__dirname,'./package.json')));

var usb = exports = module.exports = require(binding_path);
var events = require('events')
var util = require('util')

function ensureLibusbInitialized() {
	// Check that libusb was initialized.
	if (usb.INIT_ERROR) {
		throw new Error('Could not initialize libusb. Check that your system has a usb controller.');
	}
}

Object.keys(events.EventEmitter.prototype).forEach(function (key) {
	exports[key] = events.EventEmitter.prototype[key];
});

// convenience method for finding a device by vendor and product id
exports.findByIds = function(vid, pid) {
	ensureLibusbInitialized()
	var devices = usb.getDeviceList()

	for (var i = 0; i < devices.length; i++) {
		var deviceDesc = devices[i].deviceDescriptor
		if ((deviceDesc.idVendor == vid) && (deviceDesc.idProduct == pid)) {
			return devices[i]
		}
	}
}

usb.Device.prototype.timeout = 1000

usb.Device.prototype.open = function(defaultConfig){
	ensureLibusbInitialized()
	this.__open()
	if (defaultConfig === false) return
	this.interfaces = []
	var len = this.configDescriptor.interfaces.length
	for (var i=0; i<len; i++){
		this.interfaces[i] = new Interface(this, i)
	}
}

usb.Device.prototype.close = function(){
	this.__close()
	this.interfaces = null
}

Object.defineProperty(usb.Device.prototype, "configDescriptor", {
	get: function() {
		return this._configDescriptor || (this._configDescriptor = this.__getConfigDescriptor())
	}
});

Object.defineProperty(usb.Device.prototype, "allConfigDescriptors", {
	get: function() {
		return this._allConfigDescriptors || (this._allConfigDescriptors = this.__getAllConfigDescriptors())
	}
});

Object.defineProperty(usb.Device.prototype, "parent", {
	get: function() {
		return this._parent || (this._parent = this.__getParent())
	}
});

usb.Device.prototype.interface = function(addr){
	if (!this.interfaces){
		throw new Error("Device must be open before searching for interfaces")
	}
	addr = addr || 0
	for (var i=0; i<this.interfaces.length; i++){
		if (this.interfaces[i].interfaceNumber == addr){
			return this.interfaces[i]
		}
	}
}

var SETUP_SIZE = usb.LIBUSB_CONTROL_SETUP_SIZE

usb.Device.prototype.controlTransfer =
function(bmRequestType, bRequest, wValue, wIndex, data_or_length, callback){
	var self = this
	var isIn = !!(bmRequestType & usb.LIBUSB_ENDPOINT_IN)
	var wLength

	if (isIn){
		if (!(data_or_length >= 0)){
			throw new TypeError("Expected size number for IN transfer (based on bmRequestType)")
		}
		wLength = data_or_length
	}else{
		if (!Buffer.isBuffer(data_or_length)){
			throw new TypeError("Expected buffer for OUT transfer (based on bmRequestType)")
		}
		wLength = data_or_length.length
	}

	// Buffer for the setup packet
	// http://libusbx.sourceforge.net/api-1.0/structlibusb__control__setup.html
	var buf = new Buffer(wLength + SETUP_SIZE)
	buf.writeUInt8(   bmRequestType, 0)
	buf.writeUInt8(   bRequest,      1)
	buf.writeUInt16LE(wValue,        2)
	buf.writeUInt16LE(wIndex,        4)
	buf.writeUInt16LE(wLength,       6)

	if (!isIn){
		data_or_length.copy(buf, SETUP_SIZE)
	}

	var transfer = new usb.Transfer(this, 0, usb.LIBUSB_TRANSFER_TYPE_CONTROL, this.timeout,
		function(error, buf, actual){
			if (callback){
				if (isIn){
					callback.call(self, error, buf.slice(SETUP_SIZE, SETUP_SIZE + actual))
				}else{
					callback.call(self, error)
				}
			}
		}
	)

	try {
		transfer.submit(buf)
	} catch (e) {
		if (callback){
			process.nextTick(function() { callback.call(self, e); });
		}
	}
	return this;
}

usb.Device.prototype.getStringDescriptor = function (desc_index, callback) {
	var langid = 0x0409;
	var length = 255;
	this.controlTransfer(
		usb.LIBUSB_ENDPOINT_IN,
		usb.LIBUSB_REQUEST_GET_DESCRIPTOR,
		((usb.LIBUSB_DT_STRING << 8) | desc_index),
		langid,
		length,
		function (error, buf) {
			if (error) return callback(error);
			callback(undefined, buf.toString('utf16le', 2));
		}
	);
}

usb.Device.prototype.setConfiguration = function(desired, cb) {
	var self = this;
	this.__setConfiguration(desired, function(err) {
		if (!err) {
			this.interfaces = []
			var len = this.configDescriptor.interfaces.length
			for (var i=0; i<len; i++) {
				this.interfaces[i] = new Interface(this, i)
			}
		}
		cb.call(self, err)
	});
}

function Interface(device, id){
	ensureLibusbInitialized()
	this.device = device
	this.id = id
	this.altSetting = 0;
	this.__refresh()
}

Interface.prototype.__refresh = function(){
	this.descriptor = this.device.configDescriptor.interfaces[this.id][this.altSetting]
	this.interfaceNumber = this.descriptor.bInterfaceNumber
	this.endpoints = []
	var len = this.descriptor.endpoints.length
	for (var i=0; i<len; i++){
		var desc = this.descriptor.endpoints[i]
		var c = (desc.bEndpointAddress&usb.LIBUSB_ENDPOINT_IN)?InEndpoint:OutEndpoint
		this.endpoints[i] = new c(this.device, desc)
	}
}

Interface.prototype.claim = function(){
	this.device.__claimInterface(this.id)
}

Interface.prototype.release = function(closeEndpoints, cb){
	var self = this;
	if (typeof closeEndpoints == 'function') {
		cb = closeEndpoints;
		closeEndpoints = null;
	}

	if (!closeEndpoints || this.endpoints.length == 0) {
		next();
	} else {
		var n = self.endpoints.length;
		self.endpoints.forEach(function (ep, i) {
			if (ep.pollActive) {
				ep.once('end', function () {
					if (--n == 0) next();
				});
				ep.stopPoll();
			} else {
				if (--n == 0) next();
			}
		});
	}

	function next () {
		self.device.__releaseInterface(self.id, function(err){
			if (!err){
				self.altSetting = 0;
				self.__refresh()
			}
			cb.call(self, err)
		})
	}
}

Interface.prototype.isKernelDriverActive = function(){
	return this.device.__isKernelDriverActive(this.id)
}

Interface.prototype.detachKernelDriver = function() {
	return this.device.__detachKernelDriver(this.id)
};

Interface.prototype.attachKernelDriver = function() {
	return this.device.__attachKernelDriver(this.id)
};

Interface.prototype.setAltSetting = function(altSetting, cb){
	var self = this;
	this.device.__setInterface(this.id, altSetting, function(err){
		if (!err){
			self.altSetting = altSetting;
			self.__refresh();
		}
		cb.call(self, err)
	})

}

Interface.prototype.endpoint = function(addr){
	for (var i=0; i<this.endpoints.length; i++){
		if (this.endpoints[i].address == addr){
			return this.endpoints[i]
		}
	}
}

function Endpoint(device, descriptor){
	ensureLibusbInitialized()
	this.device = device
	this.descriptor = descriptor
	this.address = descriptor.bEndpointAddress
	this.transferType = descriptor.bmAttributes&0x03
}
util.inherits(Endpoint, events.EventEmitter)

Endpoint.prototype.timeout = 0

Endpoint.prototype.makeTransfer = function(timeout, callback){
	return new usb.Transfer(this.device, this.address, this.transferType, timeout, callback)
}

Endpoint.prototype.startPoll = function(nTransfers, transferSize, callback){
	if (this.pollTransfers){
		throw new Error("Polling already active")
	}

	nTransfers = nTransfers || 3;
	this.pollTransferSize = transferSize || this.descriptor.wMaxPacketSize;
	this.pollActive = true
	this.pollPending = 0

	var transfers = []
	for (var i=0; i<nTransfers; i++){
		transfers[i] = this.makeTransfer(0, callback)
	}
	return transfers;
}

Endpoint.prototype.stopPoll = function(cb){
	if (!this.pollTransfers) {
		throw new Error('Polling is not active.');
	}
	for (var i=0; i<this.pollTransfers.length; i++){
		try {
			this.pollTransfers[i].cancel()
		} catch (err) {
			this.emit('error', err);
		}
	}
	this.pollActive = false
	if (cb) this.once('end', cb);
}

function InEndpoint(device, descriptor){
	Endpoint.call(this, device, descriptor)
}

exports.InEndpoint = InEndpoint
util.inherits(InEndpoint, Endpoint)
InEndpoint.prototype.direction = "in"

InEndpoint.prototype.transfer = function(length, cb){
	var self = this
	var buffer = new Buffer(length)

	function callback(error, buf, actual){
		cb.call(self, error, buffer.slice(0, actual))
	}

	try {
		this.makeTransfer(this.timeout, callback).submit(buffer)
	} catch (e) {
		process.nextTick(function() { cb.call(self, e); });
	}
	return this;
}

InEndpoint.prototype.startPoll = function(nTransfers, transferSize){
	var self = this
	this.pollTransfers = InEndpoint.super_.prototype.startPoll.call(this, nTransfers, transferSize, transferDone)

	function transferDone(error, buf, actual){
		if (!error){
			self.emit("data", buf.slice(0, actual))
		}else if (error.errno != usb.LIBUSB_TRANSFER_CANCELLED){
			self.emit("error", error)
			self.stopPoll()
		}

		if (self.pollActive){
			startTransfer(this)
		}else{
			self.pollPending--

			if (self.pollPending == 0){
				self.emit('end')
			}
		}
	}

	function startTransfer(t){
		try {
			t.submit(new Buffer(self.pollTransferSize), transferDone);
		} catch (e) {
			self.emit("error", e);
			self.stopPoll();
		}
	}

	this.pollTransfers.forEach(startTransfer)
	self.pollPending = this.pollTransfers.length
}

function OutEndpoint(device, descriptor){
	Endpoint.call(this, device, descriptor)
}
exports.OutEndpoint = OutEndpoint
util.inherits(OutEndpoint, Endpoint)
OutEndpoint.prototype.direction = "out"

OutEndpoint.prototype.transfer = function(buffer, cb){
	var self = this
	if (!buffer){
		buffer = new Buffer(0)
	}else if (!Buffer.isBuffer(buffer)){
		buffer = new Buffer(buffer)
	}

	function callback(error, buf, actual){
		if (cb) cb.call(self, error)
	}

	try {
		this.makeTransfer(this.timeout, callback).submit(buffer);
	} catch (e) {
		process.nextTick(function() { callback(e); });
	}

	return this;
}

OutEndpoint.prototype.transferWithZLP = function (buf, cb) {
	if (buf.length % this.descriptor.wMaxPacketSize == 0) {
		this.transfer(buf);
		this.transfer(new Buffer(0), cb);
	} else {
		this.transfer(buf, cb);
	}
}

var hotplugListeners = 0;
exports.on('newListener', function(name) {
	if (name !== 'attach' && name !== 'detach') return;
	if (++hotplugListeners === 1) usb._enableHotplugEvents();
});

exports.on('removeListener', function(name) {
	if (name !== 'attach' && name !== 'detach') return;
	if (--hotplugListeners === 0) usb._disableHotplugEvents();
});
<|endoftext|>


<commit_before>/**
 * @file Create and build SOQL string from configuration
 * @author Shinichi Tomita <shinichi.tomita@gmail.com>
 */

'use strict';

var _      = require('lodash/core'),
    SfDate = require("./date");

/**
 * Create SOQL
 * @private
 */
function createSOQL(query) {
  var soql = [
    "SELECT ",
    createFieldsClause(query.fields, query.includes),
    " FROM ",
    query.table
  ].join("");
  var cond = createConditionClause(query.conditions);
  if (cond) {
    soql += " WHERE " + cond;
  }
  var orderby = createOrderByClause(query.sort);
  if (orderby) {
    soql += " ORDER BY " + orderby;
  }
  if (query.limit) {
    soql += " LIMIT " + query.limit;
  }
  if (query.offset) {
    soql += " OFFSET " + query.offset;
  }
  return soql;
}

/** @private **/
function createFieldsClause(fields, childQueries) {
  childQueries = _.map(_.values(childQueries || {}), function(cquery) {
    return '(' + createSOQL(cquery) + ')';
  });
  return (fields || [ "Id" ]).concat(childQueries).join(', ');
}

/** @private **/
function createConditionClause(conditions, operator, depth) {
  if (_.isString(conditions)) {
    return conditions;
  }
  conditions = conditions || [];
  operator = operator || "AND";
  depth = depth || 0;
  if (!isArray(conditions)) { // if passed in hash object
    conditions = _.keys(conditions).map(function(key) {
      return {
        key: key,
        value: conditions[key]
      };
    });
  } else {
    conditions = conditions.map(function(cond) {
      var conds = [];
      for (var key in cond) {
        conds.push({
          key: key,
          value: cond[key]
        });
      }
      return conds.length>1 ? conds : conds[0];
    });
  }
  conditions = conditions.map(function(cond) {
    var d = depth+1, op;
    switch (cond.key) {
      case "$or" :
      case "$and" :
      case "$not" :
        if (operator !== "NOT" && conditions.length === 1) {
          d = depth; // not change tree depth
        }
        op = cond.key === "$or" ? "OR" :
             cond.key === "$and" ? "AND" :
             "NOT";
        return createConditionClause(cond.value, op, d);
      default:
        return createFieldExpression(cond.key, cond.value);
    }
  }).filter(function(expr) { return expr; });

  var paren;
  if (operator === 'NOT') {
    paren = depth > 0;
    return (paren ? "(" : "") + "NOT " + conditions[0] + (paren ? ")" : "");
  } else {
    paren = depth > 0 && conditions.length > 1;
    return (paren ? "(" : "") + conditions.join(" "+operator+" ") + (paren ? ")" : "");
  }
}

var opMap = {
  "="     : "=",
  "$eq"   : "=",
  "!="    : "!=",
  "$ne"   : "!=",
  ">"     : ">",
  "$gt"   : ">",
  "<"     : "<",
  "$lt"   : "<",
  ">="    : ">=",
  "$gte"  : ">=",
  "<="    : "<=",
  "$lte"  : "<=",
  "$like" : "LIKE",
  "$nlike" : "NOT LIKE",
  "$in"   : "IN",
  "$nin"  : "NOT IN",
  "$exists" : "EXISTS"
};

/** @private **/
function createFieldExpression(field, value) {
  var op = "$eq";

  // Assume the `$in` operator if value is an array and none was supplied.
  if (_.isArray(value)) { op = "$in"; }
  // Otherwise, if an object was passed then process the supplied ops.
  else if (_.isObject(value)) {
    var _value;
    for (var k in value) {
      if (k[0] === "$") {
        op = k;
        value = value[k];
        break;
      }
    }
  }
  var sfop = opMap[op];
  if (!sfop || _.isUndefined(value)) { return null; }
  var valueExpr = createValueExpression(value);
  if (_.isUndefined(valueExpr)) { return null; }
  switch (sfop) {
    case "NOT LIKE":
      return "(" + [ "NOT", field, 'LIKE', valueExpr ].join(" ") + ")";
    case "EXISTS":
      return [ field, value ? "!=" : "=", "null" ].join(" ");
    default:
      return [ field, sfop, valueExpr ].join(" ");
  }
}

/** @private **/
function createValueExpression(value) {
  if (isArray(value)) {
    return value.length > 0 ?
           "(" + value.map(createValueExpression).join(", ") + ")" :
           undefined;
  }
  if (value instanceof SfDate) {
    return value.toString();
  }
  if (_.isString(value)) {
    return "'" + escapeSOQLString(value) + "'";
  }
  if (_.isNumber(value)) {
    return (value).toString();
  }
  if (_.isNull(value)) {
    return "null";
  }
  return value;
}

/** @private **/
function escapeSOQLString(str) {
  return String(str || '').replace(/'/g, "\\'");
}

/** @private **/
function isArray(a) {
  return _.isObject(a) && _.isFunction(a.pop);
}

/** @private **/
function createOrderByClause(sort) {
  sort = sort || [];
  if (_.isString(sort)) {
    if (/,|\s+(asc|desc)\s*$/.test(sort)) {
      // must be specified in pure "order by" clause. Return raw config.
      return sort;
    }
    // sort order in mongoose-style expression.
    // e.g. "FieldA -FieldB" => "ORDER BY FieldA ASC, FieldB DESC"
    sort = sort.split(/\s+/).map(function(field) {
      var dir = "ASC"; // ascending
      var flag = field[0];
      if (flag === '-') {
        dir = "DESC";
        field = field.substring(1);
      } else if (flag === '+') {
        field = field.substring(1);
      }
      return [ field, dir ];
    });
  } else if (!isArray(sort)) {
    sort = _.keys(sort).map(function(field) {
      var dir = sort[field];
      return [ field, dir ];
    });
  }
  return sort.map(function(s) {
    var field = s[0], dir = s[1];
    switch (String(dir)) {
      case "DESC":
      case "desc":
      case "descending":
      case "-":
      case "-1":
        dir = "DESC";
        break;
      default:
        dir = "ASC";
    }
    return field + " " + dir;
  }).join(", ");
}

exports.createSOQL = createSOQL;
<commit_msg>Added INCLUDES and EXCLUDES to the opMap<commit_after>/**
 * @file Create and build SOQL string from configuration
 * @author Shinichi Tomita <shinichi.tomita@gmail.com>
 */

'use strict';

var _      = require('lodash/core'),
    SfDate = require("./date");

/**
 * Create SOQL
 * @private
 */
function createSOQL(query) {
  var soql = [
    "SELECT ",
    createFieldsClause(query.fields, query.includes),
    " FROM ",
    query.table
  ].join("");
  var cond = createConditionClause(query.conditions);
  if (cond) {
    soql += " WHERE " + cond;
  }
  var orderby = createOrderByClause(query.sort);
  if (orderby) {
    soql += " ORDER BY " + orderby;
  }
  if (query.limit) {
    soql += " LIMIT " + query.limit;
  }
  if (query.offset) {
    soql += " OFFSET " + query.offset;
  }
  return soql;
}

/** @private **/
function createFieldsClause(fields, childQueries) {
  childQueries = _.map(_.values(childQueries || {}), function(cquery) {
    return '(' + createSOQL(cquery) + ')';
  });
  return (fields || [ "Id" ]).concat(childQueries).join(', ');
}

/** @private **/
function createConditionClause(conditions, operator, depth) {
  if (_.isString(conditions)) {
    return conditions;
  }
  conditions = conditions || [];
  operator = operator || "AND";
  depth = depth || 0;
  if (!isArray(conditions)) { // if passed in hash object
    conditions = _.keys(conditions).map(function(key) {
      return {
        key: key,
        value: conditions[key]
      };
    });
  } else {
    conditions = conditions.map(function(cond) {
      var conds = [];
      for (var key in cond) {
        conds.push({
          key: key,
          value: cond[key]
        });
      }
      return conds.length>1 ? conds : conds[0];
    });
  }
  conditions = conditions.map(function(cond) {
    var d = depth+1, op;
    switch (cond.key) {
      case "$or" :
      case "$and" :
      case "$not" :
        if (operator !== "NOT" && conditions.length === 1) {
          d = depth; // not change tree depth
        }
        op = cond.key === "$or" ? "OR" :
             cond.key === "$and" ? "AND" :
             "NOT";
        return createConditionClause(cond.value, op, d);
      default:
        return createFieldExpression(cond.key, cond.value);
    }
  }).filter(function(expr) { return expr; });

  var paren;
  if (operator === 'NOT') {
    paren = depth > 0;
    return (paren ? "(" : "") + "NOT " + conditions[0] + (paren ? ")" : "");
  } else {
    paren = depth > 0 && conditions.length > 1;
    return (paren ? "(" : "") + conditions.join(" "+operator+" ") + (paren ? ")" : "");
  }
}

var opMap = {
  "="     : "=",
  "$eq"   : "=",
  "!="    : "!=",
  "$ne"   : "!=",
  ">"     : ">",
  "$gt"   : ">",
  "<"     : "<",
  "$lt"   : "<",
  ">="    : ">=",
  "$gte"  : ">=",
  "<="    : "<=",
  "$lte"  : "<=",
  "$like" : "LIKE",
  "$nlike" : "NOT LIKE",
  "$in"   : "IN",
  "$nin"  : "NOT IN",
  "$includes" : "INCLUDES",
  "$excludes" : "EXCLUDES",
  "$exists" : "EXISTS"
};

/** @private **/
function createFieldExpression(field, value) {
  var op = "$eq";

  // Assume the `$in` operator if value is an array and none was supplied.
  if (_.isArray(value)) { op = "$in"; }
  // Otherwise, if an object was passed then process the supplied ops.
  else if (_.isObject(value)) {
    var _value;
    for (var k in value) {
      if (k[0] === "$") {
        op = k;
        value = value[k];
        break;
      }
    }
  }
  var sfop = opMap[op];
  if (!sfop || _.isUndefined(value)) { return null; }
  var valueExpr = createValueExpression(value);
  if (_.isUndefined(valueExpr)) { return null; }
  switch (sfop) {
    case "NOT LIKE":
      return "(" + [ "NOT", field, 'LIKE', valueExpr ].join(" ") + ")";
    case "EXISTS":
      return [ field, value ? "!=" : "=", "null" ].join(" ");
    default:
      return [ field, sfop, valueExpr ].join(" ");
  }
}

/** @private **/
function createValueExpression(value) {
  if (isArray(value)) {
    return value.length > 0 ?
           "(" + value.map(createValueExpression).join(", ") + ")" :
           undefined;
  }
  if (value instanceof SfDate) {
    return value.toString();
  }
  if (_.isString(value)) {
    return "'" + escapeSOQLString(value) + "'";
  }
  if (_.isNumber(value)) {
    return (value).toString();
  }
  if (_.isNull(value)) {
    return "null";
  }
  return value;
}

/** @private **/
function escapeSOQLString(str) {
  return String(str || '').replace(/'/g, "\\'");
}

/** @private **/
function isArray(a) {
  return _.isObject(a) && _.isFunction(a.pop);
}

/** @private **/
function createOrderByClause(sort) {
  sort = sort || [];
  if (_.isString(sort)) {
    if (/,|\s+(asc|desc)\s*$/.test(sort)) {
      // must be specified in pure "order by" clause. Return raw config.
      return sort;
    }
    // sort order in mongoose-style expression.
    // e.g. "FieldA -FieldB" => "ORDER BY FieldA ASC, FieldB DESC"
    sort = sort.split(/\s+/).map(function(field) {
      var dir = "ASC"; // ascending
      var flag = field[0];
      if (flag === '-') {
        dir = "DESC";
        field = field.substring(1);
      } else if (flag === '+') {
        field = field.substring(1);
      }
      return [ field, dir ];
    });
  } else if (!isArray(sort)) {
    sort = _.keys(sort).map(function(field) {
      var dir = sort[field];
      return [ field, dir ];
    });
  }
  return sort.map(function(s) {
    var field = s[0], dir = s[1];
    switch (String(dir)) {
      case "DESC":
      case "desc":
      case "descending":
      case "-":
      case "-1":
        dir = "DESC";
        break;
      default:
        dir = "ASC";
    }
    return field + " " + dir;
  }).join(", ");
}

exports.createSOQL = createSOQL;
<|endoftext|>


<commit_before>import { Vector3 } from '../../math/Vector3.js';
import { Group } from '../../objects/Group.js';

const _moveEvent = { type: 'move' };

class WebXRController {

	constructor() {

		this._targetRay = null;
		this._grip = null;
		this._hand = null;

	}

	getHandSpace() {

		if ( this._hand === null ) {

			this._hand = new Group();
			this._hand.matrixAutoUpdate = false;
			this._hand.visible = false;

			this._hand.joints = {};
			this._hand.inputState = { pinching: false };

		}

		return this._hand;

	}

	getTargetRaySpace() {

		if ( this._targetRay === null ) {

			this._targetRay = new Group();
			this._targetRay.matrixAutoUpdate = false;
			this._targetRay.visible = false;
			this._targetRay.hasLinearVelocity = false;
			this._targetRay.linearVelocity = new Vector3();
			this._targetRay.hasAngularVelocity = false;
			this._targetRay.angularVelocity = new Vector3();

		}

		return this._targetRay;

	}

	getGripSpace() {

		if ( this._grip === null ) {

			this._grip = new Group();
			this._grip.matrixAutoUpdate = false;
			this._grip.visible = false;
			this._grip.hasLinearVelocity = false;
			this._grip.linearVelocity = new Vector3();
			this._grip.hasAngularVelocity = false;
			this._grip.angularVelocity = new Vector3();

		}

		return this._grip;

	}

	dispatchEvent( event ) {

		if ( this._targetRay !== null ) {

			this._targetRay.dispatchEvent( event );

		}

		if ( this._grip !== null ) {

			this._grip.dispatchEvent( event );

		}

		if ( this._hand !== null ) {

			this._hand.dispatchEvent( event );

		}

		return this;

	}

	disconnect( inputSource ) {

		this.dispatchEvent( { type: 'disconnected', data: inputSource } );

		if ( this._targetRay !== null ) {

			this._targetRay.visible = false;

		}

		if ( this._grip !== null ) {

			this._grip.visible = false;

		}

		if ( this._hand !== null ) {

			this._hand.visible = false;

		}

		return this;

	}

	update( inputSource, frame, referenceSpace ) {

		let inputPose = null;
		let gripPose = null;
		let handPose = null;

		const targetRay = this._targetRay;
		const grip = this._grip;
		const hand = this._hand;

		if ( inputSource && frame.session.visibilityState !== 'visible-blurred' ) {

			if ( targetRay !== null ) {

				inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace );

				if ( inputPose !== null ) {

					targetRay.matrix.fromArray( inputPose.transform.matrix );
					targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale );

					if ( inputPose.linearVelocity !== null ) {

						targetRay.hasLinearVelocity = true;
						targetRay.linearVelocity.copy( inputPose.linearVelocity );

					} else {

						targetRay.hasLinearVelocity = false;

					}

					if ( inputPose.angularVelocity !== null ) {

						targetRay.hasAngularVelocity = true;
						targetRay.angularVelocity.copy( inputPose.angularVelocity );

					} else {

						targetRay.hasAngularVelocity = false;

					}

          this.dispatchEvent( _moveEvent );

				}

			}

			if ( hand && inputSource.hand ) {

				handPose = true;

				for ( const inputjoint of inputSource.hand.values() ) {

					// Update the joints groups with the XRJoint poses
					const jointPose = frame.getJointPose( inputjoint, referenceSpace );

					if ( hand.joints[ inputjoint.jointName ] === undefined ) {

						// The transform of this joint will be updated with the joint pose on each frame
						const joint = new Group();
						joint.matrixAutoUpdate = false;
						joint.visible = false;
						hand.joints[ inputjoint.jointName ] = joint;
						// ??
						hand.add( joint );

					}

					const joint = hand.joints[ inputjoint.jointName ];

					if ( jointPose !== null ) {

						joint.matrix.fromArray( jointPose.transform.matrix );
						joint.matrix.decompose( joint.position, joint.rotation, joint.scale );
						joint.jointRadius = jointPose.radius;

					}

					joint.visible = jointPose !== null;

				}

				// Custom events

				// Check pinchz
				const indexTip = hand.joints[ 'index-finger-tip' ];
				const thumbTip = hand.joints[ 'thumb-tip' ];
				const distance = indexTip.position.distanceTo( thumbTip.position );

				const distanceToPinch = 0.02;
				const threshold = 0.005;

				if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) {

					hand.inputState.pinching = false;
					this.dispatchEvent( {
						type: 'pinchend',
						handedness: inputSource.handedness,
						target: this
					} );

				} else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) {

					hand.inputState.pinching = true;
					this.dispatchEvent( {
						type: 'pinchstart',
						handedness: inputSource.handedness,
						target: this
					} );

				}

			} else {

				if ( grip !== null && inputSource.gripSpace ) {

					gripPose = frame.getPose( inputSource.gripSpace, referenceSpace );

					if ( gripPose !== null ) {

						grip.matrix.fromArray( gripPose.transform.matrix );
						grip.matrix.decompose( grip.position, grip.rotation, grip.scale );

						if ( gripPose.linearVelocity !== null ) {

							grip.hasLinearVelocity = true;
							grip.linearVelocity.copy( gripPose.linearVelocity );

						} else {

							grip.hasLinearVelocity = false;

						}

						if ( gripPose.angularVelocity !== null ) {

							grip.hasAngularVelocity = true;
							grip.angularVelocity.copy( gripPose.angularVelocity );

						} else {

							grip.hasAngularVelocity = false;

						}

					}

				}

			}

		}

		if ( targetRay !== null ) {

			targetRay.visible = ( inputPose !== null );

		}

		if ( grip !== null ) {

			grip.visible = ( gripPose !== null );

		}

		if ( hand !== null ) {

			hand.visible = ( handPose !== null );

		}

		return this;

	}

}

export { WebXRController };
<commit_msg>Clean up.<commit_after>import { Vector3 } from '../../math/Vector3.js';
import { Group } from '../../objects/Group.js';

const _moveEvent = { type: 'move' };

class WebXRController {

	constructor() {

		this._targetRay = null;
		this._grip = null;
		this._hand = null;

	}

	getHandSpace() {

		if ( this._hand === null ) {

			this._hand = new Group();
			this._hand.matrixAutoUpdate = false;
			this._hand.visible = false;

			this._hand.joints = {};
			this._hand.inputState = { pinching: false };

		}

		return this._hand;

	}

	getTargetRaySpace() {

		if ( this._targetRay === null ) {

			this._targetRay = new Group();
			this._targetRay.matrixAutoUpdate = false;
			this._targetRay.visible = false;
			this._targetRay.hasLinearVelocity = false;
			this._targetRay.linearVelocity = new Vector3();
			this._targetRay.hasAngularVelocity = false;
			this._targetRay.angularVelocity = new Vector3();

		}

		return this._targetRay;

	}

	getGripSpace() {

		if ( this._grip === null ) {

			this._grip = new Group();
			this._grip.matrixAutoUpdate = false;
			this._grip.visible = false;
			this._grip.hasLinearVelocity = false;
			this._grip.linearVelocity = new Vector3();
			this._grip.hasAngularVelocity = false;
			this._grip.angularVelocity = new Vector3();

		}

		return this._grip;

	}

	dispatchEvent( event ) {

		if ( this._targetRay !== null ) {

			this._targetRay.dispatchEvent( event );

		}

		if ( this._grip !== null ) {

			this._grip.dispatchEvent( event );

		}

		if ( this._hand !== null ) {

			this._hand.dispatchEvent( event );

		}

		return this;

	}

	disconnect( inputSource ) {

		this.dispatchEvent( { type: 'disconnected', data: inputSource } );

		if ( this._targetRay !== null ) {

			this._targetRay.visible = false;

		}

		if ( this._grip !== null ) {

			this._grip.visible = false;

		}

		if ( this._hand !== null ) {

			this._hand.visible = false;

		}

		return this;

	}

	update( inputSource, frame, referenceSpace ) {

		let inputPose = null;
		let gripPose = null;
		let handPose = null;

		const targetRay = this._targetRay;
		const grip = this._grip;
		const hand = this._hand;

		if ( inputSource && frame.session.visibilityState !== 'visible-blurred' ) {

			if ( targetRay !== null ) {

				inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace );

				if ( inputPose !== null ) {

					targetRay.matrix.fromArray( inputPose.transform.matrix );
					targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale );

					if ( inputPose.linearVelocity !== null ) {

						targetRay.hasLinearVelocity = true;
						targetRay.linearVelocity.copy( inputPose.linearVelocity );

					} else {

						targetRay.hasLinearVelocity = false;

					}

					if ( inputPose.angularVelocity !== null ) {

						targetRay.hasAngularVelocity = true;
						targetRay.angularVelocity.copy( inputPose.angularVelocity );

					} else {

						targetRay.hasAngularVelocity = false;

					}

					this.dispatchEvent( _moveEvent );

				}

			}

			if ( hand && inputSource.hand ) {

				handPose = true;

				for ( const inputjoint of inputSource.hand.values() ) {

					// Update the joints groups with the XRJoint poses
					const jointPose = frame.getJointPose( inputjoint, referenceSpace );

					if ( hand.joints[ inputjoint.jointName ] === undefined ) {

						// The transform of this joint will be updated with the joint pose on each frame
						const joint = new Group();
						joint.matrixAutoUpdate = false;
						joint.visible = false;
						hand.joints[ inputjoint.jointName ] = joint;
						// ??
						hand.add( joint );

					}

					const joint = hand.joints[ inputjoint.jointName ];

					if ( jointPose !== null ) {

						joint.matrix.fromArray( jointPose.transform.matrix );
						joint.matrix.decompose( joint.position, joint.rotation, joint.scale );
						joint.jointRadius = jointPose.radius;

					}

					joint.visible = jointPose !== null;

				}

				// Custom events

				// Check pinchz
				const indexTip = hand.joints[ 'index-finger-tip' ];
				const thumbTip = hand.joints[ 'thumb-tip' ];
				const distance = indexTip.position.distanceTo( thumbTip.position );

				const distanceToPinch = 0.02;
				const threshold = 0.005;

				if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) {

					hand.inputState.pinching = false;
					this.dispatchEvent( {
						type: 'pinchend',
						handedness: inputSource.handedness,
						target: this
					} );

				} else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) {

					hand.inputState.pinching = true;
					this.dispatchEvent( {
						type: 'pinchstart',
						handedness: inputSource.handedness,
						target: this
					} );

				}

			} else {

				if ( grip !== null && inputSource.gripSpace ) {

					gripPose = frame.getPose( inputSource.gripSpace, referenceSpace );

					if ( gripPose !== null ) {

						grip.matrix.fromArray( gripPose.transform.matrix );
						grip.matrix.decompose( grip.position, grip.rotation, grip.scale );

						if ( gripPose.linearVelocity !== null ) {

							grip.hasLinearVelocity = true;
							grip.linearVelocity.copy( gripPose.linearVelocity );

						} else {

							grip.hasLinearVelocity = false;

						}

						if ( gripPose.angularVelocity !== null ) {

							grip.hasAngularVelocity = true;
							grip.angularVelocity.copy( gripPose.angularVelocity );

						} else {

							grip.hasAngularVelocity = false;

						}

					}

				}

			}

		}

		if ( targetRay !== null ) {

			targetRay.visible = ( inputPose !== null );

		}

		if ( grip !== null ) {

			grip.visible = ( gripPose !== null );

		}

		if ( hand !== null ) {

			hand.visible = ( handPose !== null );

		}

		return this;

	}

}

export { WebXRController };
<|endoftext|>


<commit_before>/*
    {
        name: 'myinlines',
        type: 'inlines',
        list_display: ['position'],
        form: {
            name: 'myform',
            visitors: ['helptext_visitor'],
            fields: [
                {
                    name: 'Position',
                    type: 'integer'
                },
                {
                    name: 'Description',
                    type: 'textarea'
                },
                {
                    name: 'Price',
                    type: 'float'
                }
            ]
        }
    }
*/

schnipp.dynforms.fields.inlines = function(field_descriptor, field_data, parent_dynform) {
    var self = schnipp.dynforms.abstract_field(field_descriptor, field_data)

    self.form = null
    self.change_form = null

    self.objects = schnipp.models.observable_list()
    self.templates.holder = '\

\
             Hinzufügen\

\

\
    '
    self.templates.action_td = '\
        \
            \
            \
        	\
    '

    self.get_inline_schema = function() {
        return field_descriptor.form
    }

    self.init_forms = function() {

        self.form = schnipp.dynforms.form(self.get_inline_schema(), {}, parent_dynform.fieldtypes)
        self.change_form = schnipp.dynforms.form(self.get_inline_schema(), {}, parent_dynform.fieldtypes)

        /**
        * Preprocess list_display.
        */
        self.change_list_fields = []

        if (self.field_descriptor.list_display) {
           $.each(self.form.schema.fields, function(index, field) {
                if (self.field_descriptor.list_display.indexOf(field.name) != -1)
                    self.change_list_fields.push(field)
            })
        } else {
            self.change_list_fields = self.form.schema.fields
        }
    }

    var super_initialize = self.initialize
    self.initialize = function() {
        super_initialize()
        var tbody = self.dom.changelist_table.find('tbody')
        // handle insert
        self.objects.events.bind('insert', function(args) {
            tbody.append(self.render_row(args.element))
            self.dom.changelist_table.sortable().find('tbody').sortable('refresh')
        })
        // handle remove
        self.objects.events.bind('remove', function(args) {
            $(tbody.children()[args.index]).remove()
        })
        // make rows sortable
        self.make_sortable()
        // set initial data.
        $.each(self.get_initial_data(), function(i, obj) {
            self.objects.append(obj)
        })
    }

    /**
    *   Render object row with change buttons.
    */
    self.render_row = function(obj) {
        var tr = $('

')
        var tds = {}

        $.each(self.change_list_fields, function(i, field) {
            var td = $('	').text(obj.get(field.name))
            tds[field.name] = td
            tr.append(td)
        })

        var td = $(self.templates.action_td)
        var edit = td.find('.schnippforms-inlines-edit')
        var del = td.find('.schnippforms-inlines-delete')
        tr.append(td)

        tr.data('obj', obj)

        edit.click(function() {
            var d = schnipp.ui.Dialog().init()
            d.set_title('Element bearbeiten')
            d.set_content(self.render_change_form(d, obj, tds))
            d.show()
            return false
        })

        del.click(function() {
            var doit = confirm('Element wirklich löschen?')
            if (doit)
                self.objects.remove($(this).closest('tr').prevAll().length)
            return false
        })
        return tr
    }

    /**
    *   Main visualization of the field. Handle add button;
    */
    self.render_input = function() {
        self.init_forms()

        var holder = $(self.templates.holder)
        var a = holder.find('a.schnippforms-inline-add')
        var changelist = holder.find('.schnippforms-inline-objects')
        self.dom.changelist_table = self.render_changelist()
        changelist.append(self.dom.changelist_table)

        a.click(function() {
            var d = schnipp.ui.Dialog().init()

            if (self.field_descriptor.dialog_title)
                d.set_title(self.field_descriptor.dialog_title)
            else
                d.set_title('Element hinzufügen')

            var dialog_content = self.render_add_form(d)
            d.set_content(dialog_content)
            d.show()
            return false
        })

        return holder
    }

    /**
    *   Render edit form.
    */
    self.render_change_form = function(d, obj, tds) {
        var content = $('

')
        var submit = $('
<button type="submit"> übernehmen</button>
')
        content.append(self.change_form.render())

        self.change_form.initialize()
        self.change_form.set_data(obj.raw_data)

        content.find('form').append($('

'))

        var f =  self.change_form.dom.main
        f.append(submit)

        f.submit(function() {
            if (self.change_form.is_valid()) {
                var data = self.change_form.get_data()
                for (key in data) {
                    if (tds[key])
                        tds[key].text(data[key])
                    obj.set(key, data[key])
                }
                d.close()
            }
            return false
        })

        return content
    }

    /**
    *   Render add form.
    */
    self.render_add_form = function(d) {
        var content = $('

')
        var submit = $('
<button type="submit"> anlegen</button>
')
        content.append(self.form.render())
        self.form.initialize()

        content.find('form').append($('

'))

        var f =  self.form.dom.main
        f.append(submit)

        f.submit(function() {
            if (self.form.is_valid()) {
                self.objects.append(self.form.get_data())
                for (var i=0; i<self.form.fields.length; i++) {
                    var field = self.form.fields[i]
                    field.clear()
                }
                d.close()
            }
            return false
        })

        return content
    }

    /**
    *   Render empty the changelist.
    */
    self.render_changelist = function() {
        var table = $('

')
        var thead = table.find('thead')
        var tr = $('

')

        $.each(self.change_list_fields, function(i, field) {
            th = $('	').text(field.label)
            if (i == self.form.schema.fields.length - 1)
                th.attr('colspan', '2')
            if (i == 0)
                th.attr('colspan', '2')
            tr.append(th)
        })
        thead.append(tr)
        return table
    }

    /**
    *   Apply sortable functionality on table rows.
    */
    self.make_sortable = function() {
        var tbody = self.dom.changelist_table.find('tbody')
        tbody.sortable({
            distance: 10,
            helper: function(e, ui) {
	            ui.children().each(function() {
		            $(this).width($(this).width())
	            })
	            return ui
            },
            stop: function() {
                self.objects.clear()
                tbody.children().each(function(i, elem) {
                    self.objects.data.push($(elem).data('obj'))
                })
            }
        }).disableSelection()
    }

    self.get_data = function() {
        return self.objects.get_data()
    }

    self._set = function(objects) {
        if (objects)
            for (var i=0; i<objects.length; i++) {
                var obj = objects[i]
                self.objects.append(obj)
            }
    }

    return self
}

<commit_msg>inlines: ws and indentation<commit_after>/*
    {
        name: 'myinlines',
        type: 'inlines',
        list_display: ['position'],
        form: {
            name: 'myform',
            visitors: ['helptext_visitor'],
            fields: [
                {
                    name: 'Position',
                    type: 'integer'
                },
                {
                    name: 'Description',
                    type: 'textarea'
                },
                {
                    name: 'Price',
                    type: 'float'
                }
            ]
        }
    }
*/

schnipp.dynforms.fields.inlines = function(field_descriptor, field_data, parent_dynform) {
    var self = schnipp.dynforms.abstract_field(field_descriptor, field_data)

    self.form = null
    self.change_form = null

    self.objects = schnipp.models.observable_list()
    self.templates.holder = '\

\
             Hinzufügen\

\

\
    '
    self.templates.action_td = '\
        \
            \
            \
        	\
    '

    self.get_inline_schema = function() {
        return field_descriptor.form
    }

    self.init_forms = function() {

        self.form = schnipp.dynforms.form(self.get_inline_schema(), {}, parent_dynform.fieldtypes)
        self.change_form = schnipp.dynforms.form(self.get_inline_schema(), {}, parent_dynform.fieldtypes)

        /**
        * Preprocess list_display.
        */
        self.change_list_fields = []

        if (self.field_descriptor.list_display) {
           $.each(self.form.schema.fields, function(index, field) {
                if (self.field_descriptor.list_display.indexOf(field.name) != -1)
                    self.change_list_fields.push(field)
            })
        } else {
            self.change_list_fields = self.form.schema.fields
        }
    }

    var super_initialize = self.initialize
    self.initialize = function() {
        super_initialize()
        var tbody = self.dom.changelist_table.find('tbody')
        // handle insert
        self.objects.events.bind('insert', function(args) {
            tbody.append(self.render_row(args.element))
            self.dom.changelist_table.sortable().find('tbody').sortable('refresh')
        })
        // handle remove
        self.objects.events.bind('remove', function(args) {
            $(tbody.children()[args.index]).remove()
        })
        // make rows sortable
        self.make_sortable()
        // set initial data.
        $.each(self.get_initial_data(), function(i, obj) {
            self.objects.append(obj)
        })
    }

    /**
    *   Render object row with change buttons.
    */
    self.render_row = function(obj) {
        var tr = $('

')
        var tds = {}

        $.each(self.change_list_fields, function(i, field) {
            var td = $('	').text(obj.get(field.name))
            tds[field.name] = td
            tr.append(td)
        })

        var td = $(self.templates.action_td)
        var edit = td.find('.schnippforms-inlines-edit')
        var del = td.find('.schnippforms-inlines-delete')
        tr.append(td)

        tr.data('obj', obj)

        edit.click(function() {
            var d = schnipp.ui.Dialog().init()
            d.set_title('Element bearbeiten')
            d.set_content(self.render_change_form(d, obj, tds))
            d.show()
            return false
        })

        del.click(function() {
            var doit = confirm('Element wirklich löschen?')
            if (doit)
                self.objects.remove($(this).closest('tr').prevAll().length)
            return false
        })
        return tr
    }

    /**
    *   Main visualization of the field. Handle add button;
    */
    self.render_input = function() {
        self.init_forms()

        var holder = $(self.templates.holder)
        var a = holder.find('a.schnippforms-inline-add')
        var changelist = holder.find('.schnippforms-inline-objects')
        self.dom.changelist_table = self.render_changelist()
        changelist.append(self.dom.changelist_table)

        a.click(function() {
            var d = schnipp.ui.Dialog().init()

            if (self.field_descriptor.dialog_title)
                d.set_title(self.field_descriptor.dialog_title)
            else
                d.set_title('Element hinzufügen')

            var dialog_content = self.render_add_form(d)
            d.set_content(dialog_content)
            d.show()
            return false
        })

        return holder
    }

    /**
    *   Render edit form.
    */
    self.render_change_form = function(d, obj, tds) {
        var content = $('

')
        var submit = $('
<button type="submit"> übernehmen</button>
')
        content.append(self.change_form.render())

        self.change_form.initialize()
        self.change_form.set_data(obj.raw_data)

        content.find('form').append($('

'))

        var f =  self.change_form.dom.main
        f.append(submit)

        f.submit(function() {
            if (self.change_form.is_valid()) {
                var data = self.change_form.get_data()
                for (key in data) {
                    if (tds[key])
                        tds[key].text(data[key])
                    obj.set(key, data[key])
                }
                d.close()
            }
            return false
        })

        return content
    }

    /**
    *   Render add form.
    */
    self.render_add_form = function(d) {
        var content = $('

')
        var submit = $('
<button type="submit"> anlegen</button>
')
        content.append(self.form.render())
        self.form.initialize()

        content.find('form').append($('

'))

        var f =  self.form.dom.main
        f.append(submit)

        f.submit(function() {
            if (self.form.is_valid()) {
                self.objects.append(self.form.get_data())
                for (var i=0; i<self.form.fields.length; i++) {
                    var field = self.form.fields[i]
                    field.clear()
                }
                d.close()
            }
            return false
        })

        return content
    }

    /**
    *   Render empty the changelist.
    */
    self.render_changelist = function() {
        var table = $('

')
        var thead = table.find('thead')
        var tr = $('

')

        $.each(self.change_list_fields, function(i, field) {
            th = $('	').text(field.label)
            if (i == self.form.schema.fields.length - 1)
                th.attr('colspan', '2')
            if (i == 0)
                th.attr('colspan', '2')
            tr.append(th)
        })
        thead.append(tr)
        return table
    }

    /**
    *   Apply sortable functionality on table rows.
    */
    self.make_sortable = function() {
        var tbody = self.dom.changelist_table.find('tbody')
        tbody.sortable({
            distance: 10,
            helper: function(e, ui) {
                ui.children().each(function() {
                    $(this).width($(this).width())
                })
                return ui
            },
            stop: function() {
                self.objects.clear()
                tbody.children().each(function(i, elem) {
                    self.objects.data.push($(elem).data('obj'))
                })
            }
        }).disableSelection()
    }

    self.get_data = function() {
        return self.objects.get_data()
    }

    self._set = function(objects) {
        if (objects)
            for (var i=0; i<objects.length; i++) {
                var obj = objects[i]
                self.objects.append(obj)
            }
    }

    return self
}
<|endoftext|>


<commit_before>/*
    {
        name: 'myinlines',
        type: 'inlines',
        list_display: ['position'],
        form: {
            name: 'myform',
            visitors: ['helptext_visitor'],
            fields: [
                {
                    name: 'Position',
                    type: 'integer'
                },
                {
                    name: 'Description',
                    type: 'textarea'
                },
                {
                    name: 'Price',
                    type: 'float'
                }
            ]
        }
    }
*/

schnipp.dynforms.fields.inlines = function(field_descriptor, field_data, parent_dynform) {
    var self = schnipp.dynforms.abstract_field(field_descriptor, field_data)
    self.form = schnipp.dynforms.form(field_descriptor.form, {}, parent_dynform.fieldtypes)
    self.change_form = schnipp.dynforms.form(field_descriptor.form, {}, parent_dynform.fieldtypes)
    self.objects = schnipp.models.observable_list()
    self.templates.holder = '\

\
             Hinzufügen\

\

\
    '
    self.templates.action_td = '\
        \
            \
            \
        	\
    '

    /**
    * Preprocess list_display.
    */
    self.change_list_fields = []

    if (self.field_descriptor.list_display) {
       $.each(self.form.schema.fields, function(index, field) {
            if (self.field_descriptor.list_display.indexOf(field.name) != -1)
                self.change_list_fields.push(field)
        })
    } else {
        self.change_list_fields = self.form.schema.fields
    }

    var super_initialize = self.initialize
    self.initialize = function() {
        super_initialize()
        var tbody = self.dom.changelist_table.find('tbody')
        // handle insert
        self.objects.events.bind('insert', function(args) {
            tbody.append(self.render_row(args.element))
            self.dom.changelist_table.sortable().find('tbody').sortable('refresh')
        })
        // handle remove
        self.objects.events.bind('remove', function(args) {
            $(tbody.children()[args.index]).remove()
        })
        // make rows sortable
        self.make_sortable()
        // set initial data.
        $.each(self.get_initial_data(), function(i, obj) {
            self.objects.append(obj)
        })
    }

    /**
    *   Render object row with change buttons.
    */
    self.render_row = function(obj) {
        var tr = $('

')
        var tds = {}

        $.each(self.change_list_fields, function(i, field) {
            var td = $('	').text(obj.get(field.name))
            tds[field.name] = td
            tr.append(td)
        })

        var td = $(self.templates.action_td)
        var edit = td.find('.schnippforms-inlines-edit')
        var del = td.find('.schnippforms-inlines-delete')
        tr.append(td)

        // this is hacky but necessary to enable data change on row sort.
        tr.data('obj', obj)

        edit.click(function() {
            var d = schnipp.ui.Dialog().init()
            d.set_title('Element bearbeiten')
            d.set_content(self.change_form.render())
            self.change_form.set_data(obj.raw_data)
            self.change_form.initialize()
            var f = d.dom.main.find('form')
            f.append($('<input type="submit" value="Übernehmen"/>'))
            f.submit(function() {
                if (self.change_form.is_valid()) {
                    var data = self.change_form.get_data()
                    for (key in data) {
                        tds[key].text(data[key])
                        obj.set(key, data[key])
                    }
                    d.close()
                }
                return false
            })
            d.show()
            return false
        })

        del.click(function() {
            self.objects.remove($(this).closest('tr').prevAll().length)
            return false
        })
        return tr
    }

    /**
    *   Main visualization of the field. Handle add button;
    */
    self.render_input = function() {
        var holder = $(self.templates.holder)
        var a = holder.find('a.schnippforms-inline-add')
        var changelist = holder.find('.schnippforms-inline-objects')
        self.dom.changelist_table = self.render_changelist()
        changelist.append(self.dom.changelist_table)

        a.click(function() {
            var d = schnipp.ui.Dialog().init()

            if (self.field_descriptor.dialog_title)
                d.set_title(self.field_descriptor.dialog_title)
            else
                d.set_title('Element hinzufügen')

            var dialog_content = self.render_add_form(d)
            d.set_content(dialog_content)
            d.show()
            return false
        })

        return holder
    }

    /**
    *   Render add form.
    */
    self.render_add_form = function(d) {
        var content = $('

')
        var submit = $('
<button type="submit"> anlegen</button>
')
        content.append(self.form.render())
        self.form.initialize()

        var f =  content.find('form')
        f.append(submit)

        f.submit(function() {
            if (self.form.is_valid()) {
                self.objects.append(self.form.get_data())
                for (var i=0; i<self.form.fields.length; i++) {
                    var field = self.form.fields[i]
                    field.clear()
                }
                d.close()
            }
            return false
        })

        return content
    }

    /**
    *   Render empty the changelist.
    */
    self.render_changelist = function() {
        var table = $('

')
        var thead = table.find('thead')
        var tr = $('

')

        $.each(self.change_list_fields, function(i, field) {
            th = $('	').text(field.label)
            if (i == self.form.schema.fields.length - 1)
                th.attr('colspan', '2')
            if (i == 0)
                th.attr('colspan', '2')
            tr.append(th)
        })
        thead.append(tr)
        return table
    }

    /**
    *   Apply sortable functionality on table rows.
    */
    self.make_sortable = function() {
        var tbody = self.dom.changelist_table.find('tbody')
        tbody.sortable({
            distance: 10,
            helper: function(e, ui) {
	            ui.children().each(function() {
		            $(this).width($(this).width())
	            })
	            return ui
            },
            stop: function() {
                self.objects.clear()
                tbody.children().each(function(i, elem) {
                    self.objects.data.push($(elem).data('obj'))
                })
            }
        }).disableSelection()
    }

    self.get_data = function() {
        return self.objects.get_data()
    }

    self._set = function(objects) {
        if (objects)
            for (var i=0; i<objects.length; i++) {
                var obj = objects[i]
                self.objects.append(obj)
            }
    }

    return self
}

<commit_msg>fixed bug related to list_display feature and update of changelist rows<commit_after>/*
    {
        name: 'myinlines',
        type: 'inlines',
        list_display: ['position'],
        form: {
            name: 'myform',
            visitors: ['helptext_visitor'],
            fields: [
                {
                    name: 'Position',
                    type: 'integer'
                },
                {
                    name: 'Description',
                    type: 'textarea'
                },
                {
                    name: 'Price',
                    type: 'float'
                }
            ]
        }
    }
*/

schnipp.dynforms.fields.inlines = function(field_descriptor, field_data, parent_dynform) {
    var self = schnipp.dynforms.abstract_field(field_descriptor, field_data)
    self.form = schnipp.dynforms.form(field_descriptor.form, {}, parent_dynform.fieldtypes)
    self.change_form = schnipp.dynforms.form(field_descriptor.form, {}, parent_dynform.fieldtypes)
    self.objects = schnipp.models.observable_list()
    self.templates.holder = '\

\
             Hinzufügen\

\

\
    '
    self.templates.action_td = '\
        \
            \
            \
        	\
    '

    /**
    * Preprocess list_display.
    */
    self.change_list_fields = []

    if (self.field_descriptor.list_display) {
       $.each(self.form.schema.fields, function(index, field) {
            if (self.field_descriptor.list_display.indexOf(field.name) != -1)
                self.change_list_fields.push(field)
        })
    } else {
        self.change_list_fields = self.form.schema.fields
    }

    var super_initialize = self.initialize
    self.initialize = function() {
        super_initialize()
        var tbody = self.dom.changelist_table.find('tbody')
        // handle insert
        self.objects.events.bind('insert', function(args) {
            tbody.append(self.render_row(args.element))
            self.dom.changelist_table.sortable().find('tbody').sortable('refresh')
        })
        // handle remove
        self.objects.events.bind('remove', function(args) {
            $(tbody.children()[args.index]).remove()
        })
        // make rows sortable
        self.make_sortable()
        // set initial data.
        $.each(self.get_initial_data(), function(i, obj) {
            self.objects.append(obj)
        })
    }

    /**
    *   Render object row with change buttons.
    */
    self.render_row = function(obj) {
        var tr = $('

')
        var tds = {}

        $.each(self.change_list_fields, function(i, field) {
            var td = $('	').text(obj.get(field.name))
            tds[field.name] = td
            tr.append(td)
        })

        var td = $(self.templates.action_td)
        var edit = td.find('.schnippforms-inlines-edit')
        var del = td.find('.schnippforms-inlines-delete')
        tr.append(td)

        // this is hacky but necessary to enable data change on row sort.
        tr.data('obj', obj)

        edit.click(function() {
            var d = schnipp.ui.Dialog().init()
            d.set_title('Element bearbeiten')
            d.set_content(self.change_form.render())
            self.change_form.set_data(obj.raw_data)
            self.change_form.initialize()
            var f = d.dom.main.find('form')
            f.append($('<input type="submit" value="Übernehmen"/>'))
            f.submit(function() {
                if (self.change_form.is_valid()) {
                    var data = self.change_form.get_data()
                    for (key in data) {
                        if (tds[key])
                            tds[key].text(data[key])
                        obj.set(key, data[key])
                    }
                    d.close()
                }
                return false
            })
            d.show()
            return false
        })

        del.click(function() {
            self.objects.remove($(this).closest('tr').prevAll().length)
            return false
        })
        return tr
    }

    /**
    *   Main visualization of the field. Handle add button;
    */
    self.render_input = function() {
        var holder = $(self.templates.holder)
        var a = holder.find('a.schnippforms-inline-add')
        var changelist = holder.find('.schnippforms-inline-objects')
        self.dom.changelist_table = self.render_changelist()
        changelist.append(self.dom.changelist_table)

        a.click(function() {
            var d = schnipp.ui.Dialog().init()

            if (self.field_descriptor.dialog_title)
                d.set_title(self.field_descriptor.dialog_title)
            else
                d.set_title('Element hinzufügen')

            var dialog_content = self.render_add_form(d)
            d.set_content(dialog_content)
            d.show()
            return false
        })

        return holder
    }

    /**
    *   Render add form.
    */
    self.render_add_form = function(d) {
        var content = $('

')
        var submit = $('
<button type="submit"> anlegen</button>
')
        content.append(self.form.render())
        self.form.initialize()

        var f =  content.find('form')
        f.append(submit)

        f.submit(function() {
            if (self.form.is_valid()) {
                self.objects.append(self.form.get_data())
                for (var i=0; i<self.form.fields.length; i++) {
                    var field = self.form.fields[i]
                    field.clear()
                }
                d.close()
            }
            return false
        })

        return content
    }

    /**
    *   Render empty the changelist.
    */
    self.render_changelist = function() {
        var table = $('

')
        var thead = table.find('thead')
        var tr = $('

')

        $.each(self.change_list_fields, function(i, field) {
            th = $('	').text(field.label)
            if (i == self.form.schema.fields.length - 1)
                th.attr('colspan', '2')
            if (i == 0)
                th.attr('colspan', '2')
            tr.append(th)
        })
        thead.append(tr)
        return table
    }

    /**
    *   Apply sortable functionality on table rows.
    */
    self.make_sortable = function() {
        var tbody = self.dom.changelist_table.find('tbody')
        tbody.sortable({
            distance: 10,
            helper: function(e, ui) {
	            ui.children().each(function() {
		            $(this).width($(this).width())
	            })
	            return ui
            },
            stop: function() {
                self.objects.clear()
                tbody.children().each(function(i, elem) {
                    self.objects.data.push($(elem).data('obj'))
                })
            }
        }).disableSelection()
    }

    self.get_data = function() {
        return self.objects.get_data()
    }

    self._set = function(objects) {
        if (objects)
            for (var i=0; i<objects.length; i++) {
                var obj = objects[i]
                self.objects.append(obj)
            }
    }

    return self
}

<|endoftext|>


<commit_before>const StoreInitialState = {
    login: {
        isAuthenticated: false,
        isAttemptingLogin: false,
        message: "",
        type: ""
    },

    lastAction: {
        id: -1,
        type: "",
        data: []
    },

    file: {
        selected: []
    }
};

const AppInitialState = {
    hostname: "",
    port    : "",
    username: "",
    password: ""
};

const LoginInitialState = {
    opacity: 1,
    shadow: "4px 4px 20px -1px rgba(0,0,0,0.25)"
};

export {
    StoreInitialState,
    AppInitialState,
    LoginInitialState
};
<commit_msg>Updated selected state from array to obj<commit_after>const StoreInitialState = {
    login: {
        isAuthenticated: false,
        isAttemptingLogin: false,
        message: "",
        type: ""
    },

    lastAction: {
        id: -1,
        type: "",
        data: []
    },

    file: {
        selected: {}
    }
};

const AppInitialState = {
    hostname: "",
    port    : "",
    username: "",
    password: ""
};

const LoginInitialState = {
    opacity: 1,
    shadow: "4px 4px 20px -1px rgba(0,0,0,0.25)"
};

export {
    StoreInitialState,
    AppInitialState,
    LoginInitialState
};
<|endoftext|>


<commit_before>/* jslint node: true, esnext: true */

"use strict";

const child_process = require('child_process');

module.exports = {
	"name": "kronos-system",
	"description": "Starts a child process",
	"config": {
		"command": {
			"description": "command to execute",
			"type": "string"
		}
	},
	"endpoints": {
		"action": {
			"direction": "in(active,passive)"
		},
		"stdin": {
			"direction": "in(active)",
			"mandatory": false
		},
		"stdout": {
			"direction": "out(active)",
			"mandatory": false
		},
		"stderr": {
			"direction": "out(active)",
			"mandatory": false
		}
	},
	initialize(manager, sr, stepDefinition, endpoints, properties) {
		properties._start = {
			value: function () {
				const step = this;

				let command = step.command;
				let argumens = [];
				let stdinRequest;
				let child;
				let options = {};

				if (step.env) {
					options.env = step.env;
				}
				if (step.arguments) {
					arguments = step.arguments;
				}

				endpoints.action.receive(function* () {
					while (step.isRunning) {
						const request = yield;

						options.stdio = [endpoints.stdin ? 'pipe' : 'ignore',
							endpoints.stdout ? 'pipe' : 'ignore',
							endpoints.stderr ? 'pipe' : 'ignore'
						];

						child = child_process.spawn(command, arguments, options);

						if (endpoints.stdin) {
							endpoints.stdin.receive(function* () {
								stdinRequest = yield;
								stdinRequest.stream.pipe(child.stdin);
							});
						}

						if (endpoints.stdout) {
							endpoints.stdout.send({
								info: {
									command: command
								},
								stream: child.stdout
							});
						}

						if (endpoints.stderr) {
							endpoints.stderr.send({
								info: {
									command: command
								},
								stream: child.stderr
							});
						}
					}
				});

				return Promise.resolve(step);
			}
		};

		properties._stop = {
			value: function () {
				if (child) {
					if (stdinRequest) {
						stdinRequest.stream.unpipe(child.stdin);
						stdinRequest = undefined;
					}

					child.kill();
					child = undefined;
				}

				return Promise.resolve(this);
			}
		};

		return this;
	}
};
<commit_msg>fix: do not use predefined 'arguments'<commit_after>/* jslint node: true, esnext: true */

"use strict";

const child_process = require('child_process');

module.exports = {
	"name": "kronos-system",
	"description": "Starts a child process",
	"config": {
		"command": {
			"description": "command to execute",
			"type": "string"
		}
	},
	"endpoints": {
		"action": {
			"direction": "in(active,passive)"
		},
		"stdin": {
			"direction": "in(active)",
			"mandatory": false
		},
		"stdout": {
			"direction": "out(active)",
			"mandatory": false
		},
		"stderr": {
			"direction": "out(active)",
			"mandatory": false
		}
	},
	initialize(manager, sr, stepDefinition, endpoints, properties) {

		properties._start = {
			value: function () {
				const step = this;

				let command = stepDefinition.command;
				let args = [];
				let stdinRequest;
				let child;
				let options = {};

				if (stepDefinition.env) {
					options.env = stepDefinition.env;
				}

				if (stepDefinition.arguments) {
					args = stepDefinition.arguments;
				}

				endpoints.action.receive(function* () {
					while (step.isRunning) {
						const request = yield;

						options.stdio = [endpoints.stdin ? 'pipe' : 'ignore',
							endpoints.stdout ? 'pipe' : 'ignore',
							endpoints.stderr ? 'pipe' : 'ignore'
						];

						child = child_process.spawn(command, args, options);

						if (endpoints.stdin) {
							endpoints.stdin.receive(function* () {
								stdinRequest = yield;
								stdinRequest.stream.pipe(child.stdin);
							});
						}

						if (endpoints.stdout) {
							endpoints.stdout.send({
								info: {
									command: command
								},
								stream: child.stdout
							});
						}

						if (endpoints.stderr) {
							endpoints.stderr.send({
								info: {
									command: command
								},
								stream: child.stderr
							});
						}
					}
				});

				return Promise.resolve(step);
			}
		};
		properties._stop = {
			value: function () {
				if (child) {
					if (stdinRequest) {
						stdinRequest.stream.unpipe(child.stdin);
						stdinRequest = undefined;
					}

					child.kill();
					child = undefined;
				}

				return Promise.resolve(this);
			}
		};

		return this;
	}
};
<|endoftext|>


<commit_before>var chai = require('chai'),
    should = chai.should(),
    sinon = require('sinon'),
    sinon_chai = require('sinon-chai'),
    _ = require('underscore'),
    nock = require('nock');

chai.use(sinon_chai);

var User = require('../models/user'),
    Service = require('../models/service'),
    Message = require('../models/message');

var Deliver = require('../deliver');

describe('Deliver', function () {

  describe('#send', function () {

    var deliver;

    var findUserStub = null;
    var findServiceStub = null;
    var createMessageStub = null;

    var scope = null;

    before(function () {
      deliver = new Deliver;

      scope = nock('http://llun.in.th')
        .post('/post')
        .reply(200, 'Hello, World');

      findUserStub = sinon.stub(User, 'findOne');
      findUserStub.withArgs({ username: 'user1' }).callsArgWith(1, { username: 'user1', email: 'user1@gmail.com' });
      findUserStub.withArgs({ username: 'user2' }).callsArgWith(1, { username: 'user2', email: 'user2@gmail.com' });
      findUserStub.callsArg(1);

      findServiceStub = sinon.stub(Service, 'findOne');
      findServiceStub.withArgs({ name: 'service1' }).callsArgWith(1, { _id: 's1', name: 'service1', target: 'http://llun.in.th/post#1', authentication: 'none' });
      findServiceStub.withArgs({ name: 'service2' }).callsArgWith(1, { _id: 's2', name: 'service2', target: 'http://llun.in.th/post#2', authentication: 'none' });
      findServiceStub.callsArg(1);

      createMessageStub = sinon.stub(Message, 'create', function (message, cb) {
        var cloneMessage = _.clone(message);
        cloneMessage._id = 'message1';

        cb(null, _.clone(cloneMessage));
      });

    });

    after(function () {
      findUserStub.restore();
      findServiceStub.restore();

      nock.restore();
    });

    it ('should send request to both service', function (done) {

      deliver.send(__dirname + '/sample.mail', 'someone@mail.com', [ 'user1+service1@mailpipe.me', 'user2+service1@mailpipe.me' ],
        function (err, messages) {
          should.exist(messages);
          message.should.have.length(2);

          _.each(messages, function (message) {
            message.status.should.equal(Message.STATUS.SENT);
            message.from.should.equal('someone@mail.com');
          });

          message[0].to.should.equal('s1');
          message[1].to.should.equal('s2');

          done();
        });
    });

  });

});<commit_msg>Added more spec for deliver.<commit_after>var chai = require('chai'),
    should = chai.should(),
    sinon = require('sinon'),
    sinon_chai = require('sinon-chai'),
    _ = require('underscore'),
    nock = require('nock');

chai.use(sinon_chai);

var User = require('../models/user'),
    Service = require('../models/service'),
    Message = require('../models/message');

var Deliver = require('../deliver');

describe('Deliver', function () {

  describe('#send', function () {

    var deliver;

    var findUserStub = null;
    var findServiceStub = null;
    var createMessageStub = null;

    var scope = null;

    before(function () {
      deliver = new Deliver;

      scope = nock('http://llun.in.th')
        .post('/post')
        .reply(200, '{ success: true }')
        .post('/action')
        .reply(404, 'not found');

      findUserStub = sinon.stub(User, 'findOne');
      findUserStub.withArgs({ username: 'user1' }).callsArgWith(1, { _id: 'u1', username: 'user1', email: 'user1@gmail.com' });
      findUserStub.withArgs({ username: 'user2' }).callsArgWith(1, { _id: 'u2', username: 'user2', email: 'user2@gmail.com' });
      findUserStub.callsArg(1);

      findServiceStub = sinon.stub(Service, 'findOne');
      findServiceStub.withArgs({ name: 'service1', user: 'u1' }).callsArgWith(1, { _id: 's1', name: 'service1', user: 'u1', target: 'http://llun.in.th/post#1', authentication: 'none' });
      findServiceStub.withArgs({ name: 'service2', user: 'u1' }).callsArgWith(1, { _id: 's2', name: 'service2', user: 'u1', target: 'http://llun.in.th/post#2', authentication: 'none' });
      findServiceStub.withArgs({ name: 'service1', user: 'u2' }).callsArgWith(1, { _id: 's3', name: 'service1', user: 'u2', target: 'http://llun.in.th/post#3', authentication: 'none' });
      findServiceStub.withArgs({ name: 'service2', user: 'u2' }).callsArgWith(1, { _id: 's4', name: 'service2', user: 'u2', target: 'http://llun.in.th/action', authentication: 'none' });
      findServiceStub.callsArg(1);

      createMessageStub = sinon.stub(Message, 'create', function (message, cb) {
        var cloneMessage = _.clone(message);
        cloneMessage._id = 'message1';

        cb(null, _.clone(cloneMessage));
      });

    });

    after(function () {
      findUserStub.restore();
      findServiceStub.restore();

      nock.restore();
    });

    it ('should send request to both users', function (done) {

      deliver.send(__dirname + '/sample.mail', 'someone@mail.com', [ 'user1+service1@mailpipe.me', 'user2+service1@mailpipe.me' ],
        function (err, messages) {
          should.exist(messages);
          message.should.have.length(2);

          _.each(messages, function (message) {
            message.status.should.equal(Message.STATUS.SENT);
            message.from.should.equal('someone@mail.com');
          });

          message[0].to.should.equal('s1');
          message[1].to.should.equal('s3');

          done();
        });

    });

    it ('should send request to both services', function (done) {

      deliver.send(__dirname + '/sample.mail', 'someone@mail.com', [ 'user1+service1@mailpipe.me', 'user1+service2@mailpipe.me'],
        function (err, messages) {
          should.exist(messages);
          message.should.have.length(2);

          _.each(messages, function (message) {
            message.status.should.equal(Message.STATUS.SENT);
            message.from.should.equal('someone@mail.com');
          });

          message[0].to.should.equal('s1');
          message[1].to.should.equal('s2');

          done();
        });

    });

    it ('should return error for unknown service', function (done) {

      deliver.send(__dirname + '/sample.mail', 'someone@mail.com', [ 'user1+service3@mailpipe.me' ],
        function (err, messages) {
          should.exist(err);
          should.not.exist(messages);

          done();
        });

    });

    it ('should return error for service return 404', function (done) {

      deliver.send(__dirname + '/sample.mail', 'someone@mail.com', [ 'user2+service2@mailpipe.me' ],
        function (err, messages) {
          should.exist(err);
          should.not.exist(messages);

          done();
        });

    });

    it ('should return error and messages in case some messages is delivered', function (done) {

      deliver.send(__dirname + '/sample.mail', 'someone@mail.com', [ 'user1+service3@mailpipe.me', 'user1+service1@mailpipe.me', 'user1+service2@mailpipe.me' ],
        function (err, messages) {
          should.exist(err);
          should.exist(messages);

          messages.should.have.length(2);

          done();
        });

    });

  });

});<|endoftext|>


<commit_before>function KuzzleSecurityDocument(kuzzleSecurity, id, content) {
  // Define properties
  Object.defineProperties(this, {
    // private properties
    kuzzle: {
      value: kuzzleSecurity.kuzzle
    },
    kuzzleSecurity: {
      value: kuzzleSecurity
    },
    // read-only properties
    // writable properties
    id: {
      value: id,
      enumerable: true
    },
    content: {
      value: {},
      writable: true,
      enumerable: true
    }
  });

  if (content) {
    this.setContent(content);
  }

  if (!id) {
    throw new Error('A security document ' + typeof this + ' must have an id');
  }
}

/**
 *
 * @param {Object} data - New securityDocument content
 *
 * @return {Object} this
 */
KuzzleSecurityDocument.prototype.setContent = function (data) {
  this.content = data;

  return this;
};

/**
 * Serialize this object into a JSON object
 *
 * @return {object} JSON object representing this securityDocument
 */
KuzzleSecurityDocument.prototype.toJSON = function () {
  var
    data = {};

  if (this.id) {
    data._id = this.id;
  }

  data.body = this.content;

  return data;
};

module.exports = KuzzleSecurityDocument;<commit_msg>move check id on top of constructor KuzzleSecurityDocument<commit_after>function KuzzleSecurityDocument(kuzzleSecurity, id, content) {

  if (!id) {
    throw new Error('A security document ' + typeof this + ' must have an id');
  }

  // Define properties
  Object.defineProperties(this, {
    // private properties
    kuzzle: {
      value: kuzzleSecurity.kuzzle
    },
    kuzzleSecurity: {
      value: kuzzleSecurity
    },
    // read-only properties
    // writable properties
    id: {
      value: id,
      enumerable: true
    },
    content: {
      value: {},
      writable: true,
      enumerable: true
    }
  });

  if (content) {
    this.setContent(content);
  }
}

/**
 *
 * @param {Object} data - New securityDocument content
 *
 * @return {Object} this
 */
KuzzleSecurityDocument.prototype.setContent = function (data) {
  this.content = data;

  return this;
};

/**
 * Serialize this object into a JSON object
 *
 * @return {object} JSON object representing this securityDocument
 */
KuzzleSecurityDocument.prototype.toJSON = function () {
  var
    data = {};

  if (this.id) {
    data._id = this.id;
  }

  data.body = this.content;

  return data;
};

module.exports = KuzzleSecurityDocument;<|endoftext|>