<commit_before>
escambo = {

};

escambo.scroll = function (crop, attr, multiplier, unitSize) {
  if (crop.is(':animated'))
    return;
  params = {}; params[attr] = parseInt(crop.css(attr)) + Math.floor(multiplier)*unitSize;
  crop.animate(params);
};

escambo.home = {
};

escambo.home.enterprises = {

  area: function () {
    return jQuery('#enterprises-area');
  },
  crop: function () {
    return jQuery('#enterprises-crop');
  },
  children: function () {
    return jQuery('.escambo-plugin-profile-block');
  },
  childrenFit: function () {
    return Math.floor(this.area().width() / this.childSize());
  },
  childSize: function () {
    return this.children().outerWidth(true);
  },

  scroll: function (multiplier) {
    escambo.scroll(this.crop(), 'margin-left', multiplier, this.childSize());
  },
  scrollLeft: function () {
    self = escambo.home.enterprises;
    if (self.area().isChildOverflowing(self.children().first()))
      escambo.home.enterprises.scroll(1);
  },
  scrollRight: function () {
    self = escambo.home.enterprises;
    if (self.area().isChildOverflowing(self.children().last()))
      escambo.home.enterprises.scroll(-1);
  },
  scrollMiddle: function () {
    escambo.home.enterprises.scroll(-(this.children().length - this.childrenFit()) / 2);
  },
};

escambo.search = {

  load: function() {
    this.input = jQuery();
    this.getResults = function(data) {};
    this.query = null;
    this.last_query = null;
    this.query_url = null;
    this.typing = false;
    this.pending = false;
    this.timeout = 200;
  },

  do: function (input, url, getResults) {
    this.input = jQuery(input);
    this.typing = true;
    this.query = input.value;
    this.query_url = url;
    this.getResults = getResults;
    setTimeout(this.expire, this.timeout);
  },

  start: function () {
    if (!this.query || (this.last_query && this.query == this.last_query))
      return;
    this.pending = false;
    this.typing = false;
    this.last_query = this.query;
    this.pending = true;
    this.input.addClass('loading');
    this.getResults();
  },
  finish: function () {
    this.pending = false;
    this.input.removeClass('loading');
  },

  expire: function () {
    escambo.search.start();
  },
};
escambo.search.load();

escambo.signup = {

  load: function (empty_selection_message) {
    var form = jQuery('#signup-form');
    form.submit(function (e) {
      e.preventDefault();
      if (form.find('input[name=enterprise_register]').val() == 'true')
        this.submit();
      else if (!escambo.signup.enterprise.hasSelection())
        alert(empty_selection_message);
    });
  },

  enterprise: {

    find: function() {
      jQuery('#enterprise-register, #enterprise-find').toggle();
      jQuery('#enterprise-register-field').val(jQuery('#enterprise-register').is(':visible'));
    },
    register: function() {
      this.find();
    },

    hasSelection: function () {
      find = jQuery('#enterprise-find');
      return (find.is(':visible') &&
          find.find("input[name='enterprise_id']").is(':checked'));
    },

    search: function () {
      jQuery.get(escambo.search.query_url, {query: escambo.search.query}, function (data) {
        jQuery('#enterprise-results').html(data);
        escambo.search.finish();
      });
    },
  },
}

jQuery(document).ready(function () {
  jQuery('.scroll-left').click(escambo.home.enterprises.scrollLeft);
  jQuery('.scroll-right').click(escambo.home.enterprises.scrollRight);
  escambo.home.enterprises.scrollMiddle();
});

jQuery.fn.isChildOverflowing = function (child) {
  var p = jQuery(this).get(0);
  var el = jQuery(child).get(0);
  return (el.offsetTop < p.offsetTop || el.offsetLeft < p.offsetLeft) ||
    (el.offsetTop + el.offsetHeight > p.offsetTop + p.offsetHeight || el.offsetLeft + el.offsetWidth > p.offsetLeft + p.offsetWidth);
};

<commit_msg>Fix register enterprise check<commit_after>
escambo = {

};

escambo.scroll = function (crop, attr, multiplier, unitSize) {
  if (crop.is(':animated'))
    return;
  params = {}; params[attr] = parseInt(crop.css(attr)) + Math.floor(multiplier)*unitSize;
  crop.animate(params);
};

escambo.home = {
};

escambo.home.enterprises = {

  area: function () {
    return jQuery('#enterprises-area');
  },
  crop: function () {
    return jQuery('#enterprises-crop');
  },
  children: function () {
    return jQuery('.escambo-plugin-profile-block');
  },
  childrenFit: function () {
    return Math.floor(this.area().width() / this.childSize());
  },
  childSize: function () {
    return this.children().outerWidth(true);
  },

  scroll: function (multiplier) {
    escambo.scroll(this.crop(), 'margin-left', multiplier, this.childSize());
  },
  scrollLeft: function () {
    self = escambo.home.enterprises;
    if (self.area().isChildOverflowing(self.children().first()))
      escambo.home.enterprises.scroll(1);
  },
  scrollRight: function () {
    self = escambo.home.enterprises;
    if (self.area().isChildOverflowing(self.children().last()))
      escambo.home.enterprises.scroll(-1);
  },
  scrollMiddle: function () {
    escambo.home.enterprises.scroll(-(this.children().length - this.childrenFit()) / 2);
  },
};

escambo.search = {

  load: function() {
    this.input = jQuery();
    this.getResults = function(data) {};
    this.query = null;
    this.last_query = null;
    this.query_url = null;
    this.typing = false;
    this.pending = false;
    this.timeout = 200;
  },

  do: function (input, url, getResults) {
    this.input = jQuery(input);
    this.typing = true;
    this.query = input.value;
    this.query_url = url;
    this.getResults = getResults;
    setTimeout(this.expire, this.timeout);
  },

  start: function () {
    if (!this.query || (this.last_query && this.query == this.last_query))
      return;
    this.pending = false;
    this.typing = false;
    this.last_query = this.query;
    this.pending = true;
    this.input.addClass('loading');
    this.getResults();
  },
  finish: function () {
    this.pending = false;
    this.input.removeClass('loading');
  },

  expire: function () {
    escambo.search.start();
  },
};
escambo.search.load();

escambo.signup = {

  load: function (empty_selection_message) {
    var form = jQuery('#signup-form');
    form.submit(function (e) {
      e.preventDefault();
      if (form.find('input[name=enterprise_register]').val() == 'true' || escambo.signup.enterprise.hasSelection())
        this.submit();
      else
        alert(empty_selection_message);
    });
  },

  enterprise: {

    find: function() {
      jQuery('#enterprise-register, #enterprise-find').toggle();
      jQuery('#enterprise-register-field').val(jQuery('#enterprise-register').is(':visible'));
    },
    register: function() {
      this.find();
    },

    hasSelection: function () {
      find = jQuery('#enterprise-find');
      return (find.is(':visible') &&
          find.find("input[name='enterprise_id']").is(':checked'));
    },

    search: function () {
      jQuery.get(escambo.search.query_url, {query: escambo.search.query}, function (data) {
        jQuery('#enterprise-results').html(data);
        escambo.search.finish();
      });
    },
  },
}

jQuery(document).ready(function () {
  jQuery('.scroll-left').click(escambo.home.enterprises.scrollLeft);
  jQuery('.scroll-right').click(escambo.home.enterprises.scrollRight);
  escambo.home.enterprises.scrollMiddle();
});

jQuery.fn.isChildOverflowing = function (child) {
  var p = jQuery(this).get(0);
  var el = jQuery(child).get(0);
  return (el.offsetTop < p.offsetTop || el.offsetLeft < p.offsetLeft) ||
    (el.offsetTop + el.offsetHeight > p.offsetTop + p.offsetHeight || el.offsetLeft + el.offsetWidth > p.offsetLeft + p.offsetWidth);
};

<|endoftext|>


<commit_before>/* eslint no-underscore-dangle: 0 */

import isPlainObject from 'is-plain-object';
import { logger } from '@storybook/client-logger';
import addons from '@storybook/addons';
import Events from '@storybook/core-events';
import { toId } from '@storybook/router/utils';

import mergeWith from 'lodash/mergeWith';
import isEqual from 'lodash/isEqual';

import subscriptionsStore from './subscriptions_store';

// merge with concatenating arrays, but no duplicates
const merge = (a, b) =>
  mergeWith({}, a, b, (objValue, srcValue) => {
    if (Array.isArray(srcValue) && Array.isArray(objValue)) {
      srcValue.forEach(s => {
        const existing = objValue.find(o => o === s || isEqual(o, s));
        if (!existing) {
          objValue.push(s);
        }
      });

      return objValue;
    }
    if (Array.isArray(objValue)) {
      logger.log('the types mismatch, picking', objValue);
      return objValue;
    }
    return undefined;
  });

export const defaultDecorateStory = (storyFn, decorators) =>
  decorators.reduce(
    (decorated, decorator) => (context = {}) =>
      decorator(
        (p = {}) =>
          decorated(
            // MUTATION !
            Object.assign(
              context,
              p,
              { parameters: Object.assign(context.parameters || {}, p.parameters) },
              { options: Object.assign(context.options || {}, p.options) }
            )
          ),
        context
      ),
    storyFn
  );

const metaSubscription = () => {
  addons.getChannel().on(Events.REGISTER_SUBSCRIPTION, subscriptionsStore.register);
  return () =>
    addons.getChannel().removeListener(Events.REGISTER_SUBSCRIPTION, subscriptionsStore.register);
};

const withSubscriptionTracking = storyFn => {
  if (!addons.hasChannel()) {
    return storyFn();
  }
  subscriptionsStore.markAllAsUnused();
  subscriptionsStore.register(metaSubscription);
  const result = storyFn();
  subscriptionsStore.clearUnused();
  return result;
};

export default class ClientApi {
  constructor({ storyStore, decorateStory = defaultDecorateStory } = {}) {
    this._storyStore = storyStore;
    this._addons = {};
    this._globalDecorators = [];
    this._globalParameters = {};
    this._decorateStory = decorateStory;

    if (!storyStore) {
      throw new Error('storyStore is required');
    }
  }

  setAddon = addon => {
    this._addons = {
      ...this._addons,
      ...addon,
    };
  };

  getSeparators = () =>
    Object.assign(
      {},
      {
        hierarchyRootSeparator: '|',
        hierarchySeparator: /\/|\./,
      },
      this._globalParameters.options
    );

  addDecorator = decorator => {
    this._globalDecorators.push(decorator);
  };

  addParameters = parameters => {
    Object.assign(this._globalParameters, parameters);
  };

  clearDecorators = () => {
    this._globalDecorators = [];
  };

  storiesOf = (kind, m) => {
    if (!kind && typeof kind !== 'string') {
      throw new Error('Invalid or missing kind provided for stories, should be a string');
    }

    if (!m) {
      logger.warn(
        `Missing 'module' parameter for story with a kind of '${kind}'. It will break your HMR`
      );
    }

    if (m && m.hot && m.hot.dispose) {
      m.hot.dispose(() => {
        const { _storyStore } = this;
        _storyStore.remove();

        // TODO: refactor this
        // Maybe not needed at all if stories can just be overwriten ?
        this._storyStore.removeStoryKind(kind);
        this._storyStore.incrementRevision();
      });
    }

    const localDecorators = [];
    let localParameters = {};
    let hasAdded = false;
    const api = {
      kind,
    };

    // apply addons
    Object.keys(this._addons).forEach(name => {
      const addon = this._addons[name];
      api[name] = (...args) => {
        addon.apply(api, args);
        return api;
      };
    });

    api.add = (storyName, storyFn, parameters) => {
      hasAdded = true;
      const { _globalParameters, _globalDecorators } = this;
      const id = toId(kind, storyName);

      if (typeof storyName !== 'string') {
        throw new Error(`Invalid or missing storyName provided for a "${kind}" story.`);
      }
      if (m && m.hot && m.hot.dispose) {
        m.hot.dispose(() => {
          const { _storyStore } = this;
          _storyStore.remove(id);
        });
      }

      const fileName = m && m.id ? `${m.id}` : undefined;

      const { hierarchyRootSeparator, hierarchySeparator } = this.getSeparators();
      const baseOptions = {
        hierarchyRootSeparator,
        hierarchySeparator,
      };
      const allParam = [
        { options: baseOptions },
        _globalParameters,
        localParameters,
        parameters,
      ].reduce(
        (acc, p) => {
          if (p) {
            Object.entries(p).forEach(([key, value]) => {
              const existingValue = acc[key];

              if (Array.isArray(value)) {
                acc[key] = value;
              } else if (isPlainObject(value) && isPlainObject(existingValue)) {
                acc[key] = merge(existingValue, value);
              } else {
                acc[key] = value;
              }
            });
          }
          return acc;
        },
        { fileName }
      );

      this._storyStore.addStory(
        {
          id,
          kind,
          name: storyName,
          storyFn,
          parameters: allParam,
        },
        {
          applyDecorators: this._decorateStory,
          getDecorators: () => [
            ...(allParam.decorators || []),
            ...localDecorators,
            ..._globalDecorators,
            withSubscriptionTracking,
          ],
        }
      );
      return api;
    };

    api.addDecorator = decorator => {
      if (hasAdded) {
        logger.warn(`You have added a decorator to the kind '${kind}' after a story has already been added.
In Storybook 4 this applied the decorator only to subsequent stories. In Storybook 5+ it applies to all stories.
This is probably not what you intended. Read more here: https://github.com/storybooks/storybook/blob/master/MIGRATION.md`);
      }

      localDecorators.push(decorator);
      return api;
    };

    api.addParameters = parameters => {
      localParameters = { ...localParameters, ...parameters };
      return api;
    };

    return api;
  };

  // legacy
  getStorybook = () =>
    this._storyStore.getStoryKinds().map(kind => {
      const fileName = this._storyStore.getStoryFileName(kind);

      const stories = this._storyStore.getStories(kind).map(name => {
        const render = this._storyStore.getStoryWithContext(kind, name);
        return { name, render };
      });

      return { kind, fileName, stories };
    });

  raw = () => this._storyStore.raw();

  // FIXME: temporary expose the store for react-native
  // Longer term react-native should use the Provider/Consumer api
  store = () => this._storyStore;
}
<commit_msg>deep merge options property when adding global parameters<commit_after>/* eslint no-underscore-dangle: 0 */

import isPlainObject from 'is-plain-object';
import { logger } from '@storybook/client-logger';
import addons from '@storybook/addons';
import Events from '@storybook/core-events';
import { toId } from '@storybook/router/utils';

import mergeWith from 'lodash/mergeWith';
import isEqual from 'lodash/isEqual';
import get from 'lodash/get';

import subscriptionsStore from './subscriptions_store';

// merge with concatenating arrays, but no duplicates
const merge = (a, b) =>
  mergeWith({}, a, b, (objValue, srcValue) => {
    if (Array.isArray(srcValue) && Array.isArray(objValue)) {
      srcValue.forEach(s => {
        const existing = objValue.find(o => o === s || isEqual(o, s));
        if (!existing) {
          objValue.push(s);
        }
      });

      return objValue;
    }
    if (Array.isArray(objValue)) {
      logger.log('the types mismatch, picking', objValue);
      return objValue;
    }
    return undefined;
  });

export const defaultDecorateStory = (storyFn, decorators) =>
  decorators.reduce(
    (decorated, decorator) => (context = {}) =>
      decorator(
        (p = {}) =>
          decorated(
            // MUTATION !
            Object.assign(
              context,
              p,
              { parameters: Object.assign(context.parameters || {}, p.parameters) },
              { options: Object.assign(context.options || {}, p.options) }
            )
          ),
        context
      ),
    storyFn
  );

const metaSubscription = () => {
  addons.getChannel().on(Events.REGISTER_SUBSCRIPTION, subscriptionsStore.register);
  return () =>
    addons.getChannel().removeListener(Events.REGISTER_SUBSCRIPTION, subscriptionsStore.register);
};

const withSubscriptionTracking = storyFn => {
  if (!addons.hasChannel()) {
    return storyFn();
  }
  subscriptionsStore.markAllAsUnused();
  subscriptionsStore.register(metaSubscription);
  const result = storyFn();
  subscriptionsStore.clearUnused();
  return result;
};

export default class ClientApi {
  constructor({ storyStore, decorateStory = defaultDecorateStory } = {}) {
    this._storyStore = storyStore;
    this._addons = {};
    this._globalDecorators = [];
    this._globalParameters = {};
    this._decorateStory = decorateStory;

    if (!storyStore) {
      throw new Error('storyStore is required');
    }
  }

  setAddon = addon => {
    this._addons = {
      ...this._addons,
      ...addon,
    };
  };

  getSeparators = () =>
    Object.assign(
      {},
      {
        hierarchyRootSeparator: '|',
        hierarchySeparator: /\/|\./,
      },
      this._globalParameters.options
    );

  addDecorator = decorator => {
    this._globalDecorators.push(decorator);
  };

  addParameters = parameters => {
    Object.assign(this._globalParameters, {
      ...this._globalParameters,
      ...parameters,
      options: {
        ...merge(get(this._globalParameters, 'options', {}), get(parameters, 'options', {})),
      },
    });
  };

  clearDecorators = () => {
    this._globalDecorators = [];
  };

  storiesOf = (kind, m) => {
    if (!kind && typeof kind !== 'string') {
      throw new Error('Invalid or missing kind provided for stories, should be a string');
    }

    if (!m) {
      logger.warn(
        `Missing 'module' parameter for story with a kind of '${kind}'. It will break your HMR`
      );
    }

    if (m && m.hot && m.hot.dispose) {
      m.hot.dispose(() => {
        const { _storyStore } = this;
        _storyStore.remove();

        // TODO: refactor this
        // Maybe not needed at all if stories can just be overwriten ?
        this._storyStore.removeStoryKind(kind);
        this._storyStore.incrementRevision();
      });
    }

    const localDecorators = [];
    let localParameters = {};
    let hasAdded = false;
    const api = {
      kind,
    };

    // apply addons
    Object.keys(this._addons).forEach(name => {
      const addon = this._addons[name];
      api[name] = (...args) => {
        addon.apply(api, args);
        return api;
      };
    });

    api.add = (storyName, storyFn, parameters) => {
      hasAdded = true;
      const { _globalParameters, _globalDecorators } = this;
      const id = toId(kind, storyName);

      if (typeof storyName !== 'string') {
        throw new Error(`Invalid or missing storyName provided for a "${kind}" story.`);
      }
      if (m && m.hot && m.hot.dispose) {
        m.hot.dispose(() => {
          const { _storyStore } = this;
          _storyStore.remove(id);
        });
      }

      const fileName = m && m.id ? `${m.id}` : undefined;

      const { hierarchyRootSeparator, hierarchySeparator } = this.getSeparators();
      const baseOptions = {
        hierarchyRootSeparator,
        hierarchySeparator,
      };
      const allParam = [
        { options: baseOptions },
        _globalParameters,
        localParameters,
        parameters,
      ].reduce(
        (acc, p) => {
          if (p) {
            Object.entries(p).forEach(([key, value]) => {
              const existingValue = acc[key];

              if (Array.isArray(value)) {
                acc[key] = value;
              } else if (isPlainObject(value) && isPlainObject(existingValue)) {
                acc[key] = merge(existingValue, value);
              } else {
                acc[key] = value;
              }
            });
          }
          return acc;
        },
        { fileName }
      );

      this._storyStore.addStory(
        {
          id,
          kind,
          name: storyName,
          storyFn,
          parameters: allParam,
        },
        {
          applyDecorators: this._decorateStory,
          getDecorators: () => [
            ...(allParam.decorators || []),
            ...localDecorators,
            ..._globalDecorators,
            withSubscriptionTracking,
          ],
        }
      );
      return api;
    };

    api.addDecorator = decorator => {
      if (hasAdded) {
        logger.warn(`You have added a decorator to the kind '${kind}' after a story has already been added.
In Storybook 4 this applied the decorator only to subsequent stories. In Storybook 5+ it applies to all stories.
This is probably not what you intended. Read more here: https://github.com/storybooks/storybook/blob/master/MIGRATION.md`);
      }

      localDecorators.push(decorator);
      return api;
    };

    api.addParameters = parameters => {
      localParameters = { ...localParameters, ...parameters };
      return api;
    };

    return api;
  };

  // legacy
  getStorybook = () =>
    this._storyStore.getStoryKinds().map(kind => {
      const fileName = this._storyStore.getStoryFileName(kind);

      const stories = this._storyStore.getStories(kind).map(name => {
        const render = this._storyStore.getStoryWithContext(kind, name);
        return { name, render };
      });

      return { kind, fileName, stories };
    });

  raw = () => this._storyStore.raw();

  // FIXME: temporary expose the store for react-native
  // Longer term react-native should use the Provider/Consumer api
  store = () => this._storyStore;
}
<|endoftext|>


<commit_before>"use strict";

/**
 * @constructor
 * @param {Object} opts Options for this factory
 * @param {*=} opts.sdk The Matrix JS SDK require() to use.
 * @param {string=} opts.url The Client-Server base HTTP URL. This must be set
 * prior to calling getClientAs(). See configure() to set this after instantiation.
 * @param {string=} opts.token The application service token to use. This must
 * be set prior to calling getClientAs(). See configure() to set this after
 * instantiation.
 * @param {string=} opts.appServiceUserId The application service's user ID. Must
 * be set prior to calling getClientAs(). See configure() to set this after
 * instantiation.
 * @param {function=} opts.clientSchedulerBuilder Optional. A function that
 * returns a new client scheduler to use in place of the default event
 * scheduler that schedules events to be sent to the HS.
 */
function ClientFactory(opts) {
    opts = opts || {};
    this._sdk = opts.sdk || require("matrix-js-sdk");
    this._clients = {
    //  request_id: {
    //      user_id: Client
    //  }
    };
    this._clientSchedulerBuilder = opts.clientSchedulerBuilder || function() {};
    this.configure(opts.url, opts.token, opts.appServiceUserId);
}

/**
 * Set a function to be called when logging requests and responses.
 * @param {Function} func The function to invoke. The first arg is the string to
 * log. The second arg is a boolean which is 'true' if the log is an error.
 */
ClientFactory.prototype.setLogFunction = function(func) {
    if (func) {
        /* It would be nice if could ask the sdk what its current request
         * function is for wrapping purposes. Until such an API is invented for
         * that this hack will do
         */
        var origRequest = this._sdk.createClient({
            baseUrl: "dummy",
        })._http.opts.request;

        this._sdk.request(function(opts, callback) {
            var logPrefix = (
                (opts._matrix_opts && opts._matrix_opts._reqId ?
                    "[" + opts._matrix_opts._reqId + "] " : ""
                ) +
                opts.method + " " + opts.uri + " " +
                (opts.qs.user_id ? "(" + opts.qs.user_id + ")" : "(AS)")
            );
            // Request logging
            func(
                logPrefix + " Body: " +
                (opts.body ? JSON.stringify(opts.body).substring(0, 80) : "")
            );
            // Make the request
            origRequest(opts, function(err, response, body) {
                // Response logging
                var httpCode = response ? response.statusCode : null;
                var responsePrefix = logPrefix + " HTTP " + httpCode;
                if (err) {
                    func(
                        responsePrefix + " Error: " + JSON.stringify(err), true
                    );
                }
                else if (httpCode >= 300 || httpCode < 200) {
                    func(
                        responsePrefix + " Error: " + JSON.stringify(body), true
                    );
                }
                else {
                    func( // body may be large, so do first 80 chars
                        responsePrefix + " " +
                        JSON.stringify(body).substring(0, 80)
                    );
                }
                // Invoke the callback
                callback(err, response, body);
            });
        });
    }
};

/**
 * Construct a new Matrix JS SDK Client. Calling this twice with the same args
 * will return the *same* client instance.
 * @param {?string} userId Required. The user_id to scope the client to. A new
 * client will be created per user ID. If this is null, a client scoped to the
 * application service *itself* will be created.
 * @param {Request=} request Optional. The request ID to additionally scope the
 * client to. If set, this will create a new client per user ID / request combo.
 * This factory will dispose the created client instance when the request is
 * resolved.
 */
ClientFactory.prototype.getClientAs = function(userId, request) {
    var reqId = request ? request.getId() : "-";
    var userIdKey = userId || "bot";
    var self = this;

    // see if there is an existing match
    var client = this._getClient(reqId, userIdKey);
    if (client) {
        return client;
    }

    // create a new client
    var queryParams = {};
    if (userId) {
        queryParams.user_id = userId;
    }
    // force set access_token= so it is used when /register'ing
    queryParams.access_token = this._token;
    var clientOpts = {
        accessToken: this._token,
        baseUrl: this._url,
        userId: userId || this._botUserId, // NB: no clobber so we don't set ?user_id=BOT
        queryParams: queryParams,
        scheduler: this._clientSchedulerBuilder(),
    };
    client = this._sdk.createClient(clientOpts);
    client._http.opts._reqId = reqId; // FIXME gut wrenching

    // add a listener for the completion of this request so we can cleanup
    // the clients we've made
    if (request) {
        request.getPromise().finally(function() {
            delete self._clients[reqId];
        });
    }

    // store the new client
    if (!this._clients[reqId]) {
        this._clients[reqId] = {};
    }
    this._clients[reqId][userIdKey] = client;

    return client;
};

/**
 * Configure the factory for generating clients.
 * @param {string} baseUrl The base URL to create clients with.
 * @param {string} appServiceToken The AS token to use as the access_token
 * @param {string} appServiceUserId The AS's user_id
 */
ClientFactory.prototype.configure = function(baseUrl, appServiceToken, appServiceUserId) {
    this._url = baseUrl;
    this._token = appServiceToken;
    this._botUserId = appServiceUserId;
};

ClientFactory.prototype._getClient = function(reqId, userId) {
    if (this._clients[reqId] && this._clients[reqId][userId]) {
        return this._clients[reqId][userId];
    }
    return null;
};

module.exports = ClientFactory;
<commit_msg>Add 5min localTimeoutMs - Requires new JS SDK<commit_after>"use strict";

/**
 * @constructor
 * @param {Object} opts Options for this factory
 * @param {*=} opts.sdk The Matrix JS SDK require() to use.
 * @param {string=} opts.url The Client-Server base HTTP URL. This must be set
 * prior to calling getClientAs(). See configure() to set this after instantiation.
 * @param {string=} opts.token The application service token to use. This must
 * be set prior to calling getClientAs(). See configure() to set this after
 * instantiation.
 * @param {string=} opts.appServiceUserId The application service's user ID. Must
 * be set prior to calling getClientAs(). See configure() to set this after
 * instantiation.
 * @param {function=} opts.clientSchedulerBuilder Optional. A function that
 * returns a new client scheduler to use in place of the default event
 * scheduler that schedules events to be sent to the HS.
 */
function ClientFactory(opts) {
    opts = opts || {};
    this._sdk = opts.sdk || require("matrix-js-sdk");
    this._clients = {
    //  request_id: {
    //      user_id: Client
    //  }
    };
    this._clientSchedulerBuilder = opts.clientSchedulerBuilder || function() {};
    this.configure(opts.url, opts.token, opts.appServiceUserId);
}

/**
 * Set a function to be called when logging requests and responses.
 * @param {Function} func The function to invoke. The first arg is the string to
 * log. The second arg is a boolean which is 'true' if the log is an error.
 */
ClientFactory.prototype.setLogFunction = function(func) {
    if (func) {
        /* It would be nice if could ask the sdk what its current request
         * function is for wrapping purposes. Until such an API is invented for
         * that this hack will do
         */
        var origRequest = this._sdk.createClient({
            baseUrl: "dummy",
        })._http.opts.request;

        this._sdk.request(function(opts, callback) {
            var logPrefix = (
                (opts._matrix_opts && opts._matrix_opts._reqId ?
                    "[" + opts._matrix_opts._reqId + "] " : ""
                ) +
                opts.method + " " + opts.uri + " " +
                (opts.qs.user_id ? "(" + opts.qs.user_id + ")" : "(AS)")
            );
            // Request logging
            func(
                logPrefix + " Body: " +
                (opts.body ? JSON.stringify(opts.body).substring(0, 80) : "")
            );
            // Make the request
            origRequest(opts, function(err, response, body) {
                // Response logging
                var httpCode = response ? response.statusCode : null;
                var responsePrefix = logPrefix + " HTTP " + httpCode;
                if (err) {
                    func(
                        responsePrefix + " Error: " + JSON.stringify(err), true
                    );
                }
                else if (httpCode >= 300 || httpCode < 200) {
                    func(
                        responsePrefix + " Error: " + JSON.stringify(body), true
                    );
                }
                else {
                    func( // body may be large, so do first 80 chars
                        responsePrefix + " " +
                        JSON.stringify(body).substring(0, 80)
                    );
                }
                // Invoke the callback
                callback(err, response, body);
            });
        });
    }
};

/**
 * Construct a new Matrix JS SDK Client. Calling this twice with the same args
 * will return the *same* client instance.
 * @param {?string} userId Required. The user_id to scope the client to. A new
 * client will be created per user ID. If this is null, a client scoped to the
 * application service *itself* will be created.
 * @param {Request=} request Optional. The request ID to additionally scope the
 * client to. If set, this will create a new client per user ID / request combo.
 * This factory will dispose the created client instance when the request is
 * resolved.
 */
ClientFactory.prototype.getClientAs = function(userId, request) {
    var reqId = request ? request.getId() : "-";
    var userIdKey = userId || "bot";
    var self = this;

    // see if there is an existing match
    var client = this._getClient(reqId, userIdKey);
    if (client) {
        return client;
    }

    // create a new client
    var queryParams = {};
    if (userId) {
        queryParams.user_id = userId;
    }
    // force set access_token= so it is used when /register'ing
    queryParams.access_token = this._token;
    var clientOpts = {
        accessToken: this._token,
        baseUrl: this._url,
        userId: userId || this._botUserId, // NB: no clobber so we don't set ?user_id=BOT
        queryParams: queryParams,
        scheduler: this._clientSchedulerBuilder(),
        localTimeoutMs: 1000 * 60 * 5, // Time out CS-API calls after 5mins
    };
    client = this._sdk.createClient(clientOpts);
    client._http.opts._reqId = reqId; // FIXME gut wrenching

    // add a listener for the completion of this request so we can cleanup
    // the clients we've made
    if (request) {
        request.getPromise().finally(function() {
            delete self._clients[reqId];
        });
    }

    // store the new client
    if (!this._clients[reqId]) {
        this._clients[reqId] = {};
    }
    this._clients[reqId][userIdKey] = client;

    return client;
};

/**
 * Configure the factory for generating clients.
 * @param {string} baseUrl The base URL to create clients with.
 * @param {string} appServiceToken The AS token to use as the access_token
 * @param {string} appServiceUserId The AS's user_id
 */
ClientFactory.prototype.configure = function(baseUrl, appServiceToken, appServiceUserId) {
    this._url = baseUrl;
    this._token = appServiceToken;
    this._botUserId = appServiceUserId;
};

ClientFactory.prototype._getClient = function(reqId, userId) {
    if (this._clients[reqId] && this._clients[reqId][userId]) {
        return this._clients[reqId][userId];
    }
    return null;
};

module.exports = ClientFactory;
<|endoftext|>


<commit_before>'use strict';

var user;
var type;
var scope;

/**
 * run once to determin the scope
 * @return {[type]} [description]
 */
function checkScope(){
  if(typeof user.email !== 'undefined'){
    type = 'email';
    scope = emailFuncs;
  }else if(typeof user.username !== 'undefined'){
    type = 'username';
    scope = usernameFuncs;
  }else{
    throw 'User model must have either an email or username attribute';
  }
}

/**
 * Wrapper for model methods username scope
 * @type {Object}
 */
var usernameFuncs = {
  findOrCreate: function(User, attributes, cb){
    User.findOrCreate({username: attributes.username}, attributes).done(cb);
  },
  update: function(User, type, attributes, cb){
    User.update({username: type}, attributes).done(cb);
  }
};

/**
 * Wrapper for model methods email scope
 * @type {Object}
 */
var emailFuncs = {
  findOrCreate: function(User, attributes, cb){
    User.findOrCreate({email: attributes.email}, attributes).done(cb);
  },
  update: function(User, type, attributes, cb){
    User.update({email: type}, attributes).done(cb);
  }
};

/**
 * Login action
 */
module.exports = function(req, res){
  var bcrypt = require('bcrypt');
  if(typeof user === 'undefined'){
    user = User.definition;
    checkScope();
  }

  if(typeof req.body[type] === 'undefined' || typeof req.body.password === 'undefined'){
    res.json({error: 'Invalid '+type+' or password'}, 400);
  }else{
    scope.findOrCreate(User, req.body, function(err, user){
      if (err) {
        res.json({ error: 'DB error' }, 500);
      }
      if (user) {
        if(bcrypt.compareSync(req.body.password, user.password)){
          // password match

          // update the login
          scope.update(User, req.body[type],
            {lastIp:req.connection.remoteAddress,
              lastLogin: new Date()}, function(){});

          req.session.user = user;
          req.session.authenticated = true;
          res.json(user);
          }else{
            // invalid password
            if (req.session.user) {
              req.session.user = null;
            }
            //maybe uncomment this later
            //scope.update(User, req.body[type], {loginAttempts: user.loginAttempts++}, function(){});
            res.json({ error: 'Invalid password' }, 400);
          }
      } else {
        //TODO redirect to register
        res.json({ error: 'User not found' }, 404);
      }
    });
  }
};<commit_msg>using attempt<commit_after>'use strict';

var user;
var type;
var scope;

/**
 * run once to determin the scope
 * @return {[type]} [description]
 */
function checkScope(){
  if(typeof user.email !== 'undefined'){
    type = 'email';
    scope = emailFuncs;
  }else if(typeof user.username !== 'undefined'){
    type = 'username';
    scope = usernameFuncs;
  }else{
    throw 'User model must have either an email or username attribute';
  }
}

/**
 * Wrapper for model methods username scope
 * @type {Object}
 */
var usernameFuncs = {
  findOrCreate: function(User, attributes, cb){
    User.findOrCreate({username: attributes.username}, attributes).done(cb);
  }
};

/**
 * Wrapper for model methods email scope
 * @type {Object}
 */
var emailFuncs = {
  findOrCreate: function(User, attributes, cb){
    User.findOrCreate({email: attributes.email}, attributes).done(cb);
  }
};

/**
 * Login action
 */
module.exports = function(req, res){
  var bcrypt = require('bcrypt');
  if(typeof user === 'undefined'){
    user = User.definition;
    checkScope();
  }

  if(typeof req.body[type] === 'undefined' || typeof req.body.password === 'undefined'){
    res.json({error: 'Invalid '+type+' or password'}, 400);
  }else{
    scope.findOrCreate(User, req.body, function(err, user){
      if (err) {
        res.json({ error: 'DB error' }, 500);
      }
      if (user) {
        var attempt = {user:user.id, ip: req.connection.remoteAddress};
        if(bcrypt.compareSync(req.body.password, user.password)){
          // password match
          attempt.successful = true;

          req.session.user = user;
          req.session.authenticated = true;
          res.json(user);
        }else{
          // invalid password
          attempt.successful = false;

          if (req.session.user) {
            req.session.user = null;
          }
          //maybe uncomment this later
          //scope.update(User, req.body[type], {loginAttempts: user.loginAttempts++}, function(){});
          res.json({ error: 'Invalid password' }, 400);
        }
        // log the attempt
        Attempt.create(attempt).done(function(){});
      } else {
        //TODO redirect to register
        res.json({ error: 'User not found' }, 404);
      }
    });
  }
};<|endoftext|>


<commit_before>module.exports = require('./dist/server/utils/merge-webpack-config').default;
<commit_msg>remove bad entry<commit_after><|endoftext|>


<commit_before>var gateway = require(__dirname+'/../../');
var async = require('async');

function WithdrawalProcessor(incomingPayment) {
  this.incomingPayment = incomingPayment;
}

WithdrawalProcessor.prototype = {

  processIncomingPayment: function(callback) {
    var self = this;
    async.waterfall([
      function(callback) {
        self._getTransactionRippleAddress(callback);
      },
      function(address, callback) {
        self._createWithdrawal(address, callback);
      },
      function(rippleTransaction, callback) {
        self._finalizeRippleTransaction(callback);
      }
    ], callback);
  },

  _getTransactionRippleAddress: function(callback) {
    var self = this;
    var rippleTransaction = self.incomingPayment;
    gateway.data.models.rippleAddresses.find({
      where: { id: rippleTransaction.to_address_id }
    }).complete(function(error, address) {
      if (error){
        callback(error, null);
      } else if (address){
        callback(null, address);
      } else {
        callback('no address found', null);
      }
    });
  },

  _createWithdrawal: function(address, callback){
    var self = this;
    var rippleTransaction = self.incomingPayment;
    // var amountMinusFees = rippleTransaction.to_amount * (1 - gateway.config.get('WITHDRAWAL_FEE'));
    gateway.data.models.externalTransactions.find({
      where: {
        ripple_transaction_id: rippleTransaction.id,
        status: 'invoice'
      }
    }).complete(function(error, externalTransaction) {
      if (error) {
        logger.error('withdrawal:failed', error);
        callback(error, null);
      } else if (externalTransaction) {
        externalTransaction.updateAttributes({
          status: 'queued'
        }).complete(function(error, withdrawal) {
          if (error) {
            logger.error('withdrawal:failed', error);
            callback(error, null);
          } else if (withdrawal) {
            self.externalTransactionWithdrawal = withdrawal;
            logger.info('withdrawal:recorded', withdrawal.toJSON());
            callback(null, withdrawal);
          } else {
            logger.error('withdrawal:failed', 'withdrawal not found');
            callback('withdrawal not found', null);
          }
        });
      } else {
        gateway.data.models.externalTransactions.create({
          deposit: false,
          amount: rippleTransaction.to_amount,
          currency: rippleTransaction.to_currency,
          status: 'queued',
          ripple_transaction_id: rippleTransaction.id,
          external_account_id: address.tag
        }).complete(function(error, withdrawal) {
          if (error) {
            logger.error('withdrawal:failed', error);
            callback(error, null);
          } else if (withdrawal) {
            self.externalTransactionWithdrawal = withdrawal;
            logger.info('withdrawal:recorded', withdrawal.toJSON());
            callback(null, withdrawal);
          } else {
            logger.error('withdrawal:failed', 'withdrawal not found');
            callback('withdrawal not found', null);
          }
        });
      }
    });
  },

  _finalizeRippleTransaction: function(callback){
    var self = this;
    self.incomingPayment.updateAttributes({
      state: 'succeeded'
    }).complete(function(error, rippleTransaction) {
      if (error) {
        logger.info('payments:incoming:finalize:error', error);
        callback(error, null);
      } else {
        logger.info('payments:incoming:finalize:success', rippleTransaction.toJSON());
        callback(null, rippleTransaction);
      }
    });
  }

};

module.exports = WithdrawalProcessor;

<commit_msg>[TASK] Lookup corresponding external_transaction record via gateway_transaction record for withdrawals<commit_after>var gateway = require(__dirname+'/../../');
var async = require('async');

function WithdrawalProcessor(incomingPayment) {
  this.incomingPayment = incomingPayment;
}

WithdrawalProcessor.prototype = {

  processIncomingPayment: function(callback) {
    var self = this;
    async.waterfall([
      function(callback) {
        self._getTransactionRippleAddress(callback);
      },
      function(address, callback) {
        self._createWithdrawal(address, callback);
      },
      function(rippleTransaction, callback) {
        self._finalizeRippleTransaction(callback);
      }
    ], callback);
  },

  _getTransactionRippleAddress: function(callback) {
    var self = this;
    var rippleTransaction = self.incomingPayment;
    gateway.data.models.rippleAddresses.find({
      where: { id: rippleTransaction.to_address_id }
    }).complete(function(error, address) {
      if (error){
        callback(error, null);
      } else if (address){
        callback(null, address);
      } else {
        callback('no address found', null);
      }
    });
  },

  _createWithdrawal: function(address, callback){
    var self = this;
    var rippleTransaction = self.incomingPayment;
    // var amountMinusFees = rippleTransaction.to_amount * (1 - gateway.config.get('WITHDRAWAL_FEE'));
    gateway.data.models.gatewayTransactions.find({
      where: {
        ripple_transaction_id: rippleTransaction.id
      }
    }).complete(function(error, gatewayTransaction) {
      if (error) {
        logger.error('withdrawal:failed', error);
        callback(error, null);
      } else if (gatewayTransaction) {
        gateway.data.models.externalTransactions.find({
          where: {
            id: gatewayTransaction.external_transaction_id,
            status: 'invoice'
          }
        }).complete(function(error, externalTransaction) {
          if (error) {
            logger.error('withdrawal:failed', error);
            callback(error, null);
          } else if (externalTransaction) {
            externalTransaction.updateAttributes({
              status: 'queued'
            }).complete(function(error, withdrawal) {
              if (error) {
                logger.error('withdrawal:failed', error);
                callback(error, null);
              } else if (withdrawal) {
                self.externalTransactionWithdrawal = withdrawal;
                logger.info('withdrawal:recorded', withdrawal.toJSON());
                callback(null, withdrawal);
              } else {
                logger.error('withdrawal:failed', 'withdrawal not found');
                callback('withdrawal not found', null);
              }
            });
          } else {
            gateway.data.models.externalTransactions.create({
              deposit: false,
              amount: rippleTransaction.to_amount,
              currency: rippleTransaction.to_currency,
              status: 'queued',
              ripple_transaction_id: rippleTransaction.id,
              external_account_id: address.tag
            }).complete(function(error, withdrawal) {
              if (error) {
                logger.error('withdrawal:failed', error);
                callback(error, null);
              } else if (withdrawal) {
                self.externalTransactionWithdrawal = withdrawal;
                logger.info('withdrawal:recorded', withdrawal.toJSON());
                callback(null, withdrawal);
              } else {
                logger.error('withdrawal:failed', 'withdrawal not found');
                callback('withdrawal not found', null);
              }
            });
          }
        });
      } else {
        logger.error('withdrawal:failed', 'gatewayTransaction not found');
        callback('withdrawal not found', null);
      }
    });
  },

  _finalizeRippleTransaction: function(callback){
    var self = this;
    self.incomingPayment.updateAttributes({
      state: 'succeeded'
    }).complete(function(error, rippleTransaction) {
      if (error) {
        logger.info('payments:incoming:finalize:error', error);
        callback(error, null);
      } else {
        logger.info('payments:incoming:finalize:success', rippleTransaction.toJSON());
        callback(null, rippleTransaction);
      }
    });
  }

};

module.exports = WithdrawalProcessor;

<|endoftext|>


<commit_before>var C = require( '../constants/constants' ),
	SubscriptionRegistry = require( '../utils/subscription-registry' ),
	messageBuilder = require( '../message/message-builder' );

var EventHandler = function( connectionEndpoint, options ) {
	this._connectionEndpoint = connectionEndpoint;
	this._options = options;
	this._subscriptionRegistry = new SubscriptionRegistry( options );
};

EventHandler.prototype.handle = function( socketWrapper, message ) {
	if( message.action === C.ACTIONS.SUBSCRIBE ) {
		this._addSubscriber( socketWrapper, message );
	}

	if( message.action === C.ACTIONS.UNSUBSCRIBE ) {
		this._removeSubscriber( socketWrapper, message );
	}

	if( message.action === C.ACTIONS.EVENT ) {
		this._triggerEvent( socketWrapper, message );
	}
};

EventHandler.prototype._addSubscriber = function( socketWrapper, message ) {
	if( this._validateSubscriptionMessage( socketWrapper, message ) ) {
		this._subscriptionRegistry.subscribe( message.data[ 0 ], socketWrapper );
	}
};

EventHandler.prototype._removeSubscriber = function( socketWrapper, message ) {
	if( this._validateSubscriptionMessage( socketWrapper, message ) ) {
		this._subscriptionRegistry.unsubscribe( message.data[ 0 ], socketWrapper );
	}
};

EventHandler.prototype._triggerEvent = function( socketWrapper, message ) {
	if( typeof message.data[ 0 ] !== 'string' ) {
		if( socketWrapper !== C.SOURCE_MESSAGE_CONNECTOR ) {
			socketWrapper.sendError( C.TOPIC.EVENT, C.EVENT.INVALID_MESSAGE_DATA, message.raw );
		}

		return;
	}
	this._options.logger.log( C.LOG_LEVEL.DEBUG, C.EVENT.TRIGGER_EVENT, message.raw );

	if( socketWrapper !== C.SOURCE_MESSAGE_CONNECTOR ) {
		this._options.messageConnector.publish( C.TOPIC.EVENT, message );
	}
	var outboundMessage = messageBuilder.getMsg( C.TOPIC.EVENT, C.ACTIONS.EVENT, message.data );
	this._subscriptionRegistry.sendToSubscribers( message.data[ 0 ], outboundMessage, socketWrapper );
};

EventHandler.prototype._validateSubscriptionMessage = function( socketWrapper, message ) {
	if( message.data.length === 1 && typeof message.data[ 0 ] === 'string' ) {
		return true;
	} else {
		socketWrapper.sendError( C.TOPIC.EVENT, C.EVENT.INVALID_MESSAGE_DATA, message.raw );
		return false;
	}
};

module.exports = EventHandler;<commit_msg>Update event-handler.js<commit_after>var C = require( '../constants/constants' ),
	SubscriptionRegistry = require( '../utils/subscription-registry' ),
	messageBuilder = require( '../message/message-builder' );

var EventHandler = function( connectionEndpoint, options ) {
	this._connectionEndpoint = connectionEndpoint;
	this._options = options;
	this._subscriptionRegistry = new SubscriptionRegistry( options );
};

EventHandler.prototype.handle = function( socketWrapper, message ) {
	if( message.action === C.ACTIONS.SUBSCRIBE ) {
		this._addSubscriber( socketWrapper, message );
	}

	else if( message.action === C.ACTIONS.UNSUBSCRIBE ) {
		this._removeSubscriber( socketWrapper, message );
	}

	else if( message.action === C.ACTIONS.EVENT ) {
		this._triggerEvent( socketWrapper, message );
	}
};

EventHandler.prototype._addSubscriber = function( socketWrapper, message ) {
	if( this._validateSubscriptionMessage( socketWrapper, message ) ) {
		this._subscriptionRegistry.subscribe( message.data[ 0 ], socketWrapper );
	}
};

EventHandler.prototype._removeSubscriber = function( socketWrapper, message ) {
	if( this._validateSubscriptionMessage( socketWrapper, message ) ) {
		this._subscriptionRegistry.unsubscribe( message.data[ 0 ], socketWrapper );
	}
};

EventHandler.prototype._triggerEvent = function( socketWrapper, message ) {
	if( typeof message.data[ 0 ] !== 'string' ) {
		if( socketWrapper !== C.SOURCE_MESSAGE_CONNECTOR ) {
			socketWrapper.sendError( C.TOPIC.EVENT, C.EVENT.INVALID_MESSAGE_DATA, message.raw );
		}

		return;
	}
	this._options.logger.log( C.LOG_LEVEL.DEBUG, C.EVENT.TRIGGER_EVENT, message.raw );

	if( socketWrapper !== C.SOURCE_MESSAGE_CONNECTOR ) {
		this._options.messageConnector.publish( C.TOPIC.EVENT, message );
	}
	var outboundMessage = messageBuilder.getMsg( C.TOPIC.EVENT, C.ACTIONS.EVENT, message.data );
	this._subscriptionRegistry.sendToSubscribers( message.data[ 0 ], outboundMessage, socketWrapper );
};

EventHandler.prototype._validateSubscriptionMessage = function( socketWrapper, message ) {
	if( message.data.length === 1 && typeof message.data[ 0 ] === 'string' ) {
		return true;
	} else {
		socketWrapper.sendError( C.TOPIC.EVENT, C.EVENT.INVALID_MESSAGE_DATA, message.raw );
		return false;
	}
};

module.exports = EventHandler;
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react'
import FormBuilderPropTypes from '../FormBuilderPropTypes'
import update from 'react-addons-update'

class NumberContainer {
  constructor(value, context) {
    this.stringValue = value
    this.context = context
  }

  patch(patch) {
    if (patch.hasOwnProperty('$set')) {
      return new NumberContainer(patch.$set)
    }
    throw new Error(`Only $set is supported by NumberContainer, got: ${JSON.stringify(patch)}`)
  }

  unwrap() {
    return this.stringValue.trim() === '' ? void 0 : Number(this.stringValue)
  }
}

NumberContainer.wrap = function wrap(numberValue) {
  return new NumberContainer(numberValue)
}

export default React.createClass({
  propTypes: {
    field: FormBuilderPropTypes.field,
    value: PropTypes.shape({stringValue: PropTypes.string}),
    onChange: PropTypes.func
  },

  statics: {
    container: NumberContainer
  },

  getDefaultProps() {
    return {
      onChange() {}
    }
  },

  handleChange(e) {
    this.props.onChange({patch: {$set: e.target.value}})
  },

  render() {
    const {value} = this.props
    return (
      <input type="number"
        onChange={this.handleChange}
        value={value ? value.unwrap() : void 0}
      />
    )
  }

})
<commit_msg>Simplify number widget<commit_after>import React, {PropTypes} from 'react'
import FormBuilderPropTypes from '../FormBuilderPropTypes'
import update from 'react-addons-update'

export default React.createClass({
  propTypes: {
    field: FormBuilderPropTypes.field,
    value: PropTypes.shape({stringValue: PropTypes.string}),
    onChange: PropTypes.func
  },

  getDefaultProps() {
    return {
      onChange() {}
    }
  },

  handleChange(e) {
    const val = e.target.value.trim()
    this.props.onChange({patch: {$set: val === '' ? void 0 : Number(e.target.value)}})
  },

  render() {
    const {value} = this.props
    return (
      <input type="number"
        onChange={this.handleChange}
        value={value}
      />
    )
  }

})
<|endoftext|>


<commit_before>'use strict'

var Promise = require('bluebird');
var _ = require("lodash");
var path = require("path");

var Broker = require('./Broker/index');
var Booker = require('./Booker/index');
var Facehugger = require('./Facehugger/index');
var Replicator = require("./Replicator/index");
var Arbiter = require("./Arbiter/index");
var Doctor = require('./Physician/physician.js');
var Auth = require('./Auth/auth.js');
var Queue = require('custom-queue');
var Constellation = require("./Constellation/constellation");

var config = require('./const/config');
var iconfig = require('../inspectors-config.json');

var MetaTree = require("MetaTree").MetaTree;

var meta_tree = new MetaTree({
    server_ip: config.db.server_ip,
    n1ql: config.db.n1ql,
    bucket_name: config.db.bucket_name,
    role: config.name
});

var doctor = new Doctor();
var alien = new Facehugger();
var broker = new Broker();
var booker = new Booker();
var arbiter = new Arbiter();
var rep = new Replicator();
var auth = new Auth();

var replica = "192.168.1.3";
var replica_b = "rmt";
var main = "192.168.1.2";
var main_b = "mt";

var hosts = new Constellation();
hosts.add("lunar", replica, "Administrator:456789");
hosts.add("basilisk", main, "Administrator:123456");

var ee = new Queue();

alien.setChannels({
    "queue": ee
});
rep.setChannels({
    "queue": ee
});
arbiter.setChannels({
    "queue": ee
});
broker.setChannels({
    "queue": ee
});
booker.setChannels({
    "queue": ee
});
doctor.setChannels({
    "event-queue": ee
});
auth.setChannels({
    "queue": ee
});

//INTEROP DATA
var attempts = 7;
//var requested = [];
var data = {
<<<<<<< HEAD
    src_host: "basilisk",
    src_bucket: "mt",
    dst_host: "lunar",
    dst_bucket: "rmt"
=======
    src_host: "lunar",
    src_bucket: "rmt",
    dst_host: "basilisk",
    dst_bucket: "mt"
>>>>>>> origin/master
};
var timeo = 2000;
var book_timeo = 2000;

//to imitate
<<<<<<< HEAD
ee.on('permission.dropped.ip.192.168.1.3', d => {
=======
ee.on('permission.dropped.ip.192.168.1.2', d => {
>>>>>>> origin/master
    console.log('dropped:', d);
    ee.addTask(rep.event_names.pause('bidirect'), data);
})

ee.on('permission.restored.ip.192.168.1.2', d => {
    console.log('restored:', d);
    ee.addTask(rep.event_names.resume('bidirect'), data);
});

//ee.listenTask('dbface.request', d => console.log("REQUEST", d));
//ee.listenTask('dbface.response', d => console.log("RESPONSE", d));
var free = function (res) {

}

var act = function (requested, num, action) {
    if (!requested || _.isEmpty(requested) || !requested[0] || !requested[1]) {
        console.log("Resource info not provided");
        return Promise.resolve(false);
    }
    if (num == 0) {
        console.log("Max attempts num reached");
        return Promise.resolve(false);
    }
    console.log("Trying to ", action, " resource ", requested, ", attempt", num);
    return ee.addTask(booker.event_names.request, {
            db_id: requested[0],
            data: requested[1],
            action: action
        })
        .then((res) => {
            if (res.success === true) {
                console.log("Success", action);
                return Promise.resolve(res);
            }
        })
        .catch((res) => {
            console.log("Error while trying to request the resource");
            if (res.name == "CBirdError") {
                console.log("Unable to", action, "this resource");
                return Promise.resolve(res);
            }
            if (res.name == booker.errname) {
                console.log("Booker service error, retrying...");
            }
            if (res.name == alien.errname) {
                console.log("DBWorker service error, retrying...");
            }
            return Promise.delay(book_timeo)
                .then(() => {
                    return act(requested, (num - 1), action);
                });
        });

}

var init = Promise.coroutine(function* () {
    yield meta_tree.initModel(path.resolve(__dirname, "Model/MetaTree"));
    yield auth.init();
    yield doctor.init(iconfig);
    yield alien.init({
        server_ip: config.db.server_ip,
        n1ql: config.db.n1ql,
        bucket_name: config.db.bucket_name
    });
    yield broker.init({
        meta_tree: meta_tree
    });
    yield booker.init({
        meta_tree: meta_tree,
        hosts: hosts
    });
    yield rep.init({
        hosts: hosts
    });
    yield arbiter.init({
        hosts: hosts
    });
});

init()
    .then(function () {
        auth.tryToStart();
        doctor.tryToStart();
    }).delay(timeo)
    .then(function () {
        alien.tryToStart();
        broker.tryToStart();
        booker.tryToStart();
        rep.tryToStart();
        arbiter.tryToStart();
    })
<<<<<<< HEAD
    //    .then(() => {
    //        return ee.addTask(booker.event_names.patch, {
    //            resource: 'resource/8',
    //            patch: {
    //                state: "reserved",
    //                owner: "replica"
    //            }
    //        })
    //    })
    //    .then((res) => {
    //        console.log("PATCH RESPONSE :", res);
    //    })
    //    .delay(timeo * 5)
    //    .then(() => {
    //        return ee.addTask(rep.event_names.create('bidirect'), data);
    //    })
    //    .then((res) => {
    //        //                console.log("SETTINGS", res);
    //        var evdata = _.clone(data);
    //        evdata.settings = {
    //            docBatchSizeKb: 512,
    //            checkpointInterval: 10 //please, do not use this in production until you're all sure about your hardware
    //        };
    //        return ee.addTask(rep.event_names.settings, evdata);
    //    })
    //    .delay(timeo)
    //    .then((res) => {
    //        var evdata = _.clone(data);
    //        evdata.stat_name = "percent_completeness";
    //        return ee.addTask(rep.event_names.stats, evdata);
    //    })
    //    .delay(timeo)
    //    .then((res) => {
    //        return ee.addTask(broker.event_names.resources, {
    //            start: 1,
    //            end: 8
    //        });
    //    })
=======
    //        .delay(timeo * 5)
    //        .then(() => {
    //            return ee.addTask(rep.event_names.create('bidirect'), data);
    //        })
    //        .then((res) => {
    //            //                console.log("SETTINGS", res);
    //            var evdata = _.clone(data);
    //            evdata.settings = {
    //                docBatchSizeKb: 512,
    //                checkpointInterval: 10 //please, do not use this in production until you're all sure about your hardware
    //            };
    //            return ee.addTask(rep.event_names.settings, evdata);
    //        })
    //        .delay(timeo)
    //        .then((res) => {
    //            var evdata = _.clone(data);
    //            evdata.stat_name = "percent_completeness";
    //            return ee.addTask(rep.event_names.stats, evdata);
    //        })        .delay(timeo)
    .then((res) => {
        return ee.addTask(broker.event_names.resources, {
            start: 1,
            end: 8
        });
    })
>>>>>>> origin/master
    .delay(timeo)
    .then((range) => {
        console.log("RESPONDED WITH", range);
        var requested = _.sample(_.pairs(_.reduce(range, (res, val, key) => {
            if (val.value.state == "idle") {
                res[key] = val;
            }
            return res;
        }, {})));
        console.log("TAKING", requested);
        return act(requested, attempts, "book");
    })
    .delay(timeo)
    .then((res) => {
        console.log("BOOK RESPONSE :", res);
        return act([res.db_id, res.data], attempts, "free");
    })
    .delay(timeo)
    .then((res) => {
        console.log("FREE RESPONSE:", res);
    })
    .then((res) => {
        return ee.addTask(broker.event_names.resources, {
            start: 1,
            end: 8
        });
    })
    .delay(timeo)
    .then((range) => {
        console.log("RESPONDED WITH", range);
        var requested = _.sample(_.pairs(_.reduce(range, (res, val, key) => {
            if (val.value.state == "idle") {
                res[key] = val;
            }
            return res;
        }, {})));
        console.log("TAKING", requested);
        return act(requested, attempts, "book");
    })
    .delay(timeo)
    .then((res) => {
        console.log("BOOK RESPONSE :", res);
        return act([res.db_id, res.data], attempts, "free");
    })
    .delay(timeo)
    .then((res) => {
        console.log("FREE RESPONSE:", res);
    })
    .then((res) => {
        return ee.addTask(broker.event_names.resources, {
            start: 1,
            end: 8
        });
    })
    .delay(timeo)
    .then((range) => {
        console.log("RESPONDED WITH", range);
        var requested = _.sample(_.pairs(_.reduce(range, (res, val, key) => {
            if (val.value.state == "idle") {
                res[key] = val;
            }
            return res;
        }, {})));
        console.log("TAKING", requested);
        return act(requested, attempts, "book");
    })
    .delay(timeo)
    .then((res) => {
        console.log("BOOK RESPONSE :", res);
        return act([res.db_id, res.data], attempts, "free");
    })
    .delay(timeo)
    .then((res) => {
        console.log("FREE RESPONSE:", res);
    })
    .catch((err) => {
        console.log("ERRORRR", err.stack)
    })
    //    .delay(timeo)
<<<<<<< HEAD
    //    .then(() => {
    //        return ee.addTask(rep.event_names.pause('bidirect'), data);
    //    })
    //    .then((res) => {
    //        console.log("REP PAUSE:", res);
    //    });
=======
//    .then(() => {
//        return ee.addTask(rep.event_names.pause('bidirect'), data);
//    })
//    .then((res) => {
//        console.log("REP PAUSE:", res);
//    });
>>>>>>> origin/master
<commit_msg>Resolved<commit_after>'use strict'

var Promise = require('bluebird');
var _ = require("lodash");
var path = require("path");

var Broker = require('./Broker/index');
var Booker = require('./Booker/index');
var Facehugger = require('./Facehugger/index');
var Replicator = require("./Replicator/index");
var Arbiter = require("./Arbiter/index");
var Doctor = require('./Physician/physician.js');
var Auth = require('./Auth/auth.js');
var Queue = require('custom-queue');
var Constellation = require("./Constellation/constellation");

var config = require('./const/config');
var iconfig = require('../inspectors-config.json');

var MetaTree = require("MetaTree").MetaTree;

var meta_tree = new MetaTree({
    server_ip: "127.0.0.1",
    n1ql: "127.0.0.1:8093",
    bucket_name: "mt",
    role: config.name
});

var doctor = new Doctor();
var alien = new Facehugger();
var broker = new Broker();
var booker = new Booker();
var arbiter = new Arbiter();
var rep = new Replicator();
var auth = new Auth();

var replica = "192.168.1.3";
var replica_b = "rmt";
var main = "192.168.1.2";
var main_b = "mt";

var hosts = new Constellation();
hosts.add("lunar", replica, "Administrator:456789");
hosts.add("basilisk", main, "Administrator:123456");

var ee = new Queue();

alien.setChannels({
    "queue": ee
});
rep.setChannels({
    "queue": ee
});
arbiter.setChannels({
    "queue": ee
});
broker.setChannels({
    "queue": ee
});
booker.setChannels({
    "queue": ee
});
doctor.setChannels({
    "event-queue": ee
});
auth.setChannels({
    "queue": ee
});

//INTEROP DATA
var attempts = 7;
//var requested = [];
var data = {
    src_host: "basilisk",
    src_bucket: "mt",
    dst_host: "lunar",
    dst_bucket: "rmt"
};
var timeo = 2000;
var book_timeo = 2000;

//to imitate
ee.on('permission.dropped.ip.192.168.1.3', d => {
    console.log('dropped:', d);
    ee.addTask(rep.event_names.pause('bidirect'), data);
})

ee.on('permission.restored.ip.192.168.1.3', d => {
    console.log('restored:', d);
    ee.addTask(rep.event_names.resume('bidirect'), data);
});

//ee.listenTask('dbface.request', d => console.log("REQUEST", d));
//ee.listenTask('dbface.response', d => console.log("RESPONSE", d));
var free = function (res) {

}

var act = function (requested, num, action) {
    if (!requested || _.isEmpty(requested) || !requested[0] || !requested[1]) {
        console.log("Resource info not provided");
        return Promise.resolve(false);
    }
    if (num == 0) {
        console.log("Max attempts num reached");
        return Promise.resolve(false);
    }
    console.log("Trying to ", action, " resource ", requested, ", attempt", num);
    return ee.addTask(booker.event_names.request, {
            db_id: requested[0],
            data: requested[1],
            action: action
        })
        .then((res) => {
            if (res.success === true) {
                console.log("Success", action);
                return Promise.resolve(res);
            }
        })
        .catch((res) => {
            console.log("Error while trying to request the resource");
            if (res.name == "CBirdError") {
                console.log("Unable to", action, "this resource");
                return Promise.resolve(res);
            }
            if (res.name == booker.errname) {
                console.log("Booker service error, retrying...");
            }
            if (res.name == alien.errname) {
                console.log("DBWorker service error, retrying...");
            }
            return Promise.delay(book_timeo)
                .then(() => {
                    return act(requested, (num - 1), action);
                });
        });

}

var init = Promise.coroutine(function* () {
    yield meta_tree.initModel(path.resolve(__dirname, "Model/MetaTree"));
    yield auth.init();
    yield doctor.init(iconfig);
    yield alien.init({
        server_ip: config.db.server_ip,
        n1ql: config.db.n1ql,
        bucket_name: config.db.bucket_name
    });
    yield broker.init({
        meta_tree: meta_tree
    });
    yield booker.init({
        meta_tree: meta_tree,
        hosts: hosts,
        master: "lunar",
        master_bucket: replica_b,
        slave: "basilisk",
        slave_bucket: main_b
    });
    yield rep.init({
        hosts: hosts
    });
    yield arbiter.init({
        hosts: hosts
    });
});

init()
    .then(function () {
        auth.tryToStart();
        doctor.tryToStart();
    }).delay(timeo)
    .then(function () {
        alien.tryToStart();
        broker.tryToStart();
        booker.tryToStart();
        rep.tryToStart();
        arbiter.tryToStart();
    })
    //    .then(() => {
    //        return ee.addTask(booker.event_names.patch, {
    //            resource: 'resource/8',
    //            patch: {
    //                state: "reserved",
    //                owner: "replica"
    //            }
    //        })
    //    })
    //    .then((res) => {
    //        console.log("PATCH RESPONSE :", res);
    //    })
    //    .delay(timeo * 5)
    //    .then(() => {
    //        return ee.addTask(rep.event_names.create('bidirect'), data);
    //    })
    //    .then((res) => {
    //        //                console.log("SETTINGS", res);
    //        var evdata = _.clone(data);
    //        evdata.settings = {
    //            docBatchSizeKb: 512,
    //            checkpointInterval: 10 //please, do not use this in production until you're all sure about your hardware
    //        };
    //        return ee.addTask(rep.event_names.settings, evdata);
    //    })
    //    .delay(timeo)
    //    .then((res) => {
    //        var evdata = _.clone(data);
    //        evdata.stat_name = "percent_completeness";
    //        return ee.addTask(rep.event_names.stats, evdata);
    //    })
    //    .delay(timeo)
    //    .then((res) => {
    //        return ee.addTask(broker.event_names.resources, {
    //            start: 1,
    //            end: 8
    //        });
    //    })
    .delay(timeo)
    .then((range) => {
        console.log("RESPONDED WITH", range);
        var requested = _.sample(_.pairs(_.reduce(range, (res, val, key) => {
            if (val.value.state == "idle") {
                res[key] = val;
            }
            return res;
        }, {})));
        console.log("TAKING", requested);
        return act(requested, attempts, "book");
    })
    .delay(timeo)
    .then((res) => {
        console.log("BOOK RESPONSE :", res);
        return act([res.db_id, res.data], attempts, "free");
    })
    .delay(timeo)
    .then((res) => {
        console.log("FREE RESPONSE:", res);
    })
    .then((res) => {
        return ee.addTask(broker.event_names.resources, {
            start: 1,
            end: 8
        });
    })
    .delay(timeo)
    .then((range) => {
        console.log("RESPONDED WITH", range);
        var requested = _.sample(_.pairs(_.reduce(range, (res, val, key) => {
            if (val.value.state == "idle") {
                res[key] = val;
            }
            return res;
        }, {})));
        console.log("TAKING", requested);
        return act(requested, attempts, "book");
    })
    .delay(timeo)
    .then((res) => {
        console.log("BOOK RESPONSE :", res);
        return act([res.db_id, res.data], attempts, "free");
    })
    .delay(timeo)
    .then((res) => {
        console.log("FREE RESPONSE:", res);
    })
    .then((res) => {
        return ee.addTask(broker.event_names.resources, {
            start: 1,
            end: 8
        });
    })
    .delay(timeo)
    .then((range) => {
        console.log("RESPONDED WITH", range);
        var requested = _.sample(_.pairs(_.reduce(range, (res, val, key) => {
            if (val.value.state == "idle") {
                res[key] = val;
            }
            return res;
        }, {})));
        console.log("TAKING", requested);
        return act(requested, attempts, "book");
    })
    .delay(timeo)
    .then((res) => {
        console.log("BOOK RESPONSE :", res);
        return act([res.db_id, res.data], attempts, "free");
    })
    .delay(timeo)
    .then((res) => {
        console.log("FREE RESPONSE:", res);
    })
    .catch((err) => {
        console.log("ERRORRR", err.stack)
    })
    //    .delay(timeo)
    //    .then(() => {
    //        return ee.addTask(rep.event_names.pause('bidirect'), data);
    //    })
    //    .then((res) => {
    //        console.log("REP PAUSE:", res);
    //    });<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.layout',
  name: 'Grid',
  extends: 'foam.u2.Element',
  documentation: `
    A grid of responsive elements
  `,

  imports: [
    'displayWidth?'
  ],

  requires: [
    'foam.u2.layout.GUnit'
  ],

  css: `
    ^ {
      display: grid;
    }
  `,

  properties: [
    {
      class: 'Int',
      name: 'currentWidth',
      value: 0
    }
  ],

  methods: [
    function initE() {
      this.SUPER();
      this.addClass(this.myClass());
      this.style({ 'grid-template-columns': this.displayWidth$.map(dw => {
        dw = dw || foam.u2.layout.DisplayWidth.XL;
        return `repeat(${dw.cols}, 1fr)`;
      }) })
    },

    function createChild_(spec, args){
      var ret = this.SUPER(spec, args);

      var width = this.GUnit.isInstance(ret)
        ? ret[`${this.displayWidth.name.toLowerCase()}Columns`]
        : this.displayWidth.cols;

      var startCol = this.currentWidth + 1;
      this.currentWidth += width;

      if ( this.currentWidth > this.displayWidth.cols ) {
        startCol = 1;
        this.currentWidth = width;
      }

      var endCol = startCol + width;

      ret.style({
        'grid-column-start': startCol,
        'grid-column-end': endCol,
      });

      return ret;
    }
  ]
});
<commit_msg>Added in specification for row and column gaps in the grid model<commit_after>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2.layout',
  name: 'Grid',
  extends: 'foam.u2.Element',
  documentation: `
    A grid of responsive elements
  `,

  imports: [
    'displayWidth?'
  ],

  requires: [
    'foam.u2.layout.GUnit'
  ],

  css: `
    ^ {
      display: grid;
    }
  `,

  properties: [
    {
      class: 'Int',
      name: 'currentWidth',
      value: 0
    },
    {
      class: 'String',
      name: 'columnGap',
      value: '16px'
    },
    {
      class: 'String',
      name: 'rowGap',
      value: '32px'
    }
  ],

  methods: [
    function initE() {
      this.SUPER();
      this.addClass(this.myClass());
      this.style(
        { 'grid-template-columns': this.displayWidth$.map(dw => {
            dw = dw || foam.u2.layout.DisplayWidth.XL;
            return `repeat(${dw.cols}, 1fr)`;
          }),
          'grid-row-gap': this.rowGap,
          'grid-column-gap': this.columnGap
        }
      )
    },

    function createChild_(spec, args){
      var ret = this.SUPER(spec, args);

      var width = this.GUnit.isInstance(ret)
        ? ret[`${this.displayWidth.name.toLowerCase()}Columns`]
        : this.displayWidth.cols;

      var startCol = this.currentWidth + 1;
      this.currentWidth += width;

      if ( this.currentWidth > this.displayWidth.cols ) {
        startCol = 1;
        this.currentWidth = width;
      }

      var endCol = startCol + width;

      ret.style({
        'grid-column-start': startCol,
        'grid-column-end': endCol,
      });

      return ret;
    }
  ]
});
<|endoftext|>


<commit_before>// Copyright 2011 Joyent, Inc.  All rights reserved.

var util = require('util');
var ldap = require('ldapjs');

var Validator = require('../lib/schema/validator');

var UUID_RE = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
var ALIAS_RE = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
var MAX_ZFS_IO = 1000;

///--- Validation helpers

function validUUID(uuid) {
  return UUID_RE.test(uuid);
}

function validAlias(alias) {
  return ALIAS_RE.test(alias);
}

function validNumber(attr) {
  var number = parseInt(attr);
  return (number > 0 ? true : false);
}

function validType(type) {
  return (type == "zone" || type == "vm");
}

var NUMBER_ATTRS = {
  ram: "RAM",
  swap: "Swap",
  disk: "Disk",
  lwps: "Lightweight Processes",
  cpushares: "CPU Shares",
  zfsiopriority: "ZFS IO Priority"
};

///--- API

function Machine() {
  Validator.call(this, {
    name: 'machine',
    required: {
      uuid: 1,
      type: 1,
      brand: 1,
      ram: 1,
      disk: 1,
      swap: 1,
      lwps: 1,
      cpushares: 1,
      zfsiopriority: 1,
    },
    optional: {
      alias: 1,
      zonepath: 1,
      datasetuuid: 1,
      serveruuid: 1,
      autoboot: 1,
      datasets: 0,
      nics: 0,
      internalmetadata: 1,
      customermetadata: 1,
      delegatedataset: 1,
      disks: 0,
      vcpus: 1,
      cpucap: 1,
      status: 1,
      setup: 1,
      destroyed: 1
    }
  });
}
util.inherits(Machine, Validator);

Machine.prototype.validate = function(entry, callback) {
  var keys = Object.keys(NUMBER_ATTRS);
  var attrs = entry.attributes;
  var i;
  var errors = [];

  if (!validUUID(attrs.uuid[0])) {
    errors.push("Machine uuid: '" + attrs.uuid[0] + "' is invalid "
        + "(must be a UUID)");
  }

  for (i = 0; i < keys.length; i++) {
    var key = keys[i];

    if (!validNumber(attrs[key][0])) {
      errors.push(NUMBER_ATTRS[key] + ": '" + attrs[key][0] + "' is invalid "
          + "(must be a positive number)");
    }
  }

  if (attrs.type != undefined && typeof(attrs.type[0]) == "string"
        && !validType(attrs.type[0])) {
    errors.push("Machine type: '" + attrs.alias[0] + "' is invalid, "
      + "must be either 'zone' or 'vm'");
  }

  if (parseInt(attrs.swap[0]) < parseInt(attrs.ram[0])) {
    errors.push("Swap: '" + attrs.swap[0] + "' is invalid "
        + "(cannot be less than RAM: " + attrs.ram[0] + ")");
  }

  if (attrs.zfsiopriority[0] > MAX_ZFS_IO) {
    errors.push("ZFS IO Priority: '" + attrs.zfsiopriority[0] + "' is invalid "
        + "(cannot be greater than " + MAX_ZFS_IO + ")");
  }

  if (attrs.alias != undefined && typeof(attrs.alias[0]) == "string"
        && !validAlias(attrs.alias[0])) {
    errors.push("Machine alias: '" + attrs.alias[0] + "' is invalid");
  }

  if (attrs.vcpus != undefined && !validNumber(attrs.vcpus[0])) {
    errors.push("Virtual CPUs: '" + attrs.vcpus[0] + "' is invalid "
        + "(must be a positive number)");
  }

  if (attrs.cpucap != undefined && !validNumber(attrs.cpucap[0])) {
    errors.push("CPU Cap: '" + attrs.cpucap[0] + "' is invalid "
        + "(must be a positive number)");
  }

  if (errors.length)
    return callback(new ldap.ConstraintViolationError(errors.join('\n')));

  return callback();
};

///--- Exports

module.exports = {
  createInstance: function() {
    return new Machine();
  }
};
<commit_msg>ZAPI-23: Only use brand for machine.js<commit_after>// Copyright 2011 Joyent, Inc.  All rights reserved.

var util = require('util');
var ldap = require('ldapjs');

var Validator = require('../lib/schema/validator');

var UUID_RE = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
var ALIAS_RE = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
var MAX_ZFS_IO = 1000;

///--- Validation helpers

function validUUID(uuid) {
  return UUID_RE.test(uuid);
}

function validAlias(alias) {
  return ALIAS_RE.test(alias);
}

function validNumber(attr) {
  var number = parseInt(attr);
  return (number > 0 ? true : false);
}

function validBrand(brand) {
  return (type == "joyent" || type == "kvm");
}

var NUMBER_ATTRS = {
  ram: "RAM",
  swap: "Swap",
  disk: "Disk",
  lwps: "Lightweight Processes",
  cpushares: "CPU Shares",
  zfsiopriority: "ZFS IO Priority"
};

///--- API

function Machine() {
  Validator.call(this, {
    name: 'machine',
    required: {
      uuid: 1,
      brand: 1,
      ram: 1,
      disk: 1,
      swap: 1,
      lwps: 1,
      cpushares: 1,
      zfsiopriority: 1,
    },
    optional: {
      alias: 1,
      zonepath: 1,
      datasetuuid: 1,
      serveruuid: 1,
      autoboot: 1,
      datasets: 0,
      nics: 0,
      internalmetadata: 1,
      customermetadata: 1,
      delegatedataset: 1,
      disks: 0,
      vcpus: 1,
      cpucap: 1,
      status: 1,
      setup: 1,
      destroyed: 1
    }
  });
}
util.inherits(Machine, Validator);

Machine.prototype.validate = function(entry, callback) {
  var keys = Object.keys(NUMBER_ATTRS);
  var attrs = entry.attributes;
  var i;
  var errors = [];

  if (!validUUID(attrs.uuid[0])) {
    errors.push("Machine uuid: '" + attrs.uuid[0] + "' is invalid "
        + "(must be a UUID)");
  }

  for (i = 0; i < keys.length; i++) {
    var key = keys[i];

    if (!validNumber(attrs[key][0])) {
      errors.push(NUMBER_ATTRS[key] + ": '" + attrs[key][0] + "' is invalid "
          + "(must be a positive number)");
    }
  }

  if (attrs.brand != undefined && typeof(attrs.brand[0]) == "string"
        && !validBrand(attrs.brand[0])) {
    errors.push("Machine brand: '" + attrs.alias[0] + "' is invalid, "
      + "must be either 'joyent' or 'kvm'");
  }

  if (parseInt(attrs.swap[0]) < parseInt(attrs.ram[0])) {
    errors.push("Swap: '" + attrs.swap[0] + "' is invalid "
        + "(cannot be less than RAM: " + attrs.ram[0] + ")");
  }

  if (attrs.zfsiopriority[0] > MAX_ZFS_IO) {
    errors.push("ZFS IO Priority: '" + attrs.zfsiopriority[0] + "' is invalid "
        + "(cannot be greater than " + MAX_ZFS_IO + ")");
  }

  if (attrs.alias != undefined && typeof(attrs.alias[0]) == "string"
        && !validAlias(attrs.alias[0])) {
    errors.push("Machine alias: '" + attrs.alias[0] + "' is invalid");
  }

  if (attrs.vcpus != undefined && !validNumber(attrs.vcpus[0])) {
    errors.push("Virtual CPUs: '" + attrs.vcpus[0] + "' is invalid "
        + "(must be a positive number)");
  }

  if (attrs.cpucap != undefined && !validNumber(attrs.cpucap[0])) {
    errors.push("CPU Cap: '" + attrs.cpucap[0] + "' is invalid "
        + "(must be a positive number)");
  }

  if (errors.length)
    return callback(new ldap.ConstraintViolationError(errors.join('\n')));

  return callback();
};

///--- Exports

module.exports = {
  createInstance: function() {
    return new Machine();
  }
};
<|endoftext|>


<commit_before>module.exports = function(version) {
  // This matches stable, dev (with or without commit hash) and any other
  // release channel following the pattern '1.00.0-channel0'
  const match = version.match(
    /\d+\.\d+\.\d+(-([a-z]+)(\d+|-\w{4,})?)?$/
  );
  if (!match) {
    return 'unrecognized';
  } else if (match[2]) {
    return match[2];
  }

  return 'stable';
}
<commit_msg>Fix lint error<commit_after>module.exports = function(version) {
  // This matches stable, dev (with or without commit hash) and any other
  // release channel following the pattern '1.00.0-channel0'
  const match = version.match(/\d+\.\d+\.\d+(-([a-z]+)(\d+|-\w{4,})?)?$/);
  if (!match) {
    return 'unrecognized';
  } else if (match[2]) {
    return match[2];
  }

  return 'stable';
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import GoogleAnalytics from 'react-ga';

const debug = process.env.NODE_ENV === 'development';
GoogleAnalytics.initialize('UA-88223011-3', {debug});

const withTracker = (WrappedComponent, options = {}) => {
  const trackPage = page => {
    GoogleAnalytics.set({
      page,
      ...options,
    });
    GoogleAnalytics.pageview(page);
  };

  const HOC = class extends Component {
    componentDidMount() {
      const page = this.props.location.pathname;
      trackPage(page);
    }

    componentWillReceiveProps(nextProps) {
      const currentPage = this.props.location.pathname;
      const nextPage = nextProps.location.pathname;

      if (currentPage !== nextPage) {
        trackPage(nextPage);
      }
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };

  return HOC;
};

export default withTracker;<commit_msg>flips GA id to step.ideo.org id<commit_after>import React, { Component } from 'react';
import GoogleAnalytics from 'react-ga';

const debug = process.env.NODE_ENV === 'development';
/*
UA-88223011-2 = production
UA-88223011-3 = "dev testing"
*/
GoogleAnalytics.initialize('UA-88223011-2', {debug});

const withTracker = (WrappedComponent, options = {}) => {
  const trackPage = page => {
    GoogleAnalytics.set({
      page,
      ...options,
    });
    GoogleAnalytics.pageview(page);
  };

  const HOC = class extends Component {
    componentDidMount() {
      const page = this.props.location.pathname;
      trackPage(page);
    }

    componentWillReceiveProps(nextProps) {
      const currentPage = this.props.location.pathname;
      const nextPage = nextProps.location.pathname;

      if (currentPage !== nextPage) {
        trackPage(nextPage);
      }
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };

  return HOC;
};

export default withTracker;<|endoftext|>


<commit_before>export const shaderStructs = /* glsl */`
#define TRI_INTERSECT_EPSILON 1e-5

struct BVH {

	usampler2D index;
	sampler2D position;

	sampler2D bvhBounds;
	usampler2D bvhContents;

};

struct Ray {

	vec3 origin;
	vec3 direction;

};

struct Face {

	uint a;
	uint b;
	uint c;
	vec3 normal;

};

struct BVHRayHit {

	Face face;
	vec3 point;
	vec3 barycoord;
	float side;
	float dist;

};
`;

export const shaderIntersectFunction = /* glsl */`

// TODO: use templates for creating these functions?
uvec4 uTexelFetch1D( usampler2D tex, uint index ) {

	uint width = uint( textureSize( tex, 0 ).x );
	uvec2 uv;
	uv.x = index % width;
	uv.y = index / width;

	return texelFetch( tex, ivec2( uv ), 0 );

}

vec4 texelFetch1D( sampler2D tex, uint index ) {

	uint width = uint( textureSize( tex, 0 ).x );
	uvec2 uv;
	uv.x = index % width;
	uv.y = index / width;

	return texelFetch( tex, ivec2( uv ), 0 );

}

Ray ndcToCameraRay( vec2 coord, mat4 cameraWorld, mat4 invProjectionMatrix ) {

	// get camera look direction and near plane for camera clipping
	vec4 lookDirection = cameraWorld * vec4( 0.0, 0.0, - 1.0, 0.0 );
	vec4 nearVector = invProjectionMatrix * vec4( 0.0, 0.0, - 1.0, 1.0 );
	float near = abs( nearVector.z / nearVector.w );

	// get the camera direction and position from camera matrices
	vec4 origin = cameraWorld * vec4( 0.0, 0.0, 0.0, 1.0 );
	vec4 direction = invProjectionMatrix * vec4( coord, 0.5, 1.0 );
	direction /= direction.w;
	direction = cameraWorld * direction - origin;

	// slide the origin along the ray until it sits at the near clip plane position
	origin.xyz += direction.xyz * near / dot( direction, lookDirection );

	return Ray( origin.xyz, direction.xyz );

}

bool intersectsBounds( Ray ray, vec3 boundsMin, vec3 boundsMax, out float dist ) {

	// https://www.reddit.com/r/opengl/comments/8ntzz5/fast_glsl_ray_box_intersection/
	// https://tavianator.com/2011/ray_box.html
	vec3 invDir = 1.0 / ray.direction;

	// find intersection distances for each plane
	vec3 tMinPlane = invDir * ( boundsMin - ray.origin );
	vec3 tMaxPlane = invDir * ( boundsMax - ray.origin );

	// get the min and max distances from each intersection
	vec3 tMinHit = min( tMaxPlane, tMinPlane );
	vec3 tMaxHit = max( tMaxPlane, tMinPlane );

	// get the furthest hit distance
	vec2 t = max( tMinHit.xx, tMinHit.yz );
	float t0 = max( t.x, t.y );

	// get the minimum hit distance
	t = min( tMaxHit.xx, tMaxHit.yz );
	float t1 = min( t.x, t.y );

	// set distance to 0.0 if the ray starts inside the box
	dist = max( t0, 0.0 );

	return t1 >= max( t0, 0.0 );

}

bool intersectsTriangle( Ray ray, vec3 a, vec3 b, vec3 c, out vec3 barycoord, out vec3 norm, out float dist, out float side ) {

	// https://stackoverflow.com/questions/42740765/intersection-between-line-and-triangle-in-3d
	vec3 edge1 = b - a;
	vec3 edge2 = c - a;
	norm = cross( edge1, edge2 );

	float det = - dot( ray.direction, norm );
	float invdet = 1.0 / det;

	vec3 AO = ray.origin - a;
	vec3 DAO = cross( AO, ray.direction );

	vec4 uvt;
	uvt.x = dot( edge2, DAO ) * invdet;
	uvt.y = - dot( edge1, DAO ) * invdet;
	uvt.z = dot( AO, norm ) * invdet;
	uvt.w = 1.0 - uvt.x - uvt.y;

	// set the hit information
	barycoord = uvt.xyw;
	dist = uvt.z;
	side = sign( det );
	norm = normalize( norm );

	// add an epsilon to avoid misses between triangles
	uvt += vec4( TRI_INTERSECT_EPSILON );

	return all( greaterThanEqual( uvt, vec4( 0.0 ) ) );

}

bool intersectTriangles( BVH bvh, Ray ray, uint offset, uint count, inout float minDistance, out BVHRayHit hit ) {

	bool found = false;
	vec3 barycoord, norm;
	float dist, side;
	for ( uint i = offset, l = offset + count; i < l; i ++ ) {

		uint index3 = i * 3u;
		uint i0 = uTexelFetch1D( bvh.index, index3 + 0u ).r;
		uint i1 = uTexelFetch1D( bvh.index, index3 + 1u ).r;
		uint i2 = uTexelFetch1D( bvh.index, index3 + 2u ).r;

		vec3 a = texelFetch1D( bvh.position, i0 ).rgb;
		vec3 b = texelFetch1D( bvh.position, i1 ).rgb;
		vec3 c = texelFetch1D( bvh.position, i2 ).rgb;

		if ( intersectsTriangle( ray, a, b, c, barycoord, norm, dist, side ) && dist < minDistance ) {

			found = true;
			minDistance = dist;
			hit.face.a = i0;
			hit.face.b = i1;
			hit.face.c = i2;
			hit.face.normal = norm;

			hit.side = side;
			hit.barycoord = barycoord;
			hit.dist = dist;
			hit.point = ray.origin + ray.direction * dist;

		}

	}

	return found;

}

bool bvhIntersect( BVH bvh, Ray ray, bool anyHit, out BVHRayHit hit ) {

	// stack needs to be twice as long as the deepest tree we expect because
	// we push both the left and right child onto the stack every traversal
	int ptr = 0;
	uint stack[ 60 ];
	stack[ 0 ] = 0u;

	float triangleDistance = 1e20;
	bool found = false;
	while ( ptr > - 1 && ptr < 60 ) {

		uint currNodeIndex = stack[ ptr ];
		ptr --;

		// check if we intersect the current bounds
		float boundsHitDistance;
		vec3 boundsMin = texelFetch1D( bvh.bvhBounds, currNodeIndex * 2u + 0u ).xyz;
		vec3 boundsMax = texelFetch1D( bvh.bvhBounds, currNodeIndex * 2u + 1u ).xyz;
		if ( ! intersectsBounds( ray, boundsMin, boundsMax, boundsHitDistance ) || boundsHitDistance > triangleDistance ) {

			continue;

		}

		uvec2 boundsInfo = uTexelFetch1D( bvh.bvhContents, currNodeIndex ).xy;
		bool isLeaf = bool( boundsInfo.x & 0xffff0000u );

		if ( isLeaf ) {

			uint count = boundsInfo.x & 0x0000ffffu;
			uint offset = boundsInfo.y;

			found = intersectTriangles( bvh, ray, offset, count, triangleDistance, hit ) || found;

			// TODO: Should an "any hit" variation of the function be created?
			if ( found && anyHit ) {

				return true;

			}

		} else {

			uint leftIndex = currNodeIndex + 1u;
			uint splitAxis = boundsInfo.x & 0x0000ffffu;
			uint rightIndex = boundsInfo.y;

			bool leftToRight = ray.direction[ splitAxis ] >= 0.0;
			uint c1 = leftToRight ? leftIndex : rightIndex;
			uint c2 = leftToRight ? rightIndex : leftIndex;

			// set c2 in the stack so we traverse it later. We need to keep track of a pointer in
			// the stack while we traverse. The second pointer added is the one that will be
			// traversed first
			ptr ++;
			stack[ ptr ] = c2;

			ptr ++;
			stack[ ptr ] = c1;

		}

	}

	return found;

}

bool bvhIntersectFirstHit( BVH bvh, Ray ray, out BVHRayHit hit ) {

	return bvhIntersect( bvh, ray, false, hit );

}

bool bvhIntersectAnyHit( BVH bvh, Ray ray, out BVHRayHit hit ) {

	return bvhIntersect( bvh, ray, true, hit );

}
`;
<commit_msg>Added functions<commit_after>export const shaderStructs = /* glsl */`
#define TRI_INTERSECT_EPSILON 1e-5

struct BVH {

	usampler2D index;
	sampler2D position;

	sampler2D bvhBounds;
	usampler2D bvhContents;

};

struct Ray {

	vec3 origin;
	vec3 direction;

};

struct Face {

	uint a;
	uint b;
	uint c;
	vec3 normal;

};

struct BVHRayHit {

	Face face;
	vec3 point;
	vec3 barycoord;
	float side;
	float dist;

};
`;

export const shaderIntersectFunction = /* glsl */`

uvec4 uTexelFetch1D( usampler2D tex, uint index ) {

	uint width = uint( textureSize( tex, 0 ).x );
	uvec2 uv;
	uv.x = index % width;
	uv.y = index / width;

	return texelFetch( tex, ivec2( uv ), 0 );

}

ivec4 iTexelFetch1D( isampler2D tex, uint index ) {

	uint width = uint( textureSize( tex, 0 ).x );
	uvec2 uv;
	uv.x = index % width;
	uv.y = index / width;

	return texelFetch( tex, ivec2( uv ), 0 );

}

vec4 texelFetch1D( sampler2D tex, uint index ) {

	uint width = uint( textureSize( tex, 0 ).x );
	uvec2 uv;
	uv.x = index % width;
	uv.y = index / width;

	return texelFetch( tex, ivec2( uv ), 0 );

}

vec4 textureSampleBarycoord( sampler2D tex, vec3 barycoord, uint a, uint b, uint c ) {

	return
		barycoord.x * texelFetch1D( tex, a ) +
		barycoord.y * texelFetch1D( tex, b ) +
		barycoord.z * texelFetch1D( tex, c );

}

Ray ndcToCameraRay( vec2 coord, mat4 cameraWorld, mat4 invProjectionMatrix ) {

	// get camera look direction and near plane for camera clipping
	vec4 lookDirection = cameraWorld * vec4( 0.0, 0.0, - 1.0, 0.0 );
	vec4 nearVector = invProjectionMatrix * vec4( 0.0, 0.0, - 1.0, 1.0 );
	float near = abs( nearVector.z / nearVector.w );

	// get the camera direction and position from camera matrices
	vec4 origin = cameraWorld * vec4( 0.0, 0.0, 0.0, 1.0 );
	vec4 direction = invProjectionMatrix * vec4( coord, 0.5, 1.0 );
	direction /= direction.w;
	direction = cameraWorld * direction - origin;

	// slide the origin along the ray until it sits at the near clip plane position
	origin.xyz += direction.xyz * near / dot( direction, lookDirection );

	return Ray( origin.xyz, direction.xyz );

}

bool intersectsBounds( Ray ray, vec3 boundsMin, vec3 boundsMax, out float dist ) {

	// https://www.reddit.com/r/opengl/comments/8ntzz5/fast_glsl_ray_box_intersection/
	// https://tavianator.com/2011/ray_box.html
	vec3 invDir = 1.0 / ray.direction;

	// find intersection distances for each plane
	vec3 tMinPlane = invDir * ( boundsMin - ray.origin );
	vec3 tMaxPlane = invDir * ( boundsMax - ray.origin );

	// get the min and max distances from each intersection
	vec3 tMinHit = min( tMaxPlane, tMinPlane );
	vec3 tMaxHit = max( tMaxPlane, tMinPlane );

	// get the furthest hit distance
	vec2 t = max( tMinHit.xx, tMinHit.yz );
	float t0 = max( t.x, t.y );

	// get the minimum hit distance
	t = min( tMaxHit.xx, tMaxHit.yz );
	float t1 = min( t.x, t.y );

	// set distance to 0.0 if the ray starts inside the box
	dist = max( t0, 0.0 );

	return t1 >= max( t0, 0.0 );

}

bool intersectsTriangle( Ray ray, vec3 a, vec3 b, vec3 c, out vec3 barycoord, out vec3 norm, out float dist, out float side ) {

	// https://stackoverflow.com/questions/42740765/intersection-between-line-and-triangle-in-3d
	vec3 edge1 = b - a;
	vec3 edge2 = c - a;
	norm = cross( edge1, edge2 );

	float det = - dot( ray.direction, norm );
	float invdet = 1.0 / det;

	vec3 AO = ray.origin - a;
	vec3 DAO = cross( AO, ray.direction );

	vec4 uvt;
	uvt.x = dot( edge2, DAO ) * invdet;
	uvt.y = - dot( edge1, DAO ) * invdet;
	uvt.z = dot( AO, norm ) * invdet;
	uvt.w = 1.0 - uvt.x - uvt.y;

	// set the hit information
	barycoord = uvt.xyw;
	dist = uvt.z;
	side = sign( det );
	norm = normalize( norm );

	// add an epsilon to avoid misses between triangles
	uvt += vec4( TRI_INTERSECT_EPSILON );

	return all( greaterThanEqual( uvt, vec4( 0.0 ) ) );

}

bool intersectTriangles( BVH bvh, Ray ray, uint offset, uint count, inout float minDistance, out BVHRayHit hit ) {

	bool found = false;
	vec3 barycoord, norm;
	float dist, side;
	for ( uint i = offset, l = offset + count; i < l; i ++ ) {

		uint index3 = i * 3u;
		uint i0 = uTexelFetch1D( bvh.index, index3 + 0u ).r;
		uint i1 = uTexelFetch1D( bvh.index, index3 + 1u ).r;
		uint i2 = uTexelFetch1D( bvh.index, index3 + 2u ).r;

		vec3 a = texelFetch1D( bvh.position, i0 ).rgb;
		vec3 b = texelFetch1D( bvh.position, i1 ).rgb;
		vec3 c = texelFetch1D( bvh.position, i2 ).rgb;

		if ( intersectsTriangle( ray, a, b, c, barycoord, norm, dist, side ) && dist < minDistance ) {

			found = true;
			minDistance = dist;
			hit.face.a = i0;
			hit.face.b = i1;
			hit.face.c = i2;
			hit.face.normal = norm;

			hit.side = side;
			hit.barycoord = barycoord;
			hit.dist = dist;
			hit.point = ray.origin + ray.direction * dist;

		}

	}

	return found;

}

bool bvhIntersect( BVH bvh, Ray ray, bool anyHit, out BVHRayHit hit ) {

	// stack needs to be twice as long as the deepest tree we expect because
	// we push both the left and right child onto the stack every traversal
	int ptr = 0;
	uint stack[ 60 ];
	stack[ 0 ] = 0u;

	float triangleDistance = 1e20;
	bool found = false;
	while ( ptr > - 1 && ptr < 60 ) {

		uint currNodeIndex = stack[ ptr ];
		ptr --;

		// check if we intersect the current bounds
		float boundsHitDistance;
		vec3 boundsMin = texelFetch1D( bvh.bvhBounds, currNodeIndex * 2u + 0u ).xyz;
		vec3 boundsMax = texelFetch1D( bvh.bvhBounds, currNodeIndex * 2u + 1u ).xyz;
		if ( ! intersectsBounds( ray, boundsMin, boundsMax, boundsHitDistance ) || boundsHitDistance > triangleDistance ) {

			continue;

		}

		uvec2 boundsInfo = uTexelFetch1D( bvh.bvhContents, currNodeIndex ).xy;
		bool isLeaf = bool( boundsInfo.x & 0xffff0000u );

		if ( isLeaf ) {

			uint count = boundsInfo.x & 0x0000ffffu;
			uint offset = boundsInfo.y;

			found = intersectTriangles( bvh, ray, offset, count, triangleDistance, hit ) || found;

			// TODO: Should an "any hit" variation of the function be created?
			if ( found && anyHit ) {

				return true;

			}

		} else {

			uint leftIndex = currNodeIndex + 1u;
			uint splitAxis = boundsInfo.x & 0x0000ffffu;
			uint rightIndex = boundsInfo.y;

			bool leftToRight = ray.direction[ splitAxis ] >= 0.0;
			uint c1 = leftToRight ? leftIndex : rightIndex;
			uint c2 = leftToRight ? rightIndex : leftIndex;

			// set c2 in the stack so we traverse it later. We need to keep track of a pointer in
			// the stack while we traverse. The second pointer added is the one that will be
			// traversed first
			ptr ++;
			stack[ ptr ] = c2;

			ptr ++;
			stack[ ptr ] = c1;

		}

	}

	return found;

}

bool bvhIntersectFirstHit( BVH bvh, Ray ray, out BVHRayHit hit ) {

	return bvhIntersect( bvh, ray, false, hit );

}

bool bvhIntersectAnyHit( BVH bvh, Ray ray, out BVHRayHit hit ) {

	return bvhIntersect( bvh, ray, true, hit );

}
`;
<|endoftext|>