<commit_before>var EventHandler = require('./../utilities/event-handler');
var Utilities = require('./../utilities/utilities');
var Injector = require('./injector');
var VirtualDOM = require('./../virtual-dom/virtual-dom');
var DataStore = require('./../data-store/data-store');
var Dispatcher = require('./dispatcher');

var COMPONENT_DELIM = ':';
var PUBLIC_KEY = '$public';
var PRIVATE_KEY = '$private';
var LIFECYCLE_KEY = '$lifecycle';
var DESCENDANT_KEY = 'descendant';
var SELF_KEY = '$self';
var MISS_KEY = '$miss';
var ANY_KEY = '$any';

function Events(eventGroups, name, rootNode) {
    EventHandler.apply(this);
    this.name = name;
    this.dispatcher = new Dispatcher(rootNode);
    this.eventStore = Events.processEventGroups(eventGroups);
}

Events.prototype = Object.create(EventHandler.prototype);
Events.prototype.constructor = Events;

Events.prototype.initializeDescendantEvents = function initializeDescendantEvents(targetRoot, uid) {
    var events;
    var events;
    var selector;
    var eventName;
    for (selector in this.eventStore[DESCENDANT_KEY]) {
        events = this.eventStore[DESCENDANT_KEY][selector];
        for (eventName in events) {
            event = events[eventName];
            if (eventName.indexOf(COMPONENT_DELIM) >= 0) {
                this.setupProxyEvent(event, targetRoot, uid);
            }
            else {
                this.setupDispatchedEvent(event, targetRoot, uid);
            }
        }
    }
}

/*
example:
events:
    '#surface'
        'famous:events:click' ()=>
 */
Events.prototype.setupProxyEvent = function setupProxyEvent(event, targetRoot, uid) {
    var trigger = Events.getDirectEventAction(event.name);
    var triggerParams = Utilities.getParameterNames(trigger);
    var lastDelimIdx = event.name.lastIndexOf(COMPONENT_DELIM);
    var eventName = event.name.slice(lastDelimIdx + 1); // 'famous:events:click' -> 'click'

    var payload = {
        eventName: eventName
    };

    var targets = VirtualDOM.query(targetRoot, event.selector);
    var targetUID;
    var bestComponent;
    var triggerArgs;
    for (var i = targets.length - 1; i >= 0; i--) {
        targetUID = VirtualDOM.getUID(targets[i]);
        bestComponent = DataStore.getComponent(targetUID);

        payload.listener = function(eventPayload) {
            var listenerArgs = Injector.getArgs(event.params, eventPayload, uid);
            event.action.apply(null, listenerArgs);
        }

        triggerArgs = Injector.getArgs(triggerParams, payload, targetUID);
        trigger.apply(null, triggerArgs);
    };
}

/*
example:
events:
    '#surface'
        'custom-event' ()=>
 */
Events.prototype.setupDispatchedEvent = function setupDispatchedEvent(event, targetRoot, uid) {
    var self = this;
    var targets = VirtualDOM.query(targetRoot, event.selector);
    var component;
    var eventChannel;
    for (var i = 0; i < targets.length; i++) {
        component = DataStore.getComponent(VirtualDOM.getUID(targets[i]));
        component.events.dispatcher.on(event.name, function(message) {
            self.sendDescendantMessage(event.name, message, event.selector, uid)
        });
    }
}

Events.prototype.sendMessage = function sendMessage(key, value, uid) {
    var publicEvents = this.eventStore[PUBLIC_KEY];
    var eventsToFire = [];
    if (publicEvents[ANY_KEY]) {
        eventsToFire.push(publicEvents[key]);
    }
    if (publicEvents[key]) {
        eventsToFire.push(publicEvents[key]);
    }
    else {
        if (publicEvents[MISS_KEY]) {
            eventsToFire.push(publicEvents[MISS_KEY])
        }
    }

    if (eventsToFire.length < 1) {
        throw new Error('Unknown public event `' + key + '` for `' + this.name + '`');
    }

    var event;
    var args;
    for (var i = 0; i < eventsToFire.length; i++) {
        event = eventsToFire[i];
        args = Injector.getArgs(event.params, value, uid);
        event.action.apply(null, args);
    }
}

Events.prototype.sendMessages = function sendMessages(messages, uid) {
    for (var key in messages) {
        this.sendMessage(key, messages[key], uid);
    }
}

Events.prototype.sendDescendantMessage = function sendDescendantMessage(eventName, message, selector, uid) {
    var eventsToFire = [];
    var descendantEvents = this.eventStore[DESCENDANT_KEY][selector] || {};
    var i;
    var event;
    for (var descendantEventName in descendantEvents) {
        event = descendantEvents[descendantEventName];
        if (descendantEventName === eventName) {
            eventsToFire.push(event);
        }
    }

    if (eventsToFire.length < 1) {
        throw new Error('Unknown event `' + eventName + '` for `' + this.name + '` (' + selector + ')');
    }

    for (i = 0; i < eventsToFire.length; i++) {
        event = eventsToFire[i];
        event.action.apply(null, Injector.getArgs(event.params, message, uid));
    }
}

Events.prototype.getPublicEvent = function getPublicEvent(eventName) {
    return this.eventStore[PUBLIC_KEY][eventName];
}

Events.prototype.triggerDirectEventHandler = function triggerDirectEventHandler(name, payload, uid) {
    var handler = Events.getDirectEventAction(name);
    var handlerParams = Utilities.getParameterNames(handler);
    var handlerArgs = Injector.getArgs(handlerParams, payload, uid);
    handler.apply(null, handlerArgs);
}

Events.prototype.getSelfEvent = function getSelfEvent(eventName) {
    var lastDelimIdx = eventName.indexOf(COMPONENT_DELIM);
    eventName = eventName.slice(lastDelimIdx + 1);
    var event  = this.eventStore[PRIVATE_KEY][eventName];

    if (event) {
        return event;
    }
    else {
        return this.getPublicEvent(eventName);
    }
}

Events.prototype.triggerEvent = function(event, payload, uid) {
    var selector = event.selector;
    switch (selector) {
        case PUBLIC_KEY:
        case PRIVATE_KEY:
            this._executeEvent(event, payload, uid);
            break;
        case LIFECYCLE_KEY: this._triggerLifecycleEvent(event.name, payload, uid); break;
        case DESCENDANT_KEY: this._triggerDescendantEvent(event.name, payload, uid); break;
        default: throw new Error('`' + selector + '` is not a valid event selector');
    }
}

Events.prototype._executeEvent = function _executeEvent(event, payload, uid) {
    var args = Injector.getArgs(event.params, payload, uid);
    event.action.apply(null, args);
}

Events.prototype.triggerPublicEvent = function triggerPublicEvent(eventName, payload, uid) {
    var event = this.eventStore[PUBLIC_KEY][eventName];
    if (!event) {
        throw new Error('Unknown public event `' + eventName + '` for `' + this.name + '`');
    }

    this._executeEvent(event, payload, uid);
}

Events.prototype._triggerLifecycleEvent = function _triggerLifecycleEvent(eventName, payload, uid) {
    // TODO
}

Events.prototype._triggerDescendantEvent = function triggerDescendantEvent(eventName, payload, uid) {
    // TODO
}

Events.processEventGroups = function processEventGroups(groups) {
    var list = {};
    list[PUBLIC_KEY] = {};
    list[PRIVATE_KEY] = {};
    list[LIFECYCLE_KEY] = {};
    list[DESCENDANT_KEY] = {};

    var selector;
    var events;
    var eventName;
    var store;
    for (selector in groups) {
        events = groups[selector];
        store = {};
        for (eventName in events) {
            store[eventName] = {
                name: eventName,
                action: events[eventName],
                selector: selector,
                params: Utilities.getParameterNames(events[eventName])
            };
        }

        switch (selector) {
            case PUBLIC_KEY: list[PUBLIC_KEY] = store; break;
            case PRIVATE_KEY: list[PRIVATE_KEY] = store; break;
            case LIFECYCLE_KEY: list[LIFECYCLE_KEY] = store; break;
            default: list[DESCENDANT_KEY][selector] = store; break;
        }
    }

    return list;
}

Events.getDirectEventAction = function getDirectEventAction(name) {
    var lastDelimIdx = name.lastIndexOf(COMPONENT_DELIM);
    var moduleName = name.slice(0, lastDelimIdx);
    var handlerName = name.slice(lastDelimIdx + 1);
    var bestModule = DataStore.getModule(moduleName);

    var foundEvent;
    var fallbackEvent;
    var action;
    for (var eventName in bestModule.events[PUBLIC_KEY]) {
        action = bestModule.events[PUBLIC_KEY][eventName];
        if (eventName === handlerName) {
            foundEvent = action;
            break;
        }
        else if (eventName === MISS_KEY || eventName === ANY_KEY) {
            fallbackEvent = action;
        }
    }

    var handler = foundEvent || fallbackEvent;
    if (!handler) {
        throw new Error('Unknown behavior handler `' + name + '`');
    }
    return handler;
}

module.exports = Events;
<commit_msg>Use Logger to post error message for unfound public event<commit_after>var EventHandler = require('./../utilities/event-handler');
var Utilities = require('./../utilities/utilities');
var Injector = require('./injector');
var VirtualDOM = require('./../virtual-dom/virtual-dom');
var DataStore = require('./../data-store/data-store');
var Logger = require('./../logger/logger');
var Dispatcher = require('./dispatcher');

var COMPONENT_DELIM = ':';
var PUBLIC_KEY = '$public';
var PRIVATE_KEY = '$private';
var LIFECYCLE_KEY = '$lifecycle';
var DESCENDANT_KEY = 'descendant';
var SELF_KEY = '$self';
var MISS_KEY = '$miss';
var ANY_KEY = '$any';

function Events(eventGroups, name, rootNode) {
    EventHandler.apply(this);
    this.name = name;
    this.dispatcher = new Dispatcher(rootNode);
    this.eventStore = Events.processEventGroups(eventGroups);
}

Events.prototype = Object.create(EventHandler.prototype);
Events.prototype.constructor = Events;

Events.prototype.initializeDescendantEvents = function initializeDescendantEvents(targetRoot, uid) {
    var events;
    var events;
    var selector;
    var eventName;
    for (selector in this.eventStore[DESCENDANT_KEY]) {
        events = this.eventStore[DESCENDANT_KEY][selector];
        for (eventName in events) {
            event = events[eventName];
            if (eventName.indexOf(COMPONENT_DELIM) >= 0) {
                this.setupProxyEvent(event, targetRoot, uid);
            }
            else {
                this.setupDispatchedEvent(event, targetRoot, uid);
            }
        }
    }
}

/*
example:
events:
    '#surface'
        'famous:events:click' ()=>
 */
Events.prototype.setupProxyEvent = function setupProxyEvent(event, targetRoot, uid) {
    var trigger = Events.getDirectEventAction(event.name);
    var triggerParams = Utilities.getParameterNames(trigger);
    var lastDelimIdx = event.name.lastIndexOf(COMPONENT_DELIM);
    var eventName = event.name.slice(lastDelimIdx + 1); // 'famous:events:click' -> 'click'

    var payload = {
        eventName: eventName
    };

    var targets = VirtualDOM.query(targetRoot, event.selector);
    var targetUID;
    var bestComponent;
    var triggerArgs;
    for (var i = targets.length - 1; i >= 0; i--) {
        targetUID = VirtualDOM.getUID(targets[i]);
        bestComponent = DataStore.getComponent(targetUID);

        payload.listener = function(eventPayload) {
            var listenerArgs = Injector.getArgs(event.params, eventPayload, uid);
            event.action.apply(null, listenerArgs);
        }

        triggerArgs = Injector.getArgs(triggerParams, payload, targetUID);
        trigger.apply(null, triggerArgs);
    };
}

/*
example:
events:
    '#surface'
        'custom-event' ()=>
 */
Events.prototype.setupDispatchedEvent = function setupDispatchedEvent(event, targetRoot, uid) {
    var self = this;
    var targets = VirtualDOM.query(targetRoot, event.selector);
    var component;
    var eventChannel;
    for (var i = 0; i < targets.length; i++) {
        component = DataStore.getComponent(VirtualDOM.getUID(targets[i]));
        component.events.dispatcher.on(event.name, function(message) {
            self.sendDescendantMessage(event.name, message, event.selector, uid)
        });
    }
}

Events.prototype.sendMessage = function sendMessage(key, value, uid) {
    var publicEvents = this.eventStore[PUBLIC_KEY];
    var eventsToFire = [];
    if (publicEvents[ANY_KEY]) {
        eventsToFire.push(publicEvents[key]);
    }
    if (publicEvents[key]) {
        eventsToFire.push(publicEvents[key]);
    }
    else {
        if (publicEvents[MISS_KEY]) {
            eventsToFire.push(publicEvents[MISS_KEY])
        }
    }

    if (eventsToFire.length < 1) {
        Logger.log('Unknown public event `' + key + '` for `' + this.name + '`', 1);
    }

    var event;
    var args;
    for (var i = 0; i < eventsToFire.length; i++) {
        event = eventsToFire[i];
        args = Injector.getArgs(event.params, value, uid);
        event.action.apply(null, args);
    }
}

Events.prototype.sendMessages = function sendMessages(messages, uid) {
    for (var key in messages) {
        this.sendMessage(key, messages[key], uid);
    }
}

Events.prototype.sendDescendantMessage = function sendDescendantMessage(eventName, message, selector, uid) {
    var eventsToFire = [];
    var descendantEvents = this.eventStore[DESCENDANT_KEY][selector] || {};
    var i;
    var event;
    for (var descendantEventName in descendantEvents) {
        event = descendantEvents[descendantEventName];
        if (descendantEventName === eventName) {
            eventsToFire.push(event);
        }
    }

    if (eventsToFire.length < 1) {
        throw new Error('Unknown event `' + eventName + '` for `' + this.name + '` (' + selector + ')');
    }

    for (i = 0; i < eventsToFire.length; i++) {
        event = eventsToFire[i];
        event.action.apply(null, Injector.getArgs(event.params, message, uid));
    }
}

Events.prototype.getPublicEvent = function getPublicEvent(eventName) {
    return this.eventStore[PUBLIC_KEY][eventName];
}

Events.prototype.triggerDirectEventHandler = function triggerDirectEventHandler(name, payload, uid) {
    var handler = Events.getDirectEventAction(name);
    var handlerParams = Utilities.getParameterNames(handler);
    var handlerArgs = Injector.getArgs(handlerParams, payload, uid);
    handler.apply(null, handlerArgs);
}

Events.prototype.getSelfEvent = function getSelfEvent(eventName) {
    var lastDelimIdx = eventName.indexOf(COMPONENT_DELIM);
    eventName = eventName.slice(lastDelimIdx + 1);
    var event  = this.eventStore[PRIVATE_KEY][eventName];

    if (event) {
        return event;
    }
    else {
        return this.getPublicEvent(eventName);
    }
}

Events.prototype.triggerEvent = function(event, payload, uid) {
    var selector = event.selector;
    switch (selector) {
        case PUBLIC_KEY:
        case PRIVATE_KEY:
            this._executeEvent(event, payload, uid);
            break;
        case LIFECYCLE_KEY: this._triggerLifecycleEvent(event.name, payload, uid); break;
        case DESCENDANT_KEY: this._triggerDescendantEvent(event.name, payload, uid); break;
        default: throw new Error('`' + selector + '` is not a valid event selector');
    }
}

Events.prototype._executeEvent = function _executeEvent(event, payload, uid) {
    var args = Injector.getArgs(event.params, payload, uid);
    event.action.apply(null, args);
}

Events.prototype.triggerPublicEvent = function triggerPublicEvent(eventName, payload, uid) {
    var event = this.eventStore[PUBLIC_KEY][eventName];
    if (!event) {
        throw new Error('Unknown public event `' + eventName + '` for `' + this.name + '`');
    }

    this._executeEvent(event, payload, uid);
}

Events.prototype._triggerLifecycleEvent = function _triggerLifecycleEvent(eventName, payload, uid) {
    // TODO
}

Events.prototype._triggerDescendantEvent = function triggerDescendantEvent(eventName, payload, uid) {
    // TODO
}

Events.processEventGroups = function processEventGroups(groups) {
    var list = {};
    list[PUBLIC_KEY] = {};
    list[PRIVATE_KEY] = {};
    list[LIFECYCLE_KEY] = {};
    list[DESCENDANT_KEY] = {};

    var selector;
    var events;
    var eventName;
    var store;
    for (selector in groups) {
        events = groups[selector];
        store = {};
        for (eventName in events) {
            store[eventName] = {
                name: eventName,
                action: events[eventName],
                selector: selector,
                params: Utilities.getParameterNames(events[eventName])
            };
        }

        switch (selector) {
            case PUBLIC_KEY: list[PUBLIC_KEY] = store; break;
            case PRIVATE_KEY: list[PRIVATE_KEY] = store; break;
            case LIFECYCLE_KEY: list[LIFECYCLE_KEY] = store; break;
            default: list[DESCENDANT_KEY][selector] = store; break;
        }
    }

    return list;
}

Events.getDirectEventAction = function getDirectEventAction(name) {
    var lastDelimIdx = name.lastIndexOf(COMPONENT_DELIM);
    var moduleName = name.slice(0, lastDelimIdx);
    var handlerName = name.slice(lastDelimIdx + 1);
    var bestModule = DataStore.getModule(moduleName);

    var foundEvent;
    var fallbackEvent;
    var action;
    for (var eventName in bestModule.events[PUBLIC_KEY]) {
        action = bestModule.events[PUBLIC_KEY][eventName];
        if (eventName === handlerName) {
            foundEvent = action;
            break;
        }
        else if (eventName === MISS_KEY || eventName === ANY_KEY) {
            fallbackEvent = action;
        }
    }

    var handler = foundEvent || fallbackEvent;
    if (!handler) {
        throw new Error('Unknown behavior handler `' + name + '`');
    }
    return handler;
}

module.exports = Events;
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var parseRequest = require('../parse-request');
var util = require('util');
var _ = require('@sailshq/lodash');

/**
 * Update One Record
 *
 * http://sailsjs.com/docs/reference/blueprint-api/update
 *
 * An API call to update a model instance with the specified `id`,
 * treating the other unbound parameters as attributes.
 *
 */

module.exports = function updateOneRecord (req, res) {

  var queryOptions = parseRequest('update', req);
  var Model = req._sails.models[queryOptions.using];

  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  // FUTURE: Use a database transaction here, if supported by the datastore.
  // e.g.
  // ```
  // Model.getDatastore().transaction(function during(db, proceed){ ... })
  // .exec(function afterwards(err, result){}));
  // ```
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  // Find and update the targeted record.
  //
  // (Note: this could be achieved in a single query, but a separate `findOne`
  //  is used first to provide a better experience for front-end developers
  //  integrating with the blueprint API.)
  var query = Model.findOne(queryOptions.criteria.where, queryOptions.populates);
  query.exec(function found(err, matchingRecord) {
    if (err) {
      switch (err.name) {
        case 'UsageError': return res.badRequest(err);
        default: return res.serverError(err);
      }
    }//-•

    if (!matchingRecord) { return res.notFound(); }

    Model.update(queryOptions.criteria.where, queryOptions.valuesToSet).meta({fetch: true}).exec(function updated(err, records) {

      // Differentiate between waterline-originated validation errors
      // and serious underlying issues. Respond with badRequest if a
      // validation error is encountered, w/ validation info, or if a
      // uniqueness constraint is violated.
      if (err) {
        switch (err.name) {
          case 'AdapterError':
            switch (err.code) {
              case 'E_UNIQUE': return res.badRequest(err);
              default: return res.serverError(err);
            } return;
          case 'UsageError': return res.badRequest(err);
          default: return res.serverError(err);
        }
      }//-•

      // If we didn't fetch the updated instance, just return 'OK'.
      if (!records) {
        return res.ok();
      }

      if (!_.isArray(records)) {
        return res.serverError('Consistency violation: When `fetch: true` is used, the second argument of the callback from update should always be an array-- but for some reason, it was not!  This should never happen... it could be due to a bug or partially implemented feature in the database adapter, or some other unexpected circumstance.');
      }

      // Because this should only update a single record and update
      // returns an array, just use the first item.  If more than one
      // record was returned, something is amiss.
      if (!records.length || records.length > 1) {
        req._sails.log.warn(
        util.format('Unexpected output from `%s.update`.', Model.globalId)
        );
      }

      var updatedRecord = records[0];

      var pk = updatedRecord[Model.primaryKey];

      // If we have the pubsub hook, use the Model's publish method
      // to notify all subscribers about the update.
      if (req._sails.hooks.pubsub) {
        if (req.isSocket) { Model.subscribe(req, _.pluck(records, Model.primaryKey)); }
        Model._publishUpdate(pk, _.cloneDeep(queryOptions.valuesToSet), !req.options.mirror && req, {
          previous: _.cloneDeep(matchingRecord)
        });
      }

      // Do a final query to populate the associations of the record.
      //
      // (Note: again, this extra query could be eliminated, but it is
      //  included by default to provide a better interface for integrating
      //  front-end developers.)
      var Q = Model.findOne(queryOptions.criteria.where, queryOptions.populates);
      Q.exec(function foundAgain(err, populatedRecord) {
        if (err) { return res.serverError(err); }
        if (!populatedRecord) { return res.serverError('Could not find record after updating!'); }
        res.ok(populatedRecord);
      }); // </foundAgain>
    });// </updated>
  }); // </found>
};
<commit_msg>Set `req.options.blueprintAction` in `update` blueprint, and send whole `queryOptions.criteria` as first argument to `.update()`<commit_after>/**
 * Module dependencies
 */

var parseRequest = require('../parse-request');
var util = require('util');
var _ = require('@sailshq/lodash');

/**
 * Update One Record
 *
 * http://sailsjs.com/docs/reference/blueprint-api/update
 *
 * An API call to update a model instance with the specified `id`,
 * treating the other unbound parameters as attributes.
 *
 */

module.exports = function updateOneRecord (req, res) {

  // Set the blueprint action for parseRequest.
  req.options.blueprintAction = 'update';

  var queryOptions = parseRequest(req);
  var Model = req._sails.models[queryOptions.using];

  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  // FUTURE: Use a database transaction here, if supported by the datastore.
  // e.g.
  // ```
  // Model.getDatastore().transaction(function during(db, proceed){ ... })
  // .exec(function afterwards(err, result){}));
  // ```
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  // Find and update the targeted record.
  //
  // (Note: this could be achieved in a single query, but a separate `findOne`
  //  is used first to provide a better experience for front-end developers
  //  integrating with the blueprint API.)
  var query = Model.findOne(_.cloneDeep(queryOptions.criteria), _.cloneDeep(queryOptions.populates));
  query.exec(function found(err, matchingRecord) {
    if (err) {
      switch (err.name) {
        case 'UsageError': return res.badRequest(err);
        default: return res.serverError(err);
      }
    }//-•

    if (!matchingRecord) { return res.notFound(); }

    Model.update(_.cloneDeep(queryOptions.criteria), queryOptions.valuesToSet).meta(queryOptions.meta).exec(function updated(err, records) {

      // Differentiate between waterline-originated validation errors
      // and serious underlying issues. Respond with badRequest if a
      // validation error is encountered, w/ validation info, or if a
      // uniqueness constraint is violated.
      if (err) {
        switch (err.name) {
          case 'AdapterError':
            switch (err.code) {
              case 'E_UNIQUE': return res.badRequest(err);
              default: return res.serverError(err);
            } return;
          case 'UsageError': return res.badRequest(err);
          default: return res.serverError(err);
        }
      }//-•

      // If we didn't fetch the updated instance, just return 'OK'.
      if (!records) {
        return res.ok();
      }

      if (!_.isArray(records)) {
        return res.serverError('Consistency violation: When `fetch: true` is used, the second argument of the callback from update should always be an array-- but for some reason, it was not!  This should never happen... it could be due to a bug or partially implemented feature in the database adapter, or some other unexpected circumstance.');
      }

      // Because this should only update a single record and update
      // returns an array, just use the first item.  If more than one
      // record was returned, something is amiss.
      if (!records.length || records.length > 1) {
        req._sails.log.warn(
        util.format('Unexpected output from `%s.update`.', Model.globalId)
        );
      }

      var updatedRecord = records[0];

      var pk = updatedRecord[Model.primaryKey];

      // If we have the pubsub hook, use the Model's publish method
      // to notify all subscribers about the update.
      if (req._sails.hooks.pubsub) {
        if (req.isSocket) { Model.subscribe(req, _.pluck(records, Model.primaryKey)); }
        Model._publishUpdate(pk, _.cloneDeep(queryOptions.valuesToSet), !req.options.mirror && req, {
          previous: _.cloneDeep(matchingRecord)
        });
      }

      // Do a final query to populate the associations of the record.
      //
      // (Note: again, this extra query could be eliminated, but it is
      //  included by default to provide a better interface for integrating
      //  front-end developers.)
      var Q = Model.findOne(_.cloneDeep(queryOptions.criteria), _.cloneDeep(queryOptions.populates));
      Q.exec(function foundAgain(err, populatedRecord) {
        if (err) { return res.serverError(err); }
        if (!populatedRecord) { return res.serverError('Could not find record after updating!'); }
        res.ok(populatedRecord);
      }); // </foundAgain>
    });// </updated>
  }); // </found>
};
<|endoftext|>


<commit_before>/**
 * Randy is a country singer that sends notifications, drives a Trans Am, and is one serious bad ass.
 *
 * @package randy
 * @author Andrew Sliwinski <andrew@diy.org>
 */

/**
 * Dependencies
 */
var _       = require('underscore'),
    async   = require('async'),
    redis   = require('redis'),
    sio     = require('socket.io'),
    uuid    = require('node-uuid');

var Util    = require('./util'),
    Storage = require('./storage');

/**
 * Generic socket emitter.
 *
 * @param {Object} Socket
 * @param {Object} Notice
 *
 * @return {void}
 */
function emit (socket, notice) {
    socket.emit('notice', notice);
}

// --------------------------------

/**
 * Constructor
 */
function Randy () {
    var self = this;

    // Setup
    self.ns         = 'randy';
    self.pub        = null;
    self.sub        = null;
    self.store      = null;
    self.io         = null;
    self.sockets    = new Object(null);

    /**
     * Gets the socket (if available) for the specified target.
     *
     * @param {String} Target
     *
     * @return {Object}
     */
    function getSocket (target, callback) {
        if (target === null || target === '') {
            callback(null, self.io.sockets);
        } else {
            try {
                callback(null, self.sockets[target].socket);
            } catch (err) {
                Util.stdout(err);
            }
        }
    };

    /**
     * Subscription "message" event handler.
     *
     * @param {String} Channel
     * @param {String} Notice (JSON String)
     *
     * @return {void}
     */
    self.listener   = function (channel, data) {
        async.auto({
            decode:      function (callback) {
                Util.parse(data, callback);
            },

            socket:     ['decode', function (callback, obj) {
                getSocket(obj.decode.target, callback);
            }],

            emit:       ['socket', function (callback, obj) {
                emit(obj.socket, obj.decode);
            }]
        }, Util.stdout);
    };

    /**
     * Socket.io "connection" event handler.
     *
     * @param {Object} Socket
     *
     * @return {void}
     */
    self.connection = function (socket) {

        /**
         * Registers a socket to begin recieving notifications.
         *
         * @param {String} Unique user id
         *
         * @return {void}
         */
        socket.on('register', function (id) {
            // Check if exists
            if (typeof self.sockets[id] === 'undefined') {
                self.sockets[id] = {
                    id:         socket.id,
                    socket:     socket
                };
            } else {
                self.sockets[id].id     = socket.id;
                self.sockets[id].socket = socket;
            }

            // Emit from storage
            self.store.all(id, function (err, obj) {
                if (err) {
                    callback(err);
                } else {
                    async.forEach(obj, function (a, callback) {
                        emit(socket, a);
                        callback();
                    }, Util.stdout);
                }
            });
        });

        /**
         * Dismisses a persistent notification.
         *
         * @param {Object} Identity
         *                      - id {String, Required}
         *                      - uid {String, Required}
         *
         * @return {void}
         */
        socket.on('dismiss', function (data) {
            self.store.del(data.uid, data.id, Util.stdout);
        });

        /**
         * Submits a new event via the loopback interface.
         *
         * @param {Object} Notification object (see "register" method).
         *
         * @return {void}
         */
        socket.on('loopback', function (data) {
            self.submit(data, Util.stdout);
        });
    };
};

/**
 * Start listening for connections on the specified port.
 *
 * @param {Number} Port
 *
 * @return {Error}
 */
Randy.prototype.listen = function (port, arg, callback) {
    var self = this;

    // Detect argument list
    if (_.isUndefined(callback)) {
        callback    = arg;
        arg         = {
            port:       null,
            host:       null,
            pass:       null,
            options:    null
        };
    };

    // Normalize "null" types
    for (var item in arg) {
        arg[item] = (arg[item] === 'null') ? null : arg[item];
    }

    try {
        // Connect
        self.store  = new Storage(redis.createClient(arg.port, arg.host, arg.options));
        self.pub    = redis.createClient(arg.port, arg.host, arg.options);
        self.sub    = redis.createClient(arg.port, arg.host, arg.options);

        // Authenticate
        if (arg.pass !== null) {
            self.store.auth(arg.pass, stdout);
            self.pub.auth(arg.pass, stdout);
            self.sub.auth(arg.pass, stdout);
        }

        // Pub / Sub
        self.sub.subscribe(self.ns);
        self.sub.on('message', self.listener);

        // Socket.io
        self.io     = sio.listen(Number(port));
        self.io.set('log level', 1);
        self.io.sockets.on('connection', self.connection);
        callback(null);
    } catch (err) {
        Util.stdout(err);
    }
};

/**
 * Submits a new notification.
 *
 * @param {Object} Notification
 *                  - persist {Boolean, Default=false}
 *                  - target {String, Default=null}
 *                  - message {String, Required}
 *
 * @return {Error}
 */
Randy.prototype.submit = function (notice, callback) {
    var self = this;

    _.defaults(notice, {
        id:         uuid.v4(),                  // Assign uuid
        stamp:      new Date().toJSON(),        // Timestamp
        persist:    false,
        target:     null,
        message:    null
    });

    // Normalize typing
    notice.persist  = (notice.persist.toLowerCase() === 'true' || notice.persist === true) ? true : false;
    notice.target   = (notice.target === '') ? null : notice.target;

    // Persist
    if (notice.persist && notice.target !== null) {
        self.store.set(notice.target, notice.id, notice, Util.stdout);
    }

    // If no message is specified, drop the request
    if (notice.message === null || notice.message === '') {
        return callback('No message was specified.');
    }

    // Hash notice and publish to redis store
    async.auto({
        encode:     function (callback) {
            Util.stringify(notice, callback);
        },

        publish:    ['encode', function (callback, obj) {
            self.pub.publish(self.ns, obj.encode);
            callback(null);
        }]
    }, callback);
};

/**
 * Destroy the socket.io connection and redis subscription(s).
 *
 * @return {Error}
 */
Randy.prototype.destroy = function (callback) {
    var self = this;

    try {
        self.sub.unsubscribe();
        self.pub.end();
        self.sub.end();
        callback(null);
    } catch (err) {
        Util.stdout(err);
    }
};

// --------------------------------
// --------------------------------

/**
 * Export
 */
module.exports = new Randy();
<commit_msg>Cast port number for redis connection<commit_after>/**
 * Randy is a country singer that sends notifications, drives a Trans Am, and is one serious bad ass.
 *
 * @package randy
 * @author Andrew Sliwinski <andrew@diy.org>
 */

/**
 * Dependencies
 */
var _       = require('underscore'),
    async   = require('async'),
    redis   = require('redis'),
    sio     = require('socket.io'),
    uuid    = require('node-uuid');

var Util    = require('./util'),
    Storage = require('./storage');

/**
 * Generic socket emitter.
 *
 * @param {Object} Socket
 * @param {Object} Notice
 *
 * @return {void}
 */
function emit (socket, notice) {
    socket.emit('notice', notice);
}

// --------------------------------

/**
 * Constructor
 */
function Randy () {
    var self = this;

    // Setup
    self.ns         = 'randy';
    self.pub        = null;
    self.sub        = null;
    self.store      = null;
    self.io         = null;
    self.sockets    = new Object(null);

    /**
     * Gets the socket (if available) for the specified target.
     *
     * @param {String} Target
     *
     * @return {Object}
     */
    function getSocket (target, callback) {
        if (target === null || target === '') {
            callback(null, self.io.sockets);
        } else {
            try {
                callback(null, self.sockets[target].socket);
            } catch (err) {
                Util.stdout(err);
            }
        }
    };

    /**
     * Subscription "message" event handler.
     *
     * @param {String} Channel
     * @param {String} Notice (JSON String)
     *
     * @return {void}
     */
    self.listener   = function (channel, data) {
        async.auto({
            decode:      function (callback) {
                Util.parse(data, callback);
            },

            socket:     ['decode', function (callback, obj) {
                getSocket(obj.decode.target, callback);
            }],

            emit:       ['socket', function (callback, obj) {
                emit(obj.socket, obj.decode);
            }]
        }, Util.stdout);
    };

    /**
     * Socket.io "connection" event handler.
     *
     * @param {Object} Socket
     *
     * @return {void}
     */
    self.connection = function (socket) {

        /**
         * Registers a socket to begin recieving notifications.
         *
         * @param {String} Unique user id
         *
         * @return {void}
         */
        socket.on('register', function (id) {
            // Check if exists
            if (typeof self.sockets[id] === 'undefined') {
                self.sockets[id] = {
                    id:         socket.id,
                    socket:     socket
                };
            } else {
                self.sockets[id].id     = socket.id;
                self.sockets[id].socket = socket;
            }

            // Emit from storage
            self.store.all(id, function (err, obj) {
                if (err) {
                    callback(err);
                } else {
                    async.forEach(obj, function (a, callback) {
                        emit(socket, a);
                        callback();
                    }, Util.stdout);
                }
            });
        });

        /**
         * Dismisses a persistent notification.
         *
         * @param {Object} Identity
         *                      - id {String, Required}
         *                      - uid {String, Required}
         *
         * @return {void}
         */
        socket.on('dismiss', function (data) {
            self.store.del(data.uid, data.id, Util.stdout);
        });

        /**
         * Submits a new event via the loopback interface.
         *
         * @param {Object} Notification object (see "register" method).
         *
         * @return {void}
         */
        socket.on('loopback', function (data) {
            self.submit(data, Util.stdout);
        });
    };
};

/**
 * Start listening for connections on the specified port.
 *
 * @param {Number} Port
 *
 * @return {Error}
 */
Randy.prototype.listen = function (port, arg, callback) {
    var self = this;

    // Detect argument list
    if (_.isUndefined(callback)) {
        callback    = arg;
        arg         = {
            port:       null,
            host:       null,
            pass:       null,
            options:    null
        };
    };

    // Normalize "null" types
    for (var item in arg) {
        arg[item] = (arg[item] === 'null') ? null : arg[item];
        arg[item] = (item === 'port') ? Number(arg[item]) : arg[item];
    }

    try {
        // Connect
        self.store  = new Storage(redis.createClient(arg.port, arg.host, arg.options));
        self.pub    = redis.createClient(arg.port, arg.host, arg.options);
        self.sub    = redis.createClient(arg.port, arg.host, arg.options);

        // Authenticate
        if (arg.pass !== null) {
            self.store.auth(arg.pass, stdout);
            self.pub.auth(arg.pass, stdout);
            self.sub.auth(arg.pass, stdout);
        }

        // Pub / Sub
        self.sub.subscribe(self.ns);
        self.sub.on('message', self.listener);

        // Socket.io
        self.io     = sio.listen(Number(port));
        self.io.set('log level', 1);
        self.io.sockets.on('connection', self.connection);
        callback(null);
    } catch (err) {
        Util.stdout(err);
    }
};

/**
 * Submits a new notification.
 *
 * @param {Object} Notification
 *                  - persist {Boolean, Default=false}
 *                  - target {String, Default=null}
 *                  - message {String, Required}
 *
 * @return {Error}
 */
Randy.prototype.submit = function (notice, callback) {
    var self = this;

    _.defaults(notice, {
        id:         uuid.v4(),                  // Assign uuid
        stamp:      new Date().toJSON(),        // Timestamp
        persist:    false,
        target:     null,
        message:    null
    });

    // Normalize typing
    notice.persist  = (notice.persist.toLowerCase() === 'true' || notice.persist === true) ? true : false;
    notice.target   = (notice.target === '') ? null : notice.target;

    // Persist
    if (notice.persist && notice.target !== null) {
        self.store.set(notice.target, notice.id, notice, Util.stdout);
    }

    // If no message is specified, drop the request
    if (notice.message === null || notice.message === '') {
        return callback('No message was specified.');
    }

    // Hash notice and publish to redis store
    async.auto({
        encode:     function (callback) {
            Util.stringify(notice, callback);
        },

        publish:    ['encode', function (callback, obj) {
            self.pub.publish(self.ns, obj.encode);
            callback(null);
        }]
    }, callback);
};

/**
 * Destroy the socket.io connection and redis subscription(s).
 *
 * @return {Error}
 */
Randy.prototype.destroy = function (callback) {
    var self = this;

    try {
        self.sub.unsubscribe();
        self.pub.end();
        self.sub.end();
        callback(null);
    } catch (err) {
        Util.stdout(err);
    }
};

// --------------------------------
// --------------------------------

/**
 * Export
 */
module.exports = new Randy();
<|endoftext|>


<commit_before>var express = require('express');
var url = require('url');
var net = require('net');
var path = require('path');
var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var exnted = require('util')._extend;
var util = require('../util');
var EventEmitter = require('events').EventEmitter;
var rules = require('./rules');
var rulesUtil = require('./rules/util');
var config = util.config;

function tunnelProxy(server, proxy) {

	server.on('connect', function(req, reqSocket, head) {//ws, wss, https proxy
		var tunnelUrl = req.url = util.setProtocol(req.url, true);
		var options = parseUrl();
		var resSocket;

		if (!options.hostname) {
			tunnelUrl = req.url = util.setProtocol(req.headers.host, true);
			parseUrl();
		}
		abortIfUnavailable(reqSocket);
		function emitError(err) {
			resSocket && resSocket.destroy();
			reqSocket.destroy();
		}

		function abortIfUnavailable(socket) {
			socket.on('error', emitError).on('close', emitError);
		}

		function parseUrl(_tunnelUrl, port) {
			_tunnelUrl = _tunnelUrl || tunnelUrl;
			options = req.options = url.parse(_tunnelUrl);
			options.port = options.port || port || 443;
			return options;
		}

		function tunnel() {
			rules.resolveHost(tunnelUrl, function(err, ip) {
				req.host = ip;
				if (!util.isLocalAddress(ip) || options.port != proxy.uisslport) {
					proxy.emit('tunnel', req);
				} else {
					options.port = proxy.uisslport;
				}

				if (err) {
					emitError(err);
					return;
				}

				resSocket = net.connect(options.port, ip || options.hostname, function() {
		            reqSocket.write('HTTP/1.1 200 Connection Established\r\nProxy-Agent: ' + config.name + '\r\n\r\n');
		            resSocket.pipe(reqSocket).pipe(resSocket);
		        });
				abortIfUnavailable(resSocket);
			});
		}

		var _rules = rules.resolveRules(tunnelUrl);
		var proxyUrl = _rules.proxy && _rules.proxy.matcher;
		if (proxyUrl) {
			var _tunnelUrl = 'https:' + util.removeProtocol(proxyUrl);
			rules.resolveHost(_tunnelUrl, function(err, ip) {
				req.host = ip;
				parseUrl(_tunnelUrl, config.port);
				if (!err && util.isLocalAddress(ip) && options.port == config.port) {
					parseUrl();
					return tunnel();
				}
				proxy.emit('tunnelProxy', req);
				if (err) {
					emitError(err);
					return;
				}

			});
		} else {
			tunnel();
		}
    });

	return server;
}

process.on('uncaughtException', function(err){
	  fs.writeFileSync(path.join(process.cwd(), config.name + '-log.log'), err.stack + '\r\n', {flag: 'a'});
	  console.error(err);
	  process.exit(1);
});

function proxy(port, middlewares, _config) {
	if (Array.isArray(port)) {
		_config = middlewares;
		middlewares = port;
	} else if (!Array.isArray(middlewares)) {
		middlewares = [];
	}

	exnted(config, _config);
	var proxyEvents = new EventEmitter();
	var app = express();

	var server = app.listen(proxyEvents.port = port || config.port);
	server.on('clientError', util.noop); //ignore，防止keepalive的socket发生error时，出现crash
	middlewares = ['./init',
	               '../biz/webui']
				   .concat(require('./inspectors'))
				   .concat(middlewares)
	               .concat(['../biz/tianma'])
	               .concat(require('./handlers'));

	middlewares.forEach(function(mw) {
		app.use((typeof mw == 'string' ? require(mw) : mw).bind(proxyEvents));
	});
	exportInterfaces(proxyEvents);
	tunnelProxy(server, proxyEvents);
	require('./proxy');
	return proxyEvents;
}

function exportInterfaces(obj) {
	obj.rules = rules;
	obj.util = util;
	obj.rulesUtil = rulesUtil;
	return obj;
}

module.exports = exportInterfaces(proxy);<commit_msg>rules<commit_after>var express = require('express');
var url = require('url');
var net = require('net');
var path = require('path');
var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var exnted = require('util')._extend;
var util = require('../util');
var EventEmitter = require('events').EventEmitter;
var rules = require('./rules');
var rulesUtil = require('./rules/util');
var connect = require('./proxy/connect');
var config = util.config;

function tunnelProxy(server, proxy) {

	server.on('connect', function(req, reqSocket, head) {//ws, wss, https proxy
		var tunnelUrl = req.url = util.setProtocol(req.url, true);
		var options = parseUrl();
		var resSocket;

		if (!options.hostname) {
			tunnelUrl = req.url = util.setProtocol(req.headers.host, true);
			parseUrl();
		}
		abortIfUnavailable(reqSocket);
		function emitError(err) {
			resSocket && resSocket.destroy();
			reqSocket.destroy();
		}

		function abortIfUnavailable(socket) {
			socket.on('error', emitError).on('close', emitError);
		}

		function parseUrl(_tunnelUrl, port) {
			_tunnelUrl = _tunnelUrl || tunnelUrl;
			options = req.options = url.parse(_tunnelUrl);
			options.port = options.port || port || 443;
			return options;
		}

		function tunnel() {
			rules.resolveHost(tunnelUrl, function(err, ip) {
				req.host = ip;
				if (!util.isLocalAddress(ip) || options.port != proxy.uisslport) {
					proxy.emit('tunnel', req);
				} else {
					options.port = proxy.uisslport;
				}

				if (err) {
					emitError(err);
					return;
				}

				resSocket = net.connect(options.port, ip || options.hostname, function() {
		            reqSocket.write('HTTP/1.1 200 Connection Established\r\nProxy-Agent: ' + config.name + '\r\n\r\n');
		            resSocket.pipe(reqSocket).pipe(resSocket);
		        });
				abortIfUnavailable(resSocket);
			});
		}

		var _rules = rules.resolveRules(tunnelUrl);
		var proxyUrl = _rules.proxy && _rules.proxy.matcher;
		if (proxyUrl) {
			var _tunnelUrl = 'https:' + util.removeProtocol(proxyUrl);
			rules.resolveHost(_tunnelUrl, function(err, ip) {
				req.host = ip;
				parseUrl(_tunnelUrl, config.port);
				if (!err && util.isLocalAddress(ip) && options.port == config.port) {
					parseUrl();
					return tunnel();
				}
				proxy.emit('tunnelProxy', req);
				if (err) {
					emitError(err);
					return;
				}
				options.host = ip;
				connect(req, function(err, proxySocket) {
					abortIfUnavailable(proxySocket);
					resSocket.pipe(proxySocket).pipe(resSocket);
				});
			});
		} else {
			tunnel();
		}
    });

	return server;
}

process.on('uncaughtException', function(err){
	  fs.writeFileSync(path.join(process.cwd(), config.name + '-log.log'), err.stack + '\r\n', {flag: 'a'});
	  console.error(err);
	  process.exit(1);
});

function proxy(port, middlewares, _config) {
	if (Array.isArray(port)) {
		_config = middlewares;
		middlewares = port;
	} else if (!Array.isArray(middlewares)) {
		middlewares = [];
	}

	exnted(config, _config);
	var proxyEvents = new EventEmitter();
	var app = express();

	var server = app.listen(proxyEvents.port = port || config.port);
	server.on('clientError', util.noop); //ignore，防止keepalive的socket发生error时，出现crash
	middlewares = ['./init',
	               '../biz/webui']
				   .concat(require('./inspectors'))
				   .concat(middlewares)
	               .concat(['../biz/tianma'])
	               .concat(require('./handlers'));

	middlewares.forEach(function(mw) {
		app.use((typeof mw == 'string' ? require(mw) : mw).bind(proxyEvents));
	});
	exportInterfaces(proxyEvents);
	tunnelProxy(server, proxyEvents);
	require('./proxy');
	return proxyEvents;
}

function exportInterfaces(obj) {
	obj.rules = rules;
	obj.util = util;
	obj.rulesUtil = rulesUtil;
	return obj;
}

module.exports = exportInterfaces(proxy);<|endoftext|>


<commit_before>'use strict';

var is = require('is_js');

var debug = function () {};

var GET_RE = /.*(get).*/gi;
var POST_RE = /.*(post).*/gi;
var PUT_RE = /.*(put).*/gi;
var DELETE_RE = /.*(delete).*/gi;
var $1 = '$1';

/**
 * Returns a clean, lower case method name.
 */
function clean(method) {
  if (method.match(GET_RE)) {
    return method.replace(GET_RE, $1).toLowerCase();
  }

  if (method.match(POST_RE)) {
    return method.replace(POST_RE, $1).toLowerCase();
  }

  if (method.match(PUT_RE)) {
    return method.replace(PUT_RE, $1).toLowerCase();
  }

  if (method.match(DELETE_RE)) {
    return method.replace(DELETE_RE, $1).toLowerCase();
  }

  throw new Error("Invalid method [" + method + "]!");
}

/**
 * Normalizes a route object.
 */
function normalize(route) {
  if (is.not.array(route.path) && is.not.string(route.path)) {
    throw new Error("The route's path must be a [String] or an [Array] of [String]s!");
  }

  if (is.array(route.method)) {
    /* If method is an array */
    route.method.forEach(function (method, index) {
      route.method[index] = clean(method);
    });
  }

  /* If method is a string */
  if (is.string(route.method)) {
    route.method = clean(route.method);
  }

  return route;
}

/**
 * Authorizes a route for the current session.
 *
 * @type Express Middleware.
 *
 * @param {Object} route The route object.
 * @param {Object} req Express' req object.
 * @param {Object} res Express' res object.
 * @param {Function} next Express' next function.
 */
function authorize(req, res, next) {
  var allowed = true;

  if (is.array(req.allows)) {
    allowed = req.route.allows.indexOf(req.session.authorized) > -1;
  } else if (is.string(req.route.allows)) {
    allowed = req.route.allows === req.session.authorized;
  }

  debug(req.method + " " + req.path + " [" + req.route.allows + "][" + req.session.authorized + "] : " + (allowed ? "OK" : "DENY"));

  if (allowed) {
    return next();
  }

  res.status(403).end();
}

/**
 * Generates the Express middleware to associate the allowed values to the route.
 */
function generate(allows) {
  return function (req, res, next) {
    req.route.allows = allows;

    next();
  };
}

/**
 * Initializes and registers route athuorizations.
 *
 * @param {Object} app Express application.
 * @param {Object} config Configuration object.
 */
function auth(app, config) {
  /* Ensure authorizer */
  if (is.not.function(config.authorizer)) {
    throw new Error("Authorizer must be a [Function]!");
  }

  /* Check debug type */
  if (is.function(config.debug)) {
    debug = config.debug;
  } else if (config.debug) {
    debug = console.log;
  }

  /* Set the authorized property in 'req.session' */
  app.use(function (req, res, next) {
    req.session.authorized = config.authorizer(req);

    next();
  });

  function onEachRoute(route) {
    route = normalize(route);

    debug(route.method + " " + route.path + " --> " + route.allows);

    var router = app.route(route.path);

    if (is.array(route.method) && route.method.length) {
      route.method.forEach(function (method) {
        router[method](generate(route.allows), authorize);
      });
    } else if (is.string(route.method)) {
      router[route.method](generate(route.allows), authorize);
    } else /* Defaults to all */ {
      router(generate(route.allows), authorize);
    }
  }

  /* Set authorization rules for each route */
  config.routes.forEach(onEachRoute);
}

module.exports = auth;
<commit_msg>Fixed all routes fallback<commit_after>'use strict';

var is = require('is_js');

var debug = function () {};

var GET_RE = /.*(get).*/gi;
var POST_RE = /.*(post).*/gi;
var PUT_RE = /.*(put).*/gi;
var DELETE_RE = /.*(delete).*/gi;
var $1 = '$1';

/**
 * Returns a clean, lower case method name.
 */
function clean(method) {
  if (method.match(GET_RE)) {
    return method.replace(GET_RE, $1).toLowerCase();
  }

  if (method.match(POST_RE)) {
    return method.replace(POST_RE, $1).toLowerCase();
  }

  if (method.match(PUT_RE)) {
    return method.replace(PUT_RE, $1).toLowerCase();
  }

  if (method.match(DELETE_RE)) {
    return method.replace(DELETE_RE, $1).toLowerCase();
  }

  throw new Error("Invalid method [" + method + "]!");
}

/**
 * Normalizes a route object.
 */
function normalize(route) {
  if (is.not.array(route.path) && is.not.string(route.path)) {
    throw new Error("The route's path must be a [String] or an [Array] of [String]s!");
  }

  if (is.array(route.method)) {
    /* If method is an array */
    route.method.forEach(function (method, index) {
      route.method[index] = clean(method);
    });
  }

  /* If method is a string */
  if (is.string(route.method)) {
    route.method = clean(route.method);
  }

  return route;
}

/**
 * Authorizes a route for the current session.
 *
 * @type Express Middleware.
 *
 * @param {Object} route The route object.
 * @param {Object} req Express' req object.
 * @param {Object} res Express' res object.
 * @param {Function} next Express' next function.
 */
function authorize(req, res, next) {
  var allowed = true;

  if (is.array(req.allows)) {
    allowed = req.route.allows.indexOf(req.session.authorized) > -1;
  } else if (is.string(req.route.allows)) {
    allowed = req.route.allows === req.session.authorized;
  }

  debug(req.method + " " + req.path + " [" + req.route.allows + "][" + req.session.authorized + "] : " + (allowed ? "OK" : "DENY"));

  if (allowed) {
    return next();
  }

  res.status(403).end();
}

/**
 * Generates the Express middleware to associate the allowed values to the route.
 */
function generate(allows) {
  return function (req, res, next) {
    req.route.allows = allows;

    next();
  };
}

/**
 * Initializes and registers route athuorizations.
 *
 * @param {Object} app Express application.
 * @param {Object} config Configuration object.
 */
function auth(app, config) {
  /* Ensure authorizer */
  if (is.not.function(config.authorizer)) {
    throw new Error("Authorizer must be a [Function]!");
  }

  /* Check debug type */
  if (is.function(config.debug)) {
    debug = config.debug;
  } else if (config.debug) {
    debug = console.log;
  }

  /* Set the authorized property in 'req.session' */
  app.use(function (req, res, next) {
    req.session.authorized = config.authorizer(req);

    next();
  });

  function onEachRoute(route) {
    route = normalize(route);

    debug(route.method + " " + route.path + " --> " + route.allows);

    var router = app.route(route.path);

    if (is.array(route.method) && route.method.length) {
      route.method.forEach(function (method) {
        router[method](generate(route.allows), authorize);
      });
    } else if (is.string(route.method)) {
      router[route.method](generate(route.allows), authorize);
    } else /* Defaults to all */ {
      router.all(generate(route.allows), authorize);
    }
  }

  /* Set authorization rules for each route */
  config.routes.forEach(onEachRoute);
}

module.exports = auth;
<|endoftext|>


<commit_before>/*jshint laxcomma:true, smarttabs: true */
/**
 * DESCRIPTION
 * @module NAME
 * @author
 * @requires command
 * @requires prime
 **/
var  command = require( './command' ) // this is command
   , prime = require( 'prime' ) // custom prime
   , isFunction = require("mout/lang/isFunction")
   , nopt = require('nopt')
   , domain = require("domain")
   , os = require("os")
   , fs = require("fs")
   , path = require("path")
   , abbrev = require("abbrev")
   , util = require("util")
   , chalk = require("chalk")
   , commands = require("./commands")
   , command_list
   , shorthands
   , parsed
   , clidomain
   , colors
   , help
   , commands;                         // The primary Class exports from the module

colors = ['red', 'blue','green', 'yellow','bold', 'grey', 'dim', 'black', 'magenta']
clidomain = domain.create()
clidomain.on('error', function(err, domn ){
  console.log( chalk.bold( util.format( "%s", err.name, err.message) ) )
  if( parsed && parsed.traceback ){
	console.log( chalk.red( err.stack ) )
  } else {
  	console.log('use --traceback for full stacktrace')
  }

  process.exit( 0 )
})

exports.use = commands.register;

Object.keys( commands ).forEach( function( key ){
	exports.use( key, commands[key])
})

// primary flags
opts = {
	"help":Boolean
	,version:Boolean
	,traceback: Boolean
};

// flag alias
shorthands = {
	'h':['--help']
	,'v':['--version']
};

exports.Command = command;
exports.Class = prime;
exports.list = commands.list
exports.commands = commands
colors.forEach( function( color ){
	exports[color] = chalk[color].bind( chalk )
})
exports.run = function( ){
	parsed = nopt( opts, shorthands );

	// pull out the first non-flag argument
	command = parsed.argv.remain.shift();
	// did the try to use the help command directly?
	help = !!parsed.help
	if( help || command == 'help' || command == null ){
		command = ( command == "help" || command == null ) ? parsed.argv.remain.shift() : command
		// allow for abbreviated commands
		return clidomain.run(function(){
			console.log( commands.help.run( command ) )
		});
	}

	if(commands.hasOwnProperty( command ) ) {
		return clidomain.run(function(){
		  commands[command].run(null)
		})
	}
	console.error('unknown command %s', command )
	console.log("know commands: %s ", Object.keys( commands ).join(', ') )
	process.exit(0);
}
<commit_msg>expose list from the top level cli<commit_after>/*jshint laxcomma:true, smarttabs: true */
/**
 * DESCRIPTION
 * @module NAME
 * @author
 * @requires command
 * @requires prime
 **/
var  command = require( './command' ) // this is command
   , prime = require( 'prime' ) // custom prime
   , isFunction = require("mout/lang/isFunction")
   , nopt = require('nopt')
   , domain = require("domain")
   , os = require("os")
   , fs = require("fs")
   , path = require("path")
   , abbrev = require("abbrev")
   , util = require("util")
   , chalk = require("chalk")
   , commands = require("./commands")
   , command_list
   , shorthands
   , parsed
   , clidomain
   , colors
   , help;                         // The primary Class exports from the module

colors = ['red', 'blue','green', 'yellow','bold', 'grey', 'dim', 'black', 'magenta']
clidomain = domain.create()
clidomain.on('error', function(err, domn ){
  console.log( chalk.red( util.format( "%s:", err.name) ), chalk.bold( err.message ) )
  if( parsed && parsed.traceback ){
	console.log( chalk.red( err.stack ) )
  } else {
  	console.log('use --traceback for full stacktrace')
  }

  return err.code ? process.exit( err.code ) : null;
})

exports.use = commands.register.bind( commands );
exports.remove = commands.unregister.bind( commands );

// primary flags
opts = {
	"help":Boolean
	,version:Boolean
	,traceback: Boolean
};

// flag alias
shorthands = {
	'h':['--help']
	,'v':['--version']
};

exports.Command = command;
exports.Class = prime;

Object.defineProperties( exports,{
	list:{
		get: function(){
			return Object.keys( commands )
		}
	}
});

exports.commands = commands
exports.reset = commands.reset.bind( commands );

colors.forEach( function( color ){
	exports[color] = chalk[color].bind( chalk )
})
exports.run = function( ){
	parsed = nopt( opts, shorthands );

	// pull out the first non-flag argument
	command = parsed.argv.remain.shift();
	// did the try to use the help command directly?
	help = !!parsed.help
	if( help || command == 'help' || command == null ){
		command = ( command == "help" || command == null ) ? parsed.argv.remain.shift() : command
		// allow for abbreviated commands
		return clidomain.run(function(){
			console.log( commands.help.run( command ) )
		});
	}

	if(commands.hasOwnProperty( command ) ) {
		return clidomain.run(function(){
		  commands[command].run(null)
		})
	}
	console.error('unknown command %s', command )
	console.log("know commands: %s ", Object.keys( commands ).join(', ') )
	process.exit(0);
}
<|endoftext|>


<commit_before>
/*!
 * Stylus - plugin - url
 * Copyright(c) 2010 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Compiler = require('../visitor/compiler')
  , nodes = require('../nodes')
  , parse = require('url').parse
  , extname = require('path').extname
  , utils = require('../utils')
  , fs = require('fs');

/**
 * Mime table.
 */

var mimes = {
    '.gif': 'image/gif'
  , '.png': 'image/png'
  , '.jpg': 'image/jpeg'
  , '.jpeg': 'image/jpeg'
  , '.svg': 'image/svg+xml'
  , '.ttf': 'application/x-font-ttf'
};

/**
 * Return a url() function with the given `options`.
 *
 * Options:
 *
 *    - `limit` bytesize limit defaulting to 30Kb
 *    - `paths` image resolution path(s), merged with general lookup paths
 *
 * Examples:
 *
 *    stylus(str)
 *      .set('filename', __dirname + '/css/test.styl')
 *      .define('url', stylus.url({ paths: [__dirname + '/public'] }))
 *      .render(function(err, css){ ... })
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

module.exports = function(options) {
  options = options || {};

  var _paths = options.paths || [];
  var sizeLimit = null != options.limit ? options.limit : 30000;

  function fn(url){
    // Compile the url
    var compiler = new Compiler(url);
    compiler.isURL = true;
    url = url.nodes.map(function(node){
      return compiler.visit(node);
    }).join('');

    // Parse literal
    url = parse(url);
    var ext = extname(url.pathname)
      , mime = mimes[ext]
      , literal = new nodes.Literal('url("' + url.href + '")')
      , paths = _paths.concat(this.paths)
      , buf;

    // Not supported
    if (!mime) return literal;

    // Absolute
    if (url.protocol) return literal;

    // Lookup
    var found = utils.lookup(url.pathname, paths);

    // Failed to lookup
    if (!found) return literal;

    // Read data
    buf = fs.readFileSync(found);

    // To large
    if (false !== sizeLimit && buf.length > sizeLimit) return literal;

    // Encode
    return new nodes.Literal('url("data:' + mime + ';base64,' + buf.toString('base64') + '")');
  };

  fn.raw = true;
  return fn;
};
<commit_msg>Add MIME of fonts in base64<commit_after>
/*!
 * Stylus - plugin - url
 * Copyright(c) 2010 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var Compiler = require('../visitor/compiler')
  , nodes = require('../nodes')
  , parse = require('url').parse
  , extname = require('path').extname
  , utils = require('../utils')
  , fs = require('fs');

/**
 * Mime table.
 */

var mimes = {
    '.gif': 'image/gif'
  , '.png': 'image/png'
  , '.jpg': 'image/jpeg'
  , '.jpeg': 'image/jpeg'
  , '.svg': 'image/svg+xml'
  , '.ttf': 'application/x-font-ttf'
  , '.eot': 'application/vnd.ms-fontobject'
  , '.woff': 'application/x-font-woff'
};

/**
 * Return a url() function with the given `options`.
 *
 * Options:
 *
 *    - `limit` bytesize limit defaulting to 30Kb
 *    - `paths` image resolution path(s), merged with general lookup paths
 *
 * Examples:
 *
 *    stylus(str)
 *      .set('filename', __dirname + '/css/test.styl')
 *      .define('url', stylus.url({ paths: [__dirname + '/public'] }))
 *      .render(function(err, css){ ... })
 *
 * @param {Object} options
 * @return {Function}
 * @api public
 */

module.exports = function(options) {
  options = options || {};

  var _paths = options.paths || [];
  var sizeLimit = null != options.limit ? options.limit : 30000;

  function fn(url){
    // Compile the url
    var compiler = new Compiler(url);
    compiler.isURL = true;
    url = url.nodes.map(function(node){
      return compiler.visit(node);
    }).join('');

    // Parse literal
    url = parse(url);
    var ext = extname(url.pathname)
      , mime = mimes[ext]
      , literal = new nodes.Literal('url("' + url.href + '")')
      , paths = _paths.concat(this.paths)
      , buf;

    // Not supported
    if (!mime) return literal;

    // Absolute
    if (url.protocol) return literal;

    // Lookup
    var found = utils.lookup(url.pathname, paths);

    // Failed to lookup
    if (!found) return literal;

    // Read data
    buf = fs.readFileSync(found);

    // To large
    if (false !== sizeLimit && buf.length > sizeLimit) return literal;

    // Encode
    return new nodes.Literal('url("data:' + mime + ';base64,' + buf.toString('base64') + '")');
  };

  fn.raw = true;
  return fn;
};
<|endoftext|>


<commit_before>import bemNamingFactory from 'bem-naming';

import {
    prepareClassName,
    isClassName,
    isDOMElement
} from './utils';

export default function(options) {
    // defaults options:
    // {
    //     elem: '_',
    //     mod: '__'
    //     wordPattern: '[a-z0-9]+(?:-[a-z0-9]+)*'
    // }
    const bemNaming = bemNamingFactory(options);

    return function(chai) {
        const { Assertion } = chai;
        const { typeOf, isTrue } = chai.assert;

        Assertion.addMethod('block', function(blockName) {
            const entity = this._obj;

            // check input
            isTrue(
                isClassName(entity) || isDOMElement(entity),
                `${entity} is neither a DOM element nor a className`
            );
            typeOf(blockName, 'string');

            // retrieve and prepare className
            const className = prepareClassName(entity);

            // check if there is at least one valid block
            isTrue(
                className.some(item => bemNaming.isBlock(item)),
                `there is no valid block in ${entity}`
            );

            // check block
            this.assert(
                className.indexOf(blockName) !== -1,
                'expected #{this} to be #{exp} block but got #{act}',
                'expected #{this} to not be #{exp} block but got #{act}',
                blockName,
                entity
            );
        });

        Assertion.addProperty('validBlock', function() {
            const entity = this._obj;

            // check input
            isTrue(
                isClassName(entity) || isDOMElement(entity),
                `${entity} is neither a DOM element nor a className`
            );

            // retrieve and prepare className
            const className = prepareClassName(entity);

            // check block
            this.assert(
                className.some(item => bemNaming.isBlock(item)),
                'expected #{this} to be a block but got #{act}',
                'expected #{this} to not be a block but got #{act}',
                entity,
                entity
            );
        });

        Assertion.addMethod('elem', function(bemjson) {
            const entity = this._obj;

            // check input
            isTrue(
                isClassName(entity) || isDOMElement(entity),
                `${entity} is neither a DOM element nor a className`
            );
            typeOf(bemjson, 'object');

            // retrieve and prepare className
            const className = prepareClassName(entity);

            // check if there is at least one valid element
            isTrue(
                className.some(item => bemNaming.isElem(item)),
                `there is no valid element in ${entity}`
            );

            // check element
            this.assert(
                className.some(item => {
                    const parsedItem = bemNaming.parse(item);

                    return (
                        parsedItem.block === bemjson.block &&
                        parsedItem.elem === bemjson.elem
                    );
                }),
                'expected #{this} to be an elem #{exp} but got #{act}',
                'expected #{this} to not be an elem of #{exp} block, but got #{act}',
                bemjson,
                entity
            );
        });

        Assertion.addProperty('validElem', function() {
            const entity = this._obj;

            // check input
            isTrue(
                isClassName(entity) || isDOMElement(entity),
                `${entity} is neither a DOM element nor a className`
            );

            // retrieve and prepare className
            const className = prepareClassName(entity);

            // check block
            this.assert(
                className.some(item => bemNaming.isElem(item)),
                'expected #{this} to be an element but got #{act}',
                'expected #{this} to not be an element but got #{act}',
                entity,
                entity
            );
        });

        Assertion.addMethod('mods', function(bemjson) {
            const entity = this._obj;

            // check input
            isTrue(
                isClassName(entity) || isDOMElement(entity),
                `${entity} is neither a DOM element nor a className`
            );
            typeOf(bemjson, 'object');

            // retrieve and prepare className
            const className = prepareClassName(entity);

            const mods = Object.keys(bemjson);
            const modWord = 'modificator' + (mods.length === 1 ? '' : 's');

            // check mods
            this.assert(
                mods.every(modName => {
                    // parsing to string to handle boolean and numeric mod values
                    const modVal = String(bemjson[modName]);

                    return className.some(item => {
                        // ignore if no mods
                        if (!bemNaming.isBlockMod(item) && !bemNaming.isElemMod(item)) {
                            return false;
                        }

                        const parsedItem = bemNaming.parse(item);

                        return (
                            parsedItem.modName === modName &&
                            String(parsedItem.modVal) === modVal
                        );
                    });
                }),
                `expected #{this} to have #{exp} ${modWord}`,
                `expected #{this} to not have #{exp} ${modWord}`,
                bemjson,
                entity
            );
        });
    };
}
<commit_msg>:wrench: elem assertion minor refactoring<commit_after>import bemNamingFactory from 'bem-naming';

import {
    prepareClassName,
    isClassName,
    isDOMElement
} from './utils';

export default function(options) {
    // defaults options:
    // {
    //     elem: '_',
    //     mod: '__'
    //     wordPattern: '[a-z0-9]+(?:-[a-z0-9]+)*'
    // }
    const bemNaming = bemNamingFactory(options);

    return function(chai) {
        const { Assertion } = chai;
        const { typeOf, isTrue } = chai.assert;

        Assertion.addMethod('block', function(blockName) {
            const entity = this._obj;

            // check input
            isTrue(
                isClassName(entity) || isDOMElement(entity),
                `${entity} is neither a DOM element nor a className`
            );
            typeOf(blockName, 'string');

            // retrieve and prepare className
            const className = prepareClassName(entity);

            // check if there is at least one valid block
            isTrue(
                className.some(item => bemNaming.isBlock(item)),
                `there is no valid block in ${entity}`
            );

            // check block
            this.assert(
                className.indexOf(blockName) !== -1,
                'expected #{this} to be #{exp} block but got #{act}',
                'expected #{this} to not be #{exp} block but got #{act}',
                blockName,
                entity
            );
        });

        Assertion.addProperty('validBlock', function() {
            const entity = this._obj;

            // check input
            isTrue(
                isClassName(entity) || isDOMElement(entity),
                `${entity} is neither a DOM element nor a className`
            );

            // retrieve and prepare className
            const className = prepareClassName(entity);

            // check block
            this.assert(
                className.some(item => bemNaming.isBlock(item)),
                'expected #{this} to be a block but got #{act}',
                'expected #{this} to not be a block but got #{act}',
                entity,
                entity
            );
        });

        Assertion.addMethod('elem', function(bemjson) {
            const entity = this._obj;

            // check input
            isTrue(
                isClassName(entity) || isDOMElement(entity),
                `${entity} is neither a DOM element nor a className`
            );
            typeOf(bemjson, 'object');

            // retrieve and prepare className
            const className = prepareClassName(entity);

            // check element
            this.assert(
                className.some(item => {
                    // ignore if not element
                    if (!bemNaming.isElem(item)) {
                        return false;
                    }

                    const parsedItem = bemNaming.parse(item);

                    return (
                        parsedItem.block === bemjson.block &&
                        parsedItem.elem === bemjson.elem
                    );
                }),
                'expected #{this} to be an elem #{exp} but got #{act}',
                'expected #{this} to not be an elem of #{exp} block, but got #{act}',
                bemjson,
                entity
            );
        });

        Assertion.addProperty('validElem', function() {
            const entity = this._obj;

            // check input
            isTrue(
                isClassName(entity) || isDOMElement(entity),
                `${entity} is neither a DOM element nor a className`
            );

            // retrieve and prepare className
            const className = prepareClassName(entity);

            // check block
            this.assert(
                className.some(item => bemNaming.isElem(item)),
                'expected #{this} to be an element but got #{act}',
                'expected #{this} to not be an element but got #{act}',
                entity,
                entity
            );
        });

        Assertion.addMethod('mods', function(bemjson) {
            const entity = this._obj;

            // check input
            isTrue(
                isClassName(entity) || isDOMElement(entity),
                `${entity} is neither a DOM element nor a className`
            );
            typeOf(bemjson, 'object');

            // retrieve and prepare className
            const className = prepareClassName(entity);

            const mods = Object.keys(bemjson);
            const modWord = 'modificator' + (mods.length === 1 ? '' : 's');

            // check mods
            this.assert(
                mods.every(modName => {
                    // parsing to string to handle boolean and numeric mod values
                    const modVal = String(bemjson[modName]);

                    return className.some(item => {
                        // ignore if no mods
                        if (!bemNaming.isBlockMod(item) && !bemNaming.isElemMod(item)) {
                            return false;
                        }

                        const parsedItem = bemNaming.parse(item);

                        return (
                            parsedItem.modName === modName &&
                            String(parsedItem.modVal) === modVal
                        );
                    });
                }),
                `expected #{this} to have #{exp} ${modWord}`,
                `expected #{this} to not have #{exp} ${modWord}`,
                bemjson,
                entity
            );
        });
    };
}
<|endoftext|>


<commit_before>var reverb = new Tone.Freeverb(0.2, 0.1);
reverb.wet.value = 0.1;

var shaker = new Tone.Sampler({
    "cabasa": "./samples/shaker/cabasa.mp3",
    "caxixi": "./samples/shaker/caxixi.mp3",
    "maracas": "./samples/shaker/maracas.mp3",
    "shaker": "./samples/shaker/shaker.mp3"
}).chain(reverb, Tone.Master);

var guitar = new Tone.Sampler({
    "1": "./samples/guitar/1.mp3",
    "2": "./samples/guitar/2.mp3",
    "3": "./samples/guitar/3.mp3"
}).chain(reverb, Tone.Master);

var cowbell = new Tone.Sampler({
    "hi": "./samples/cowbell/hi.mp3",
    "med-hi": "./samples/cowbell/med-hi.mp3",
    "med": "./samples/cowbell/med.mp3",
    "low": "./samples/cowbell/low.mp3"
}).chain(reverb, Tone.Master);

var cat = new Tone.Sampler({
    "1": "./samples/cat/meow1.mp3",
    "2": "./samples/cat/meow2.mp3",
    "3": "./samples/cat/hiss.mp3",
    "4": "./samples/cat/meow3.mp3",
    "5": "./samples/cat/meow4.mp3",
    "6": "./samples/cat/purr.mp3",
    "7": "./samples/cat/meow5.mp3",
    "8": "./samples/cat/meow6.mp3"
}).toMaster();
cat.volume.value = -12;

var tambourine = new Tone.Sampler({
    "finger": "./samples/tambourine/finger.mp3",
    "roll": "./samples/tambourine/roll.mp3",
    "shake": "./samples/tambourine/shake.mp3",
    "slap": "./samples/tambourine/slap.mp3"
}).chain(reverb, Tone.Master);

var activeInst = 'shaker';

$("input[name=instrument]:radio").change(function(data) {
    tambourine.triggerAttack();
    activeInst = data.target.id;
});

window.addEventListener('devicemotion', deviceMotionHandler);

var lastTime = Date.now();

function deviceMotionHandler(event) {
    var x = event.acceleration.x;
    var y = event.acceleration.y;
    var z = event.acceleration.z;
    var changeTest = changeDirection(x);

    //console.log(changeTest + " and time " + (Date.now() - lastTime));
    console.log(x + " and time " + (Date.now() - lastTime));
    //playShaker(x);
    var diff = Math.abs(x);
    //if (Math.abs(x) > threshold) {
    switch (activeInst) {
        case 'guitar':
            playGuitar(diff);
            break;
        case 'cowbell':
            playCowbell(diff);
            break;
        case 'shakers':
            playShaker(diff);
            break;
        case 'cat':
            playCat(diff);
            break;
        case 'tambourine':
            playTambourine(diff);
            break;
    }
    // }

    lastTime = Date.now();
}

var threshold = 20;

var lastMove = Date.now();

var mousePos = 'ul';

playShaker = function(diff) {
    if (Math.abs(diff) > threshold && Date.now() - lastMove > 150) {
        var vel = map(Math.abs(diff), 10, 100, 0, 1);
        //console.log("velocity = " + vel + " and diff = " + diff);
        if (diff > 0) {
            shaker.triggerRelease("cabasa");
            shaker.pitch = 0;
            shaker.triggerAttack("cabasa", 0, vel);
        };
        if (diff < 0) {
            shaker.triggerRelease("cabasa");
            shaker.pitch = -4;
            shaker.triggerAttack("cabasa", 0, vel);
        };
        // switch (mousePos) {
        //     case 'ul':
        //         shaker.triggerAttack("cabasa", 0, 1);
        //         break;
        //     case 'ur':
        //         shaker.triggerAttack("caxixi", 0, 1);
        //         break;
        //     case 'll':
        //         shaker.triggerAttack("maracas", 0, 1);
        //         break;
        //     case 'lr':
        //         shaker.triggerAttack("shaker", 0, 1);
        //         break;
        // }

        lastMove = Date.now();
    }
    lastVal = diff;
}

var guitarCount = 1;
playGuitar = function(diff) {
    if (diff > threshold && Date.now() - lastMove > 150) {

        if (guitarCount > 3) {
            guitarCount = 1;
        }
        guitar.triggerAttack(guitarCount);
        guitarCount++;

        lastMove = Date.now();
    }
    lastVal = diff;
}

var triggerSpace = 150;

playTambourine = function(diff) {
    if (diff > threshold && Date.now() - lastMove > triggerSpace) {
        switch (mousePos) {
            case 'ul':
                tambourine.triggerAttack("finger", 0, 1);
                break;
            case 'ur':
                tambourine.triggerAttack("roll", 0, 1);
                break;
            case 'll':
                tambourine.triggerAttack("shake", 0, 1);
                break;
            case 'lr':
                tambourine.triggerAttack("slap", 0, 1);
                break;
        }

        lastMove = Date.now();
    }
    lastVal = diff;
}

playCowbell = function(diff) {
    if (diff > threshold && Date.now() - lastMove > 150) {
        switch (mousePos) {
            case 'ul':
                cowbell.triggerAttack("hi", 0, 1);
                break;
            case 'ur':
                cowbell.triggerAttack("med-hi", 0, 1);
                break;
            case 'll':
                cowbell.triggerAttack("med", 0, 1);
                break;
            case 'lr':
                cowbell.triggerAttack("low", 0, 1);
                break;
        }

        lastMove = Date.now();
    }
    lastVal = diff;
}

var triggerTimeout = 200;
var catCount = 1;
playCat = function(diff) {
    if (diff > threshold && Date.now() - lastMove > triggerTimeout) {

        if (catCount > 8) {
            catCount = 1;
        }
        cat.triggerAttack(catCount);
        catCount++;

        lastMove = Date.now();
    }
    lastVal = diff;
}

map = function(n, start1, stop1, start2, stop2) {
    return ((n - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
};

var lastXVal;
var shakeDir;
changeDirection = function(val) {
    var lastDir = shakeDir;
    if (val - lastXVal > 4) {
        shakeDir = 'forward';
    } else if (val - lastXVal < 4) {
        shakeDir = 'backward';
    }
    var returnVal = lastXVal;
    lastXVal = val;
    if (shakeDir != lastDir) {
        return returnVal - val;
    } else {
        return false;
    }
}
<commit_msg>testing<commit_after>var reverb = new Tone.Freeverb(0.2, 0.1);
reverb.wet.value = 0.1;

var shaker = new Tone.Sampler({
    "cabasa": "./samples/shaker/cabasa.mp3",
    "caxixi": "./samples/shaker/caxixi.mp3",
    "maracas": "./samples/shaker/maracas.mp3",
    "shaker": "./samples/shaker/shaker.mp3"
}).chain(reverb, Tone.Master);

var guitar = new Tone.Sampler({
    "1": "./samples/guitar/1.mp3",
    "2": "./samples/guitar/2.mp3",
    "3": "./samples/guitar/3.mp3"
}).chain(reverb, Tone.Master);

var cowbell = new Tone.Sampler({
    "hi": "./samples/cowbell/hi.mp3",
    "med-hi": "./samples/cowbell/med-hi.mp3",
    "med": "./samples/cowbell/med.mp3",
    "low": "./samples/cowbell/low.mp3"
}).chain(reverb, Tone.Master);

var cat = new Tone.Sampler({
    "1": "./samples/cat/meow1.mp3",
    "2": "./samples/cat/meow2.mp3",
    "3": "./samples/cat/hiss.mp3",
    "4": "./samples/cat/meow3.mp3",
    "5": "./samples/cat/meow4.mp3",
    "6": "./samples/cat/purr.mp3",
    "7": "./samples/cat/meow5.mp3",
    "8": "./samples/cat/meow6.mp3"
}).toMaster();
cat.volume.value = -12;

var tambourine = new Tone.Sampler({
    "finger": "./samples/tambourine/finger.mp3",
    "roll": "./samples/tambourine/roll.mp3",
    "shake": "./samples/tambourine/shake.mp3",
    "slap": "./samples/tambourine/slap.mp3"
}).chain(reverb, Tone.Master);

var activeInst = 'shaker';

$("input[name=instrument]:radio").change(function(data) {
    tambourine.triggerAttack("finger");
    activeInst = data.target.id;
});

window.addEventListener('devicemotion', deviceMotionHandler);

var lastTime = Date.now();

function deviceMotionHandler(event) {
    var x = event.acceleration.x;
    var y = event.acceleration.y;
    var z = event.acceleration.z;
    var changeTest = changeDirection(x);

    //console.log(changeTest + " and time " + (Date.now() - lastTime));
    console.log(x + " and time " + (Date.now() - lastTime));
    //playShaker(x);
    var diff = Math.abs(x);
    //if (Math.abs(x) > threshold) {
    switch (activeInst) {
        case 'guitar':
            playGuitar(diff);
            break;
        case 'cowbell':
            playCowbell(diff);
            break;
        case 'shakers':
            playShaker(diff);
            break;
        case 'cat':
            playCat(diff);
            break;
        case 'tambourine':
            playTambourine(diff);
            break;
    }
    // }

    lastTime = Date.now();
}

var threshold = 20;

var lastMove = Date.now();

var mousePos = 'ul';

playShaker = function(diff) {
    if (Math.abs(diff) > threshold && Date.now() - lastMove > 150) {
        var vel = map(Math.abs(diff), 10, 100, 0, 1);
        //console.log("velocity = " + vel + " and diff = " + diff);
        if (diff > 0) {
            shaker.triggerRelease("cabasa");
            shaker.pitch = 0;
            shaker.triggerAttack("cabasa", 0, vel);
        };
        if (diff < 0) {
            shaker.triggerRelease("cabasa");
            shaker.pitch = -4;
            shaker.triggerAttack("cabasa", 0, vel);
        };
        // switch (mousePos) {
        //     case 'ul':
        //         shaker.triggerAttack("cabasa", 0, 1);
        //         break;
        //     case 'ur':
        //         shaker.triggerAttack("caxixi", 0, 1);
        //         break;
        //     case 'll':
        //         shaker.triggerAttack("maracas", 0, 1);
        //         break;
        //     case 'lr':
        //         shaker.triggerAttack("shaker", 0, 1);
        //         break;
        // }

        lastMove = Date.now();
    }
    lastVal = diff;
}

var guitarCount = 1;
playGuitar = function(diff) {
    if (diff > threshold && Date.now() - lastMove > 150) {

        if (guitarCount > 3) {
            guitarCount = 1;
        }
        guitar.triggerAttack(guitarCount);
        guitarCount++;

        lastMove = Date.now();
    }
    lastVal = diff;
}

var triggerSpace = 150;

playTambourine = function(diff) {
    if (diff > threshold && Date.now() - lastMove > triggerSpace) {
        switch (mousePos) {
            case 'ul':
                tambourine.triggerAttack("finger", 0, 1);
                break;
            case 'ur':
                tambourine.triggerAttack("roll", 0, 1);
                break;
            case 'll':
                tambourine.triggerAttack("shake", 0, 1);
                break;
            case 'lr':
                tambourine.triggerAttack("slap", 0, 1);
                break;
        }

        lastMove = Date.now();
    }
    lastVal = diff;
}

playCowbell = function(diff) {
    if (diff > threshold && Date.now() - lastMove > 150) {
        switch (mousePos) {
            case 'ul':
                cowbell.triggerAttack("hi", 0, 1);
                break;
            case 'ur':
                cowbell.triggerAttack("med-hi", 0, 1);
                break;
            case 'll':
                cowbell.triggerAttack("med", 0, 1);
                break;
            case 'lr':
                cowbell.triggerAttack("low", 0, 1);
                break;
        }

        lastMove = Date.now();
    }
    lastVal = diff;
}

var triggerTimeout = 200;
var catCount = 1;
playCat = function(diff) {
    if (diff > threshold && Date.now() - lastMove > triggerTimeout) {

        if (catCount > 8) {
            catCount = 1;
        }
        cat.triggerAttack(catCount);
        catCount++;

        lastMove = Date.now();
    }
    lastVal = diff;
}

map = function(n, start1, stop1, start2, stop2) {
    return ((n - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
};

var lastXVal;
var shakeDir;
changeDirection = function(val) {
    var lastDir = shakeDir;
    if (val - lastXVal > 4) {
        shakeDir = 'forward';
    } else if (val - lastXVal < 4) {
        shakeDir = 'backward';
    }
    var returnVal = lastXVal;
    lastXVal = val;
    if (shakeDir != lastDir) {
        return returnVal - val;
    } else {
        return false;
    }
}
<|endoftext|>