<commit_before>module.exports = function(r) {
    const dbExec = require('./run');
    const db = require('./db')(r);
    const model = require('./model')(r);
    const commonQueries = require('./common-queries');

    return {
        getDatasetsForExperiment,
        getDataset,
        createDatasetForExperiment,
        addSampleToDataset,
        updateSamplesInDataset,
        allSamplesInDataset,
        modifyDataset,
        publishDataset
    };

    function* getDatasetsForExperiment(experimentId) {
        let rql = commonQueries.datasetDetailsRql(r.table('experiment2dataset').getAll(experimentId, {index: 'experiment_id'})
            .eqJoin('dataset_id', r.table('datasets')).zip(), r);
        let dataset = yield dbExec(rql);
        return {val: dataset};
    }

    function* getDataset(datasetId) {
        let rql = commonQueries.datasetDetailsRql(r.table('datasets').get(datasetId), r);
        let dataset = yield dbExec(rql);
        return {val: dataset};
    }

    function* createDatasetForExperiment(experimentId, userId, datasetArgs) {
        let dataset = new model.Dataset(datasetArgs.title, userId);
        dataset.description = datasetArgs.description;
        let created = yield db.insert('datasets', dataset);
        let e2d = new model.Experiment2Dataset(experimentId, created.id);
        yield r.table('experiment2dataset').insert(e2d);
        return yield getDataset(created.id);
    }

    function* addSampleToDataset(datasetId, sampleId) {
        let d2s = new model.Dataset2Sample(datasetId, sampleId);
        yield r.table('dataset2sample').insert(d2s);
        return yield getDataset(datasetId);
    }

    function* updateSamplesInDataset(datasetId, samplesToAdd, samplesToDelete) {
        if (samplesToAdd.length) {
            let add = samplesToAdd.map(s => new model.Dataset2Sample(datasetId, s.id));
            add = yield removeExistingSampleEntriesInDataset(add);
            if (add.length) {
                yield r.table('dataset2sample').insert(add);
            }
        }

        if (samplesToDelete.length) {
            let toDelete = samplesToDelete.map(s => [datasetId, s.id]);
            yield r.table('dataset2sample').getAll(r.args(toDelete), {index: 'dataset_sample'}).delete();
        }

        return yield getDataset(datasetId);
    }

    function* removeExistingSampleEntriesInDataset(samplesToAdd) {
        if (samplesToAdd.length) {
            let indexEntries = samplesToAdd.map(s => [s]);
            let matchingEntries = yield r.table('dataset2sample').getAll(r.args(indexEntries), {index: 'dataset_sample'});
            let bySampleId = _.indexBy(matchingEntries, 'sample_id');
            return samplesToAdd.filter(s => (!(s.sample_id in bySampleId)));
        }

        return samplesToAdd;
    }

    function* allSamplesInDataset(datasetId, sampleIds) {
        let indexArgs = sampleIds.map(sid => [datasetId, sid]);
        let samples = yield r.table('dataset2sample').getAll(r.args(indexArgs), {index: 'dataset_sample'});
        return samples.length === sampleIds.length;
    }

    function* modifyDataset(datasetId, datasetArgs) {
        yield r.table('datasets').get(datasetId).update(datasetArgs);
        return yield getDataset(datasetId);
    }

    function* publishDataset() {
        return {error: `Not implemented`};
    }
};
<commit_msg>Rename variable to better convey its meaning.<commit_after>module.exports = function(r) {
    const dbExec = require('./run');
    const db = require('./db')(r);
    const model = require('./model')(r);
    const commonQueries = require('./common-queries');

    return {
        getDatasetsForExperiment,
        getDataset,
        createDatasetForExperiment,
        addSampleToDataset,
        updateSamplesInDataset,
        allSamplesInDataset,
        modifyDataset,
        publishDataset
    };

    function* getDatasetsForExperiment(experimentId) {
        let rql = commonQueries.datasetDetailsRql(r.table('experiment2dataset').getAll(experimentId, {index: 'experiment_id'})
            .eqJoin('dataset_id', r.table('datasets')).zip(), r);
        let dataset = yield dbExec(rql);
        return {val: dataset};
    }

    function* getDataset(datasetId) {
        let rql = commonQueries.datasetDetailsRql(r.table('datasets').get(datasetId), r);
        let dataset = yield dbExec(rql);
        return {val: dataset};
    }

    function* createDatasetForExperiment(experimentId, userId, datasetArgs) {
        let dataset = new model.Dataset(datasetArgs.title, userId);
        dataset.description = datasetArgs.description;
        let created = yield db.insert('datasets', dataset);
        let e2d = new model.Experiment2Dataset(experimentId, created.id);
        yield r.table('experiment2dataset').insert(e2d);
        return yield getDataset(created.id);
    }

    function* addSampleToDataset(datasetId, sampleId) {
        let d2s = new model.Dataset2Sample(datasetId, sampleId);
        yield r.table('dataset2sample').insert(d2s);
        return yield getDataset(datasetId);
    }

    function* updateSamplesInDataset(datasetId, samplesToAdd, samplesToDelete) {
        if (samplesToAdd.length) {
            let add = samplesToAdd.map(s => new model.Dataset2Sample(datasetId, s.id));
            add = yield removeExistingSampleEntriesInDataset(add);
            if (add.length) {
                yield r.table('dataset2sample').insert(add);
            }
        }

        if (samplesToDelete.length) {
            let toDelete = samplesToDelete.map(s => [datasetId, s.id]);
            yield r.table('dataset2sample').getAll(r.args(toDelete), {index: 'dataset_sample'}).delete();
        }

        return yield getDataset(datasetId);
    }

    function* removeExistingSampleEntriesInDataset(samplesToAdd) {
        if (samplesToAdd.length) {
            let indexEntries = samplesToAdd.map(s => [s]);
            let matchingEntries = yield r.table('dataset2sample').getAll(r.args(indexEntries), {index: 'dataset_sample'});
            let matchingEntriesBySampleId = _.indexBy(matchingEntries, 'sample_id');
            return samplesToAdd.filter(s => (!(s.sample_id in matchingEntriesBySampleId)));
        }

        return samplesToAdd;
    }

    function* allSamplesInDataset(datasetId, sampleIds) {
        let indexArgs = sampleIds.map(sid => [datasetId, sid]);
        let samples = yield r.table('dataset2sample').getAll(r.args(indexArgs), {index: 'dataset_sample'});
        return samples.length === sampleIds.length;
    }

    function* modifyDataset(datasetId, datasetArgs) {
        yield r.table('datasets').get(datasetId).update(datasetArgs);
        return yield getDataset(datasetId);
    }

    function* publishDataset() {
        return {error: `Not implemented`};
    }
};
<|endoftext|>


<commit_before>import AdyenStrategy from './strategy/adyen';
import BraintreeStrategy from './strategy/braintree';
import CybersourceStrategy from './strategy/cybersource';
import errors from '../../errors';
import find from 'component-find';
import Promise from 'promise';
import RiskConcern from '../risk-concern';
import SagePayStrategy from './strategy/sage-pay';
import StripeStrategy from './strategy/stripe';
import TestStrategy from './strategy/test';
import WirecardStrategy from './strategy/wirecard';
import WorldpayStrategy from './strategy/worldpay';
import OrbitalStrategy from './strategy/orbital';

const debug = require('debug')('recurly:risk:three-d-secure');

export function factory (options) {
  return new ThreeDSecure({ risk: this, ...options });
}

/**
 * 3D Secure 2.0
 *
 * Usage
 *
 * ```
 * const risk = recurly.Risk();
 * const threeDSecure = risk.ThreeDSecure({ actionTokenId: 'my-action-token-id' });
 *
 * threeDSecure.on('token', token => token);
 * threeDSecure.on('error', err => err);
 *
 * threeDSecure.attach(document.querySelector('#my-checkout-3ds-container'));
 * ```
 *
 * @param {Risk} risk
 * @param {String} [actionTokenId] when given, the concern will parse any auth actions
 *                                 necessary to fulfull the action
 */
export class ThreeDSecure extends RiskConcern {
  concernName = 'three-d-secure';

  static STRATEGIES = [
    AdyenStrategy,
    BraintreeStrategy,
    CybersourceStrategy,
    SagePayStrategy,
    StripeStrategy,
    TestStrategy,
    WirecardStrategy,
    WorldpayStrategy,
    OrbitalStrategy,
  ];

  /**
   * Returns a strateggy for a given gateway type
   *
   * @param  {String} type
   * @return {ThreeDSecureStrategy}
   */
  static getStrategyForGatewayType (type) {
    return find(ThreeDSecure.STRATEGIES, s => s.strategyName === type);
  }

  /**
   * Performs preflight procedures per strategy
   *
   * @typedef  {Object} Preflights
   * @property {Object} gateway
   * @property {String} gateway.type  e.g. 'worldpay'
   * @property {Object} params        params required by the strategy
   *
   * @param {Recurly}    options.recurly
   * @param {String}     options.bin         credit card BIN
   * @param {Preflights} options.preflights
   * @return {Promise}
   */
  static preflight ({ recurly, number, month, year, preflights }) {
    const finished_preflights = [];
    return preflights.reduce((preflight, result) => {
      return preflight.then(() => {
        const { type } = result.gateway;
        const { gateway_code } = result.params;
        const strategy = ThreeDSecure.getStrategyForGatewayType(type);
        return strategy.preflight({ recurly, number, month, year, ...result.params })
          .then(results =>{
            finished_preflights.push({ processor: type, gateway_code,  results });
            return finished_preflights;
          });
      });
    }, Promise.resolve())
}

  constructor ({ risk, actionTokenId }) {
    super({ risk });

    this.actionTokenId = actionTokenId;

    if (!actionTokenId) {
      throw errors('invalid-option', { name: 'actionTokenId', expect: 'a three_d_secure_action_token_id' });
    }

    this.recurly.request.get({ route: `/tokens/${actionTokenId}` })
      .catch(err => this.error(err))
      .then(token => {
        assertIsActionToken(token);
        this.strategy = this.getStrategyForActionToken(token);
        this.strategy.on('done', (...args) => this.onStrategyDone(...args));
        this.markReady();
      })
      .catch(err => this.error(err));

    this.report('create', { actionTokenId });
    this.whenReady(() => this.report('ready', { strategy: this.strategy.strategyName }));
  }

  /**
   * Instructs the strategy to attach, awaiting readiness of the strategy
   *
   * @param {HTMLElement} container
   */
  attach (container) {
    this.whenReady(() => {
      this.strategy.attach(container);
      this.report('attach');
    });
  }

  remove () {
    this.whenReady(() => {
      this.strategy.remove();
      this.report('remove');
    });
  }

  /**
   * Determines which strategy to employ based on an ThreeDSecureActionToken
   *
   * @private
   * @param {Object} actionToken
   */
  getStrategyForActionToken (actionToken) {
    const strategy = ThreeDSecure.getStrategyForGatewayType(actionToken.gateway.type);
    return new strategy({ threeDSecure: this, actionToken });
  }

  /**
   * Creates a ThreeDSecureActionResultToken from action results
   *
   * @private
   * @param {Object} results
   * @param {Function} done callback
   * @return {Promise} to create the token
   */
  createResultToken (results) {
    const data = {
      type: 'three_d_secure_action_result',
      three_d_secure_action_token_id: this.actionTokenId,
      results
    };
    debug('submitting results for tokenization', data);
    return this.recurly.request.post({ route: '/tokens', data });
  }

  // Listeners

  /**
   * Called when a strategy has produced results
   *
   * @param {Object} results
   */
  onStrategyDone (results) {
    this.createResultToken(results)
      .catch(cause => this.error('3ds-result-tokenization-error', { cause }))
      .then(token => {
        debug('Result token', token);
        this.emit('token', token);
        this.report('done', { actionResultTokenId: token.id });
      })
      .done();
  }
}

function assertIsActionToken (token) {
  if (token && token.type === 'three_d_secure_action') return;
  throw errors('invalid-option', { name: 'actionTokenId', expect: 'a three_d_secure_action_token_id' });
}
<commit_msg>fix linter errors<commit_after>import AdyenStrategy from './strategy/adyen';
import BraintreeStrategy from './strategy/braintree';
import CybersourceStrategy from './strategy/cybersource';
import errors from '../../errors';
import find from 'component-find';
import Promise from 'promise';
import RiskConcern from '../risk-concern';
import SagePayStrategy from './strategy/sage-pay';
import StripeStrategy from './strategy/stripe';
import TestStrategy from './strategy/test';
import WirecardStrategy from './strategy/wirecard';
import WorldpayStrategy from './strategy/worldpay';
import OrbitalStrategy from './strategy/orbital';

const debug = require('debug')('recurly:risk:three-d-secure');

export function factory (options) {
  return new ThreeDSecure({ risk: this, ...options });
}

/**
 * 3D Secure 2.0
 *
 * Usage
 *
 * ```
 * const risk = recurly.Risk();
 * const threeDSecure = risk.ThreeDSecure({ actionTokenId: 'my-action-token-id' });
 *
 * threeDSecure.on('token', token => token);
 * threeDSecure.on('error', err => err);
 *
 * threeDSecure.attach(document.querySelector('#my-checkout-3ds-container'));
 * ```
 *
 * @param {Risk} risk
 * @param {String} [actionTokenId] when given, the concern will parse any auth actions
 *                                 necessary to fulfull the action
 */
export class ThreeDSecure extends RiskConcern {
  concernName = 'three-d-secure';

  static STRATEGIES = [
    AdyenStrategy,
    BraintreeStrategy,
    CybersourceStrategy,
    SagePayStrategy,
    StripeStrategy,
    TestStrategy,
    WirecardStrategy,
    WorldpayStrategy,
    OrbitalStrategy,
  ];

  /**
   * Returns a strateggy for a given gateway type
   *
   * @param  {String} type
   * @return {ThreeDSecureStrategy}
   */
  static getStrategyForGatewayType (type) {
    return find(ThreeDSecure.STRATEGIES, s => s.strategyName === type);
  }

  /**
   * Performs preflight procedures per strategy
   *
   * @typedef  {Object} Preflights
   * @property {Object} gateway
   * @property {String} gateway.type  e.g. 'worldpay'
   * @property {Object} params        params required by the strategy
   *
   * @param {Recurly}    options.recurly
   * @param {String}     options.bin         credit card BIN
   * @param {Preflights} options.preflights
   * @return {Promise}
   */
  static preflight ({ recurly, number, month, year, preflights }) {
    const finished_preflights = [];
    return preflights.reduce((preflight, result) => {
      return preflight.then(() => {
        const { type } = result.gateway;
        const { gateway_code } = result.params;
        const strategy = ThreeDSecure.getStrategyForGatewayType(type);
        return strategy.preflight({ recurly, number, month, year, ...result.params })
          .then(results =>{
            finished_preflights.push({ processor: type, gateway_code,  results });
            return finished_preflights;
          });
      });
    }, Promise.resolve());
  }

  constructor ({ risk, actionTokenId }) {
    super({ risk });

    this.actionTokenId = actionTokenId;

    if (!actionTokenId) {
      throw errors('invalid-option', { name: 'actionTokenId', expect: 'a three_d_secure_action_token_id' });
    }

    this.recurly.request.get({ route: `/tokens/${actionTokenId}` })
      .catch(err => this.error(err))
      .then(token => {
        assertIsActionToken(token);
        this.strategy = this.getStrategyForActionToken(token);
        this.strategy.on('done', (...args) => this.onStrategyDone(...args));
        this.markReady();
      })
      .catch(err => this.error(err));

    this.report('create', { actionTokenId });
    this.whenReady(() => this.report('ready', { strategy: this.strategy.strategyName }));
  }

  /**
   * Instructs the strategy to attach, awaiting readiness of the strategy
   *
   * @param {HTMLElement} container
   */
  attach (container) {
    this.whenReady(() => {
      this.strategy.attach(container);
      this.report('attach');
    });
  }

  remove () {
    this.whenReady(() => {
      this.strategy.remove();
      this.report('remove');
    });
  }

  /**
   * Determines which strategy to employ based on an ThreeDSecureActionToken
   *
   * @private
   * @param {Object} actionToken
   */
  getStrategyForActionToken (actionToken) {
    const strategy = ThreeDSecure.getStrategyForGatewayType(actionToken.gateway.type);
    return new strategy({ threeDSecure: this, actionToken });
  }

  /**
   * Creates a ThreeDSecureActionResultToken from action results
   *
   * @private
   * @param {Object} results
   * @param {Function} done callback
   * @return {Promise} to create the token
   */
  createResultToken (results) {
    const data = {
      type: 'three_d_secure_action_result',
      three_d_secure_action_token_id: this.actionTokenId,
      results
    };
    debug('submitting results for tokenization', data);
    return this.recurly.request.post({ route: '/tokens', data });
  }

  // Listeners

  /**
   * Called when a strategy has produced results
   *
   * @param {Object} results
   */
  onStrategyDone (results) {
    this.createResultToken(results)
      .catch(cause => this.error('3ds-result-tokenization-error', { cause }))
      .then(token => {
        debug('Result token', token);
        this.emit('token', token);
        this.report('done', { actionResultTokenId: token.id });
      })
      .done();
  }
}

function assertIsActionToken (token) {
  if (token && token.type === 'three_d_secure_action') return;
  throw errors('invalid-option', { name: 'actionTokenId', expect: 'a three_d_secure_action_token_id' });
}
<|endoftext|>


<commit_before>"use strict";

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/* global React */

var RTable = (function (_React$Component) {
  _inherits(RTable, _React$Component);

  function RTable(props) {
    _classCallCheck(this, RTable);

    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(RTable).call(this, props));

    _this.state = {
      results: []
    };
    _this.loader = new RTable.DataLoader(_this, _this.props.dataUrl);
    return _this;
  }

  _createClass(RTable, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      this.loader.loadInitial();
    }
  }, {
    key: "getValue",
    value: function getValue(row, col) {
      if (col.get) {
        return col.get(row);
      }
      return row[col.name];
    }
  }, {
    key: "render",
    value: function render() {
      var _this2 = this;

      var filters = this.props.filters || [];
      var columns = this.props.columns || [];
      var header = columns.map(function (col, n) {
        return React.createElement(
          "th",
          { key: n, onClick: _this2.loader.fn.orderToggle(col.name) },
          col.label,
          _this2.state.ordering == col.name ? "▲" : _this2.state.ordering == "-" + col.name ? "▼" : null
        );
      });
      var rows = this.state.results.map(function (row, m) {
        var cells = _this2.props.columns.map(function (col, n) {
          return React.createElement(
            "td",
            { key: n },
            _this2.getValue(row, col)
          );
        });
        return React.createElement(
          "tr",
          { key: m },
          cells
        );
      });

      return React.createElement(
        "table",
        { className: "table table-striped table-hover" },
        React.createElement(
          "thead",
          null,
          React.createElement(
            "tr",
            null,
            React.createElement(
              "td",
              { className: "text-center", colSpan: columns.length },
              this.state.hasPrev ? React.createElement(
                "a",
                { className: "btn btn-primary t-prev", href: this.state.prevQuery, onClick: this.loader.fn.prevPage },
                "prev"
              ) : React.createElement(
                "button",
                { className: "btn btn-primary t-prev", disabled: true },
                "prev"
              ),
              ' ',
              "page ",
              this.state.page,
              " of ",
              this.state.pages,
              ", results ",
              this.state.firstResult,
              "-",
              this.state.lastResult,
              " of ",
              this.state.count,
              ' ',
              this.state.hasNext ? React.createElement(
                "a",
                { className: "btn btn-primary t-next", href: this.state.nextQuery, onClick: this.loader.fn.nextPage },
                "next"
              ) : React.createElement(
                "button",
                { className: "btn btn-primary t-next", disabled: true },
                "next"
              )
            )
          ),
          React.createElement(
            "tr",
            { ref: "filterRow" },
            React.createElement(
              "td",
              { className: "form-inline", colSpan: columns.length },
              filters.map(function (filter, i) {
                return React.createElement(
                  "span",
                  { key: i },
                  React.createElement(
                    "label",
                    null,
                    filter.label + ':'
                  ),
                  ' ',
                  filter.choices ? React.createElement(
                    "select",
                    { className: "form-control input-sm ", onInput: _this2.loader.fn.filter(filter.name) },
                    filter.choices.map(function (choice, j) {
                      return React.createElement(
                        "option",
                        { key: j, value: choice.value },
                        choice.label || choice.value
                      );
                    })
                  ) : React.createElement("input", { className: "form-control input-sm", onInput: _this2.loader.fn.filterDelayed(filter.name) }),
                  ' '
                );
              })
            )
          ),
          React.createElement(
            "tr",
            { ref: "columnHeaderRow" },
            header
          )
        ),
        React.createElement(
          "tbody",
          { ref: "rowContainer" },
          rows
        )
      );
    }
  }]);

  return RTable;
})(React.Component);

var DataLoader = (function () {
  function DataLoader(component, baseUrl) {
    var _this3 = this;

    _classCallCheck(this, DataLoader);

    this.component = component;
    this.baseUrl = baseUrl;
    this.filterDelay = 800;
    this.fn = {
      goToPage: this.goToPage.bind(this),
      nextPage: this.nextPage.bind(this),
      prevPage: this.prevPage.bind(this),
      orderBy: function orderBy(column) {
        return function (event) {
          return _this3.orderBy(event, column);
        };
      },
      orderToggle: function orderToggle(column) {
        return function (event) {
          return _this3.orderToggle(event, column);
        };
      },
      filter: function filter(key) {
        return function (event) {
          return _this3.filter(event, key);
        };
      },
      filterDelayed: function filterDelayed(key) {
        return delayed(_this3.filterDelay, function (event) {
          return _this3.filter(event, key);
        });
      }
    };
  }

  _createClass(DataLoader, [{
    key: "loadInitial",
    value: function loadInitial() {
      var data = parseUri(this.getWindowLocation()).queryKey;
      data.page = data.page || "1";
      var url = this.baseUrl;
      for (var k in data) {
        if (data.hasOwnProperty(k)) {
          url = UpdateQueryString(k, data[k], url);
        }
      }this.load(url);
    }
  }, {
    key: "getWindowLocation",
    value: function getWindowLocation() {
      return window.location;
    }
  }, {
    key: "currentState",
    value: function currentState() {
      return this.component.state;
    }
  }, {
    key: "load",
    value: function load(url) {
      var _this4 = this;

      var divideRoundUp = function divideRoundUp(a, b) {
        return Math.floor((a + b - 1) / b);
      };
      var parsedUrl = parseUri(url);
      var urlParams = parsedUrl.queryKey;
      return getJson(url).then(function (response) {
        // have: count, next, previous, results
        response.fullUrl = url;
        response.query = '?' + parsedUrl.query; // TODO drop? use consistently?
        response.page = parseInt(urlParams.page) || 1;
        response.page0 = response.page - 1;
        response.hasNext = !!response.next;
        response.hasPrev = !!response.previous;
        response.nextQuery = UpdateQueryString('page', response.page + 1, response.query);
        response.prevQuery = UpdateQueryString('page', response.page - 1, response.query);
        response.ordering = urlParams.ordering || null;
        if (response.next) {
          var pageSize = response.results.length;
          response.pages = divideRoundUp(response.count, pageSize);
          response.firstResult = pageSize * response.page0 + 1;
          response.lastResult = pageSize * (response.page0 + 1);
        } else {
          response.pages = response.page;
          response.lastResult = response.count;
          response.firstResult = response.count - response.results.length + 1;
        }
        _this4.component.setState(response);
        return response;
      });
    }
  }, {
    key: "goToPage",
    value: function goToPage(event, page) {
      if (event.ctrlKey || event.altKey || event.shiftKey) return;
      event.preventDefault();
      var newDataUrl = UpdateQueryString('page', page, this.currentState().fullUrl);
      var newWindowUrl = UpdateQueryString('page', page, window.location.href);
      if (window.history.replaceState) {
        window.history.replaceState({}, '', newWindowUrl);
      }
      return this.load(newDataUrl);
    }
  }, {
    key: "nextPage",
    value: function nextPage(event) {
      return this.goToPage(event, this.currentState().page + 1);
    }
  }, {
    key: "prevPage",
    value: function prevPage(event) {
      return this.goToPage(event, this.currentState().page - 1);
    }
  }, {
    key: "orderBy",
    value: function orderBy(event, ordering) {
      if (event.ctrlKey || event.altKey || event.shiftKey) return;
      event.preventDefault();
      var newDataUrl = UpdateQueryString('ordering', ordering, this.currentState().fullUrl);
      var newWindowUrl = UpdateQueryString('ordering', ordering, window.location.href);
      if (window.history.replaceState) {
        window.history.replaceState({}, '', newWindowUrl);
      }
      return this.load(newDataUrl);
    }
  }, {
    key: "orderToggle",
    value: function orderToggle(event, ordering) {
      if (!ordering.length) {
        return;
      }
      if (this.currentState().ordering == ordering) {
        if (ordering[0] == '-') {
          ordering = ordering.substr(1);
        } else {
          ordering = '-' + ordering;
        }
      }
      return this.orderBy(event, ordering);
    }
  }, {
    key: "filter",
    value: function filter(event, key) {
      var newFilterValue = event.target.value || null;
      var newDataUrl = UpdateQueryString(key, newFilterValue, this.currentState().fullUrl);
      var newWindowUrl = UpdateQueryString(key, newFilterValue, window.location.href);
      if (window.history.replaceState) {
        window.history.replaceState({}, '', newWindowUrl);
      }
      return this.load(newDataUrl);
    }
  }]);

  return DataLoader;
})();

RTable.DataLoader = DataLoader;

function getJson(url) {
  var request = new XMLHttpRequest();
  return new Promise(function (resolve, reject) {
    request.open('GET', url, true);
    request.onreadystatechange = function () {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status >= 200 && this.status < 400) {
        try {
          resolve(JSON.parse(this.responseText));
        } catch (e) {
          reject(e);
        }
      } else {
        reject(this);
      }
    };
    request.send();
  });
}

function delayed(delay, fn) {
  var timeout = null;
  return function () {
    var _arguments = arguments;

    if (timeout) {
      clearTimeout(timeout);
    }
    timeout = setTimeout(function () {
      return fn.apply(null, _arguments);
    }, delay);
  };
}

/* ------------- */
/* packaged deps */

// http://blog.stevenlevithan.com/archives/parseuri
function parseUri(str) {
  var o = parseUri.options,
      m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
      uri = {},
      i = 14;

  while (i--) {
    uri[o.key[i]] = m[i] || "";
  }uri[o.q.name] = {};
  uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
    if ($1) uri[o.q.name][$1] = $2;
  });

  return uri;
}

parseUri.options = {
  strictMode: false,
  key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"],
  q: {
    name: "queryKey",
    parser: /(?:^|&)([^&=]*)=?([^&]*)/g
  },
  parser: {
    strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
    loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
  }
};

// http://stackoverflow.com/a/11654596/399317
function UpdateQueryString(key, value, url) {
  var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi");
  var hash;

  if (re.test(url)) {
    if (typeof value !== 'undefined' && value !== null) return url.replace(re, '$1' + key + "=" + value + '$2$3');else {
      hash = url.split('#');
      url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
      if (typeof hash[1] !== 'undefined' && hash[1] !== null) url += '#' + hash[1];
      return url;
    }
  } else {
    if (typeof value !== 'undefined' && value !== null) {
      var separator = url.indexOf('?') !== -1 ? '&' : '?';
      hash = url.split('#');
      url = hash[0] + separator + key + '=' + value;
      if (typeof hash[1] !== 'undefined' && hash[1] !== null) url += '#' + hash[1];
      return url;
    } else return url;
  }
}
<commit_msg>Update dist<commit_after>"use strict";

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/* global React */

var RTable = (function (_React$Component) {
  _inherits(RTable, _React$Component);

  function RTable(props) {
    _classCallCheck(this, RTable);

    var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(RTable).call(this, props));

    _this.state = {
      results: []
    };
    _this.loader = new RTable.DataLoader(_this, _this.props.dataUrl);
    return _this;
  }

  _createClass(RTable, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      this.loader.loadInitial();
    }
  }, {
    key: "getValue",
    value: function getValue(row, col) {
      if (col.get) {
        return col.get(row);
      }
      return row[col.name];
    }
  }, {
    key: "render",
    value: function render() {
      var _this2 = this;

      var filters = this.props.filters || [];
      var columns = this.props.columns || [];
      var header = columns.map(function (col, n) {
        return React.createElement(
          "th",
          { key: n, onClick: _this2.loader.fn.orderToggle(col.name) },
          col.label || col.name,
          _this2.state.ordering == col.name ? "▲" : _this2.state.ordering == "-" + col.name ? "▼" : null
        );
      });
      var rows = this.state.results.map(function (row, m) {
        var cells = _this2.props.columns.map(function (col, n) {
          return React.createElement(
            "td",
            { key: n },
            _this2.getValue(row, col)
          );
        });
        return React.createElement(
          "tr",
          { key: m },
          cells
        );
      });

      return React.createElement(
        "table",
        { className: "table table-striped table-hover" },
        React.createElement(
          "thead",
          null,
          React.createElement(
            "tr",
            null,
            React.createElement(
              "td",
              { className: "text-center", colSpan: columns.length },
              this.state.hasPrev ? React.createElement(
                "a",
                { className: "btn btn-primary t-prev", href: this.state.prevQuery, onClick: this.loader.fn.prevPage },
                "prev"
              ) : React.createElement(
                "button",
                { className: "btn btn-primary t-prev", disabled: true },
                "prev"
              ),
              ' ',
              "page ",
              this.state.page,
              " of ",
              this.state.pages,
              ", results ",
              this.state.firstResult,
              "-",
              this.state.lastResult,
              " of ",
              this.state.count,
              ' ',
              this.state.hasNext ? React.createElement(
                "a",
                { className: "btn btn-primary t-next", href: this.state.nextQuery, onClick: this.loader.fn.nextPage },
                "next"
              ) : React.createElement(
                "button",
                { className: "btn btn-primary t-next", disabled: true },
                "next"
              )
            )
          ),
          React.createElement(
            "tr",
            { ref: "filterRow" },
            React.createElement(
              "td",
              { className: "form-inline", colSpan: columns.length },
              filters.map(function (filter, i) {
                return React.createElement(
                  "span",
                  { key: i },
                  React.createElement(
                    "label",
                    null,
                    filter.label + ':'
                  ),
                  ' ',
                  filter.choices ? React.createElement(
                    "select",
                    { className: "form-control input-sm ", onInput: _this2.loader.fn.filter(filter.name) },
                    filter.choices.map(function (choice, j) {
                      return React.createElement(
                        "option",
                        { key: j, value: choice.value },
                        choice.label || choice.value
                      );
                    })
                  ) : React.createElement("input", { className: "form-control input-sm", onInput: _this2.loader.fn.filterDelayed(filter.name) }),
                  ' '
                );
              })
            )
          ),
          React.createElement(
            "tr",
            { ref: "columnHeaderRow" },
            header
          )
        ),
        React.createElement(
          "tbody",
          { ref: "rowContainer" },
          rows
        )
      );
    }
  }]);

  return RTable;
})(React.Component);

var DataLoader = (function () {
  function DataLoader(component, baseUrl) {
    var _this3 = this;

    _classCallCheck(this, DataLoader);

    this.component = component;
    this.baseUrl = baseUrl;
    this.filterDelay = 800;
    this.fn = {
      goToPage: this.goToPage.bind(this),
      nextPage: this.nextPage.bind(this),
      prevPage: this.prevPage.bind(this),
      orderBy: function orderBy(column) {
        return function (event) {
          return _this3.orderBy(event, column);
        };
      },
      orderToggle: function orderToggle(column) {
        return function (event) {
          return _this3.orderToggle(event, column);
        };
      },
      filter: function filter(key) {
        return function (event) {
          return _this3.filter(event, key);
        };
      },
      filterDelayed: function filterDelayed(key) {
        return delayed(_this3.filterDelay, function (event) {
          return _this3.filter(event, key);
        });
      }
    };
  }

  _createClass(DataLoader, [{
    key: "loadInitial",
    value: function loadInitial() {
      var data = parseUri(this.getWindowLocation()).queryKey;
      data.page = data.page || "1";
      var url = this.baseUrl;
      for (var k in data) {
        if (data.hasOwnProperty(k)) {
          url = UpdateQueryString(k, data[k], url);
        }
      }this.load(url);
    }
  }, {
    key: "getWindowLocation",
    value: function getWindowLocation() {
      return window.location;
    }
  }, {
    key: "currentState",
    value: function currentState() {
      return this.component.state;
    }
  }, {
    key: "load",
    value: function load(url) {
      var _this4 = this;

      var divideRoundUp = function divideRoundUp(a, b) {
        return Math.floor((a + b - 1) / b);
      };
      var parsedUrl = parseUri(url);
      var urlParams = parsedUrl.queryKey;
      return getJson(url).then(function (response) {
        // have: count, next, previous, results
        response.fullUrl = url;
        response.query = '?' + parsedUrl.query; // TODO drop? use consistently?
        response.page = parseInt(urlParams.page) || 1;
        response.page0 = response.page - 1;
        response.hasNext = !!response.next;
        response.hasPrev = !!response.previous;
        response.nextQuery = UpdateQueryString('page', response.page + 1, response.query);
        response.prevQuery = UpdateQueryString('page', response.page - 1, response.query);
        response.ordering = urlParams.ordering || null;
        if (response.next) {
          var pageSize = response.results.length;
          response.pages = divideRoundUp(response.count, pageSize);
          response.firstResult = pageSize * response.page0 + 1;
          response.lastResult = pageSize * (response.page0 + 1);
        } else {
          response.pages = response.page;
          response.lastResult = response.count;
          response.firstResult = response.count - response.results.length + 1;
        }
        _this4.component.setState(response);
        return response;
      });
    }
  }, {
    key: "goToPage",
    value: function goToPage(event, page) {
      if (event.ctrlKey || event.altKey || event.shiftKey) return;
      event.preventDefault();
      var newDataUrl = UpdateQueryString('page', page, this.currentState().fullUrl);
      var newWindowUrl = UpdateQueryString('page', page, window.location.href);
      if (window.history.replaceState) {
        window.history.replaceState({}, '', newWindowUrl);
      }
      return this.load(newDataUrl);
    }
  }, {
    key: "nextPage",
    value: function nextPage(event) {
      return this.goToPage(event, this.currentState().page + 1);
    }
  }, {
    key: "prevPage",
    value: function prevPage(event) {
      return this.goToPage(event, this.currentState().page - 1);
    }
  }, {
    key: "orderBy",
    value: function orderBy(event, ordering) {
      if (event.ctrlKey || event.altKey || event.shiftKey) return;
      event.preventDefault();
      var newDataUrl = UpdateQueryString('ordering', ordering, this.currentState().fullUrl);
      var newWindowUrl = UpdateQueryString('ordering', ordering, window.location.href);
      if (window.history.replaceState) {
        window.history.replaceState({}, '', newWindowUrl);
      }
      return this.load(newDataUrl);
    }
  }, {
    key: "orderToggle",
    value: function orderToggle(event, ordering) {
      if (!ordering.length) {
        return;
      }
      if (this.currentState().ordering == ordering) {
        if (ordering[0] == '-') {
          ordering = ordering.substr(1);
        } else {
          ordering = '-' + ordering;
        }
      }
      return this.orderBy(event, ordering);
    }
  }, {
    key: "filter",
    value: function filter(event, key) {
      var newFilterValue = event.target.value || null;
      var newDataUrl = UpdateQueryString(key, newFilterValue, this.currentState().fullUrl);
      var newWindowUrl = UpdateQueryString(key, newFilterValue, window.location.href);
      if (window.history.replaceState) {
        window.history.replaceState({}, '', newWindowUrl);
      }
      return this.load(newDataUrl);
    }
  }]);

  return DataLoader;
})();

RTable.DataLoader = DataLoader;

function getJson(url) {
  var request = new XMLHttpRequest();
  return new Promise(function (resolve, reject) {
    request.open('GET', url, true);
    request.onreadystatechange = function () {
      if (this.readyState !== 4) {
        return;
      }
      if (this.status >= 200 && this.status < 400) {
        try {
          resolve(JSON.parse(this.responseText));
        } catch (e) {
          reject(e);
        }
      } else {
        reject(this);
      }
    };
    request.send();
  });
}

function delayed(delay, fn) {
  var timeout = null;
  return function () {
    var _arguments = arguments;

    if (timeout) {
      clearTimeout(timeout);
    }
    timeout = setTimeout(function () {
      return fn.apply(null, _arguments);
    }, delay);
  };
}

/* ------------- */
/* packaged deps */

// http://blog.stevenlevithan.com/archives/parseuri
function parseUri(str) {
  var o = parseUri.options,
      m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
      uri = {},
      i = 14;

  while (i--) {
    uri[o.key[i]] = m[i] || "";
  }uri[o.q.name] = {};
  uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
    if ($1) uri[o.q.name][$1] = $2;
  });

  return uri;
}

parseUri.options = {
  strictMode: false,
  key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"],
  q: {
    name: "queryKey",
    parser: /(?:^|&)([^&=]*)=?([^&]*)/g
  },
  parser: {
    strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
    loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
  }
};

// http://stackoverflow.com/a/11654596/399317
function UpdateQueryString(key, value, url) {
  var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi");
  var hash;

  if (re.test(url)) {
    if (typeof value !== 'undefined' && value !== null) return url.replace(re, '$1' + key + "=" + value + '$2$3');else {
      hash = url.split('#');
      url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
      if (typeof hash[1] !== 'undefined' && hash[1] !== null) url += '#' + hash[1];
      return url;
    }
  } else {
    if (typeof value !== 'undefined' && value !== null) {
      var separator = url.indexOf('?') !== -1 ? '&' : '?';
      hash = url.split('#');
      url = hash[0] + separator + key + '=' + value;
      if (typeof hash[1] !== 'undefined' && hash[1] !== null) url += '#' + hash[1];
      return url;
    } else return url;
  }
}
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import fetchMock from 'fetch-mock/es5/client';
import LoginActivityPage from './LoginActivityPage';
import loginActivityJson from './loginActivityJson.fixture';

function mockFetch(props = {}) {
  fetchMock.restore();

  const {queryStartTimestamp, queryEndTimestamp} = props;
  const url = `/api/login_activity?created_at_or_before=${queryEndTimestamp}&created_after=${queryStartTimestamp}`;
  fetchMock.get(url, loginActivityJson);
}

function testProps(props = {}) {
  return {
    queryStartTimestamp: '1529513716',
    queryEndTimestamp: '1532105716',
    ...props
  };
}

it('renders without crashing', () => {
  const props = testProps();
  mockFetch(props);
  const el = document.createElement('div');
  ReactDOM.render(<LoginActivityPage {...props} />, el);
});

it('renders after fetching', done => {
  const props = testProps();
  mockFetch(props);
  const el = document.createElement('div');
  ReactDOM.render(<LoginActivityPage {...props} />, el);

  setTimeout(() => {
    expect(el.innerHTML).toContain('Login Attempts, Past 30 days');
    expect(el.querySelectorAll('div.tooltip').length).toEqual(47);
    done();
  }, 0);
});
<commit_msg>Fix test bug in LoginActivityPage<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import fetchMock from 'fetch-mock/es5/client';
import LoginActivityPage from './LoginActivityPage';
import loginActivityJson from './loginActivityJson.fixture';

function mockFetch(props = {}) {
  fetchMock.restore();

  const {queryStartTimestamp, queryEndTimestamp} = props;
  const url = `/api/login_activity?created_at_or_before=${queryEndTimestamp}&created_after=${queryStartTimestamp}`;
  fetchMock.get(url, loginActivityJson);
}

function testProps(props = {}) {
  return {
    queryStartTimestamp: '1529513716',
    queryEndTimestamp: '1532105716',
    ...props
  };
}

it('renders without crashing', () => {
  const props = testProps();
  mockFetch(props);
  const el = document.createElement('div');
  ReactDOM.render(<LoginActivityPage {...props} />, el);
});

it('renders after fetching', done => {
  const props = testProps();
  mockFetch(props);
  const el = document.createElement('div');
  ReactDOM.render(<LoginActivityPage {...props} />, el);

  setTimeout(() => {
    expect(el.innerHTML).toContain('Login Attempts, Past 30 days');
    expect(el.querySelectorAll('div.tooltip').length).toEqual(41);
    done();
  }, 0);
});
<|endoftext|>


<commit_before>
define(['ByteSource'], function(ByteSource) {

  'use strict';

  var PHYSICAL_BLOCK_BYTES = 512;
  var BTREE_NODE_BYTES = 512;

  var MAC_CHARSET_128_255
    = '\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8'
    + '\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC'
    + '\u2020\xB0\xA2\xA3\xA7\u2022\xB6\xDF\xAE\xA9\u2122\xB4\xA8\u2260\xC6\xD8'
    + '\u221E\xB1\u2264\u2265\xA5\xB5\u2202\u2211\u220F\u03C0\u222B\xAA\xBA\u03A9\xE6\xF8'
    + '\xBF\xA1\xAC\u221A\u0192\u2248\u2206\xAB\xBB\u2026\xA0\xC0\xC3\xD5\u0152\u0153'
    + '\u2013\u2014\u201C\u201D\u2018\u2019\xF7\u25CA\xFF\u0178\u2044\u20AC\u2039\u203A\uFB01\uFB02'
    + '\u2021\xB7\u201A\u201E\u2030\xC2\xCA\xC1\xCB\xC8\xCD\xCE\xCF\xCC\xD3\xD4'
    + '\uF8FF\xD2\xDA\xDB\xD9\u0131\u02C6\u02DC\xAF\u02D8\u02D9\u02DA\xB8\u02DD\u02DB\u02C7';

  function macintoshRoman(u8array, offset, length) {
    switch(arguments.length) {
      case 2: u8array = u8array.subarray(offset); break;
      case 3: u8array = u8array.subarray(offset, offset + length); break;
    }
    return String.fromCharCode.apply(null, u8array)
      .replace(/[\x80-\xFF]/g, function(c) {
        return MAC_CHARSET_128_255[c.charCodeAt(0) - 128];
      });
  }

  function macintoshDate(dv, offset) {
    var offset = dv.getUint32(offset, false);
    if (offset === 0) return null;
    return new Date(new Date(1904, 0).getTime() + offset * 1000);
  }

  function nullTerminate(str) {
    return str.replace(/\0.*/, '');
  }

  function extentDataRecord(dv, offset) {
    var record = [];
    for (var i = 0; i < 3; i++) {
      record.push({
        offset: dv.getUint16(offset + i*4, false),
        length: dv.getUint16(offset + i*4 + 2, false),
      });
    }
    return record;
  }

  function AppleVolume(byteSource) {
    this.byteSource = byteSource;
  }
  AppleVolume.prototype = {
    read: function(reader) {
      this.readPartitions(this.byteSource, reader);
    },
    readPartitions: function(byteSource, reader) {
      var self = this;
      function doPartition(n) {
        byteSource.slice(PHYSICAL_BLOCK_BYTES * n, PHYSICAL_BLOCK_BYTES * (n+1)).read({
          onbytes: function(bytes) {
            if (macintoshRoman(bytes, 0, 4) !== 'PM\0\0') {
              console.error('invalid partition map signature');
              return;
            }
            var dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
            var mapBlockCount = dv.getInt32(4, false);
            var partitionInfo = {
              blockOffset: dv.getInt32(8, false),
              blockCount: dv.getInt32(12, false),
              type: nullTerminate(macintoshRoman(bytes, 48, 32)),
              status: dv.getInt32(88, false),
            };
            var dataAreaBlockCount = dv.getInt32(84, false);
            if (dataAreaBlockCount > 0) {
              partitionInfo.dataArea = {
                blockCount: dataAreaBlockCount,
                blockOffset: dv.getInt32(80, false),
              };
            }
            var bootCodeByteLength = dv.getInt32(96, false);
            if (bootCodeByteLength > 0) {
              partitionInfo.bootCode = {
                byteLength: bootCodeByteLength,
                blockOffset: dv.getInt32(92, false),
                loadAddress: dv.getInt32(100, false),
                entryPoint: dv.getInt32(108, false),
                checksum: dv.getInt32(116, false),
              };
            }
            var partitionName = nullTerminate(macintoshRoman(bytes, 16, 32));
            if (partitionName) partitionInfo.name = partitionName;
            var processorType = nullTerminate(macintoshRoman(bytes, 124, 16));
            if (processorType) partitionInfo.processorType = processorType;
            switch (partitionInfo.type) {
              case 'Apple_HFS':
                self.readHFS(
                  byteSource.slice(
                    PHYSICAL_BLOCK_BYTES * partitionInfo.blockOffset,
                    PHYSICAL_BLOCK_BYTES * (partitionInfo.blockOffset + partitionInfo.blockCount)),
                  reader);
                break;
            }
            if (typeof reader.onpartition === 'function') {
              reader.onpartition(partitionInfo);
            }
            if (n < mapBlockCount) {
              doPartition(n + 1);
            }
          },
        });

      }
      doPartition(1);
    },
    readHFS: function(byteSource, reader) {
      var self = this;
      // first 2 blocks are boot blocks
      var masterDirectoryBlock = byteSource.slice(PHYSICAL_BLOCK_BYTES * 2, PHYSICAL_BLOCK_BYTES * (2+1));
      masterDirectoryBlock.read({
        onbytes: function(bytes) {
          if (macintoshRoman(bytes, 0, 2) !== 'BD') {
            console.error('HFS master directory block signature not found');
            return;
          }
          var dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
          var volumeInfo = {
            createdAt: macintoshDate(dv, 2),
            lastModifiedAt: macintoshDate(dv, 6),
            attributes: dv.getUint16(10, false),
            rootFileCount: dv.getUint16(12, false),
            bitmapBlockOffset: dv.getUint16(14, false), // always 3?
            nextAllocationSearch: dv.getUint16(16, false), // used internally
            allocationBlockCount: dv.getUint16(18, false),
            allocationBlockByteLength: dv.getInt32(20, false), // size of one block, always multiple of 512
            defaultClumpSize: dv.getInt32(24, false),
            allocationBlocksOffset: dv.getUint16(28, false),
            nextUnusedCatalogNodeId: dv.getInt32(30, false), // catalog node: file or folder
            unusedAllocationBlockCount: dv.getUint16(34, false),
            name: nullTerminate(macintoshRoman(bytes, 36 + 1, bytes[36])),
            lastBackupAt: macintoshDate(dv, 64),
            backupSequenceNumber: dv.getUint16(68, false), // used internally
            writeCount: dv.getInt32(70, false),
            extentsOverflowFileClumpSize: dv.getInt32(74, false),
            catalogFileClumpSize: dv.getInt32(78, false),
            rootFolderCount: dv.getUint16(82, false),
            fileCount: dv.getInt32(84, false),
            folderCount: dv.getInt32(88, false),
            finderInfo: [
              dv.getInt32(92, false),
              dv.getInt32(96, false),
              dv.getInt32(100, false),
              dv.getInt32(104, false),
              dv.getInt32(108, false),
              dv.getInt32(112, false),
              dv.getInt32(116, false),
              dv.getInt32(120, false),
            ],
            cacheBlockCount: dv.getUint16(124, false), // used internally
            bitmapCacheBlockCount: dv.getUint16(126, false), // used internally
            commonCacheBlockCount: dv.getUint16(128, false), // used internally
            extentsOverflowFileByteLength: dv.getInt32(130, false),
            extentsOverflowFileExtentRecord: extentDataRecord(dv, 134),
            catalogFileByteLength: dv.getInt32(146, false),
            catalogFileExtentRecord: extentDataRecord(dv, 150),
          };
          if (typeof reader.onvolumestart === 'function') {
            reader.onvolumestart(volumeInfo);
          }
          var allocationBlocksAt = PHYSICAL_BLOCK_BYTES * volumeInfo.allocationBlocksOffset;
          var allocationBlocksLen = volumeInfo.allocationBlockByteLength * volumeInfo.allocationBlockCount;
          var allocationBlocks = byteSource.slice(allocationBlocksAt, allocationBlocksAt + allocationBlocksLen);
          allocationBlocks.blockSize = volumeInfo.allocationBlockByteLength;
          var catalogExtents = volumeInfo.catalogFileExtentRecord[0];
          catalogExtents = allocationBlocks.slice(
            allocationBlocks.blockSize * catalogExtents.offset,
            allocationBlocks.blockSize * (catalogExtents.offset + catalogExtents.length));
          self.readCatalog(catalogExtents, {

          });
        }
      });
    },
    readCatalog: function(byteSource, reader) {
      var self = this;
      this.readBTreeNode(byteSource.slice(0, BTREE_NODE_BYTES), {
        onheadernode: function(headerNode) {
          var rootNode = byteSource.slice(
            headerNode.rootNodeNumber * BTREE_NODE_BYTES,
            (headerNode.rootNodeNumber + 1) * BTREE_NODE_BYTES);
          self.readBTreeNode(rootNode, {
            onindexnode: function(indexNode) {
              console.log(indexNode);
            }
          });
        },
      });
    },
    readBTreeNode: function(byteSource, reader) {
      var self = this;
      byteSource.read({
        onbytes: function(bytes) {
          var node = {};
          var dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
          var records = new Array(dv.getUint16(10, false));
          for (var i = 0; i < records.length; i++) {
            records[i] = bytes.subarray(
              dv.getUint16(BTREE_NODE_BYTES - 2*(i+1), false),
              dv.getUint16(BTREE_NODE_BYTES - 2*(i+2), false));
          }
          var forwardLink = dv.getInt32(0, false);
          var backwardLink = dv.getInt32(4, false);
          if (forwardLink !== 0) node.forwardLink = forwardLink;
          if (backwardLink !== 0) node.backwardLink = backwardLink;
          node.depth = bytes[9];
          switch(bytes[8]) {
            case 0: // index
              node.pointers = [];
              for (var i = 0; i < records.length; i++) {
                var recordBytes = records[i];
                var keyLength;
                if (recordBytes.length === 0 || (keyLength = recordBytes[0]) === 0) {
                  // deleted record
                  continue;
                }
                var dv = new DataView(recordBytes.buffer, recordBytes.byteOffset, recordBytes.byteLength);
                var parentDirectoryID = dv.getUint32(2, false);
                var name = macintoshRoman(recordBytes, 7, recordBytes[6]);
                var nodeNumber = dv.getUint32(1 + keyLength, false);
                node.pointers.push({name:name, nodeNumber:nodeNumber, parentDirectoryID:parentDirectoryID});
              }
              if (typeof reader.onindexnode === 'function') {
                reader.onindexnode(node);
              }
              break;
            case 1: // header
              if (node.records.length !== 3) {
                console.error('header node: expected 3 records, got ' + recordCount);
                return;
              }
              var recordDV = new DataView(node.records[0].buffer, node.records[0].byteOffset, node.records[0].byteLength);
              node.treeDepth = recordDV.getUint16(0, false);
              node.rootNodeNumber = recordDV.getUint32(2, false);
              node.leafRecordCount = recordDV.getUint32(6, false);
              node.firstLeaf = recordDV.getUint32(10, false);
              node.lastLeaf = recordDV.getUint32(14, false);
              node.nodeByteLength = recordDV.getUint16(18, false); // always 512?
              node.maxKeyByteLength = recordDV.getUint16(20, false);
              node.nodeCount = recordDV.getUint32(22, false);
              node.freeNodeCount = recordDV.getUint32(26, false);
              node.bitmap = node.records[2];
              if (typeof reader.onheadernode === 'function') {
                reader.onheadernode(node);
              }
              break;
            case 2: // map
              console.error('NYI: map node');
              break;
            case 0xff: // leaf
              console.error('NYI: leaf node');
              break;
            default:
              console.error('unknown node type: ' + bytes[8]);
              break;
          }
        }
      });
    },
  };

  return AppleVolume;

});
<commit_msg>Fix unrefactored cases (field became a variable)<commit_after>
define(['ByteSource'], function(ByteSource) {

  'use strict';

  var PHYSICAL_BLOCK_BYTES = 512;
  var BTREE_NODE_BYTES = 512;

  var MAC_CHARSET_128_255
    = '\xC4\xC5\xC7\xC9\xD1\xD6\xDC\xE1\xE0\xE2\xE4\xE3\xE5\xE7\xE9\xE8'
    + '\xEA\xEB\xED\xEC\xEE\xEF\xF1\xF3\xF2\xF4\xF6\xF5\xFA\xF9\xFB\xFC'
    + '\u2020\xB0\xA2\xA3\xA7\u2022\xB6\xDF\xAE\xA9\u2122\xB4\xA8\u2260\xC6\xD8'
    + '\u221E\xB1\u2264\u2265\xA5\xB5\u2202\u2211\u220F\u03C0\u222B\xAA\xBA\u03A9\xE6\xF8'
    + '\xBF\xA1\xAC\u221A\u0192\u2248\u2206\xAB\xBB\u2026\xA0\xC0\xC3\xD5\u0152\u0153'
    + '\u2013\u2014\u201C\u201D\u2018\u2019\xF7\u25CA\xFF\u0178\u2044\u20AC\u2039\u203A\uFB01\uFB02'
    + '\u2021\xB7\u201A\u201E\u2030\xC2\xCA\xC1\xCB\xC8\xCD\xCE\xCF\xCC\xD3\xD4'
    + '\uF8FF\xD2\xDA\xDB\xD9\u0131\u02C6\u02DC\xAF\u02D8\u02D9\u02DA\xB8\u02DD\u02DB\u02C7';

  function macintoshRoman(u8array, offset, length) {
    switch(arguments.length) {
      case 2: u8array = u8array.subarray(offset); break;
      case 3: u8array = u8array.subarray(offset, offset + length); break;
    }
    return String.fromCharCode.apply(null, u8array)
      .replace(/[\x80-\xFF]/g, function(c) {
        return MAC_CHARSET_128_255[c.charCodeAt(0) - 128];
      });
  }

  function macintoshDate(dv, offset) {
    var offset = dv.getUint32(offset, false);
    if (offset === 0) return null;
    return new Date(new Date(1904, 0).getTime() + offset * 1000);
  }

  function nullTerminate(str) {
    return str.replace(/\0.*/, '');
  }

  function extentDataRecord(dv, offset) {
    var record = [];
    for (var i = 0; i < 3; i++) {
      record.push({
        offset: dv.getUint16(offset + i*4, false),
        length: dv.getUint16(offset + i*4 + 2, false),
      });
    }
    return record;
  }

  function AppleVolume(byteSource) {
    this.byteSource = byteSource;
  }
  AppleVolume.prototype = {
    read: function(reader) {
      this.readPartitions(this.byteSource, reader);
    },
    readPartitions: function(byteSource, reader) {
      var self = this;
      function doPartition(n) {
        byteSource.slice(PHYSICAL_BLOCK_BYTES * n, PHYSICAL_BLOCK_BYTES * (n+1)).read({
          onbytes: function(bytes) {
            if (macintoshRoman(bytes, 0, 4) !== 'PM\0\0') {
              console.error('invalid partition map signature');
              return;
            }
            var dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
            var mapBlockCount = dv.getInt32(4, false);
            var partitionInfo = {
              blockOffset: dv.getInt32(8, false),
              blockCount: dv.getInt32(12, false),
              type: nullTerminate(macintoshRoman(bytes, 48, 32)),
              status: dv.getInt32(88, false),
            };
            var dataAreaBlockCount = dv.getInt32(84, false);
            if (dataAreaBlockCount > 0) {
              partitionInfo.dataArea = {
                blockCount: dataAreaBlockCount,
                blockOffset: dv.getInt32(80, false),
              };
            }
            var bootCodeByteLength = dv.getInt32(96, false);
            if (bootCodeByteLength > 0) {
              partitionInfo.bootCode = {
                byteLength: bootCodeByteLength,
                blockOffset: dv.getInt32(92, false),
                loadAddress: dv.getInt32(100, false),
                entryPoint: dv.getInt32(108, false),
                checksum: dv.getInt32(116, false),
              };
            }
            var partitionName = nullTerminate(macintoshRoman(bytes, 16, 32));
            if (partitionName) partitionInfo.name = partitionName;
            var processorType = nullTerminate(macintoshRoman(bytes, 124, 16));
            if (processorType) partitionInfo.processorType = processorType;
            switch (partitionInfo.type) {
              case 'Apple_HFS':
                self.readHFS(
                  byteSource.slice(
                    PHYSICAL_BLOCK_BYTES * partitionInfo.blockOffset,
                    PHYSICAL_BLOCK_BYTES * (partitionInfo.blockOffset + partitionInfo.blockCount)),
                  reader);
                break;
            }
            if (typeof reader.onpartition === 'function') {
              reader.onpartition(partitionInfo);
            }
            if (n < mapBlockCount) {
              doPartition(n + 1);
            }
          },
        });

      }
      doPartition(1);
    },
    readHFS: function(byteSource, reader) {
      var self = this;
      // first 2 blocks are boot blocks
      var masterDirectoryBlock = byteSource.slice(PHYSICAL_BLOCK_BYTES * 2, PHYSICAL_BLOCK_BYTES * (2+1));
      masterDirectoryBlock.read({
        onbytes: function(bytes) {
          if (macintoshRoman(bytes, 0, 2) !== 'BD') {
            console.error('HFS master directory block signature not found');
            return;
          }
          var dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
          var volumeInfo = {
            createdAt: macintoshDate(dv, 2),
            lastModifiedAt: macintoshDate(dv, 6),
            attributes: dv.getUint16(10, false),
            rootFileCount: dv.getUint16(12, false),
            bitmapBlockOffset: dv.getUint16(14, false), // always 3?
            nextAllocationSearch: dv.getUint16(16, false), // used internally
            allocationBlockCount: dv.getUint16(18, false),
            allocationBlockByteLength: dv.getInt32(20, false), // size of one block, always multiple of 512
            defaultClumpSize: dv.getInt32(24, false),
            allocationBlocksOffset: dv.getUint16(28, false),
            nextUnusedCatalogNodeId: dv.getInt32(30, false), // catalog node: file or folder
            unusedAllocationBlockCount: dv.getUint16(34, false),
            name: nullTerminate(macintoshRoman(bytes, 36 + 1, bytes[36])),
            lastBackupAt: macintoshDate(dv, 64),
            backupSequenceNumber: dv.getUint16(68, false), // used internally
            writeCount: dv.getInt32(70, false),
            extentsOverflowFileClumpSize: dv.getInt32(74, false),
            catalogFileClumpSize: dv.getInt32(78, false),
            rootFolderCount: dv.getUint16(82, false),
            fileCount: dv.getInt32(84, false),
            folderCount: dv.getInt32(88, false),
            finderInfo: [
              dv.getInt32(92, false),
              dv.getInt32(96, false),
              dv.getInt32(100, false),
              dv.getInt32(104, false),
              dv.getInt32(108, false),
              dv.getInt32(112, false),
              dv.getInt32(116, false),
              dv.getInt32(120, false),
            ],
            cacheBlockCount: dv.getUint16(124, false), // used internally
            bitmapCacheBlockCount: dv.getUint16(126, false), // used internally
            commonCacheBlockCount: dv.getUint16(128, false), // used internally
            extentsOverflowFileByteLength: dv.getInt32(130, false),
            extentsOverflowFileExtentRecord: extentDataRecord(dv, 134),
            catalogFileByteLength: dv.getInt32(146, false),
            catalogFileExtentRecord: extentDataRecord(dv, 150),
          };
          if (typeof reader.onvolumestart === 'function') {
            reader.onvolumestart(volumeInfo);
          }
          var allocationBlocksAt = PHYSICAL_BLOCK_BYTES * volumeInfo.allocationBlocksOffset;
          var allocationBlocksLen = volumeInfo.allocationBlockByteLength * volumeInfo.allocationBlockCount;
          var allocationBlocks = byteSource.slice(allocationBlocksAt, allocationBlocksAt + allocationBlocksLen);
          allocationBlocks.blockSize = volumeInfo.allocationBlockByteLength;
          var catalogExtents = volumeInfo.catalogFileExtentRecord[0];
          catalogExtents = allocationBlocks.slice(
            allocationBlocks.blockSize * catalogExtents.offset,
            allocationBlocks.blockSize * (catalogExtents.offset + catalogExtents.length));
          self.readCatalog(catalogExtents, {

          });
        }
      });
    },
    readCatalog: function(byteSource, reader) {
      var self = this;
      this.readBTreeNode(byteSource.slice(0, BTREE_NODE_BYTES), {
        onheadernode: function(headerNode) {
          var rootNode = byteSource.slice(
            headerNode.rootNodeNumber * BTREE_NODE_BYTES,
            (headerNode.rootNodeNumber + 1) * BTREE_NODE_BYTES);
          self.readBTreeNode(rootNode, {
            onindexnode: function(indexNode) {
              console.log(indexNode);
            }
          });
        },
      });
    },
    readBTreeNode: function(byteSource, reader) {
      var self = this;
      byteSource.read({
        onbytes: function(bytes) {
          var node = {};
          var dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
          var records = new Array(dv.getUint16(10, false));
          for (var i = 0; i < records.length; i++) {
            records[i] = bytes.subarray(
              dv.getUint16(BTREE_NODE_BYTES - 2*(i+1), false),
              dv.getUint16(BTREE_NODE_BYTES - 2*(i+2), false));
          }
          var forwardLink = dv.getInt32(0, false);
          var backwardLink = dv.getInt32(4, false);
          if (forwardLink !== 0) node.forwardLink = forwardLink;
          if (backwardLink !== 0) node.backwardLink = backwardLink;
          node.depth = bytes[9];
          switch(bytes[8]) {
            case 0: // index
              node.pointers = [];
              for (var i = 0; i < records.length; i++) {
                var recordBytes = records[i];
                var keyLength;
                if (recordBytes.length === 0 || (keyLength = recordBytes[0]) === 0) {
                  // deleted record
                  continue;
                }
                var dv = new DataView(recordBytes.buffer, recordBytes.byteOffset, recordBytes.byteLength);
                var parentDirectoryID = dv.getUint32(2, false);
                var name = macintoshRoman(recordBytes, 7, recordBytes[6]);
                var nodeNumber = dv.getUint32(1 + keyLength, false);
                node.pointers.push({name:name, nodeNumber:nodeNumber, parentDirectoryID:parentDirectoryID});
              }
              if (typeof reader.onindexnode === 'function') {
                reader.onindexnode(node);
              }
              break;
            case 1: // header
              if (records.length !== 3) {
                console.error('header node: expected 3 records, got ' + recordCount);
                return;
              }
              var recordDV = new DataView(records[0].buffer, records[0].byteOffset, records[0].byteLength);
              node.treeDepth = recordDV.getUint16(0, false);
              node.rootNodeNumber = recordDV.getUint32(2, false);
              node.leafRecordCount = recordDV.getUint32(6, false);
              node.firstLeaf = recordDV.getUint32(10, false);
              node.lastLeaf = recordDV.getUint32(14, false);
              node.nodeByteLength = recordDV.getUint16(18, false); // always 512?
              node.maxKeyByteLength = recordDV.getUint16(20, false);
              node.nodeCount = recordDV.getUint32(22, false);
              node.freeNodeCount = recordDV.getUint32(26, false);
              node.bitmap = node.records[2];
              if (typeof reader.onheadernode === 'function') {
                reader.onheadernode(node);
              }
              break;
            case 2: // map
              console.error('NYI: map node');
              break;
            case 0xff: // leaf
              console.error('NYI: leaf node');
              break;
            default:
              console.error('unknown node type: ' + bytes[8]);
              break;
          }
        }
      });
    },
  };

  return AppleVolume;

});
<|endoftext|>


<commit_before>var Utils = {
    /**
      * @param String input  A match pattern
      * @returns  null if input is invalid
      * @returns  String to be passed to the RegExp constructor */
    parse_match_pattern: function (input) {
        if (typeof input !== 'string') return null;
        var match_pattern = '(?:^'
          , regEscape = function(s) {return s.replace(/[[^$.|?*+(){}\\]/g, '\\$&');}
          , result = /^(\*|https?|file|ftp|chrome-extension):\/\//.exec(input);

        // Parse scheme
        if (!result) return null;
        input = input.substr(result[0].length);
        match_pattern += result[1] === '*' ? 'https?://' : result[1] + '://';

        // Parse host if scheme is not `file`
        if (result[1] !== 'file') {
            if (!(result = /^(?:\*|(\*\.)?([^\/*]+))(?=\/)/.exec(input))) return null;
            input = input.substr(result[0].length);
            if (result[0] === '*') {    // host is '*'
                match_pattern += '[^/]+';
            } else {
                if (result[1]) {         // Subdomain wildcard exists
                    match_pattern += '(?:[^/]+\\.)?';
                }
                // Append host (escape special regex characters)
                match_pattern += regEscape(result[2]);
            }
        }
        // Add remainder (path)
        match_pattern += input.split('*').map(regEscape).join('.*');
        match_pattern += '$)';
        return match_pattern;
    },
    urlsAreEqual: function (urlString1, urlString2) {
        var url1 = new URL(urlString1);
        var url2 = new URL(urlString2);

        return url1.hostname === url2.hostname &&
               url1.pathname === url2.pathname;
    },
    extrapolateUrlFromCookie: function (cookie) {
        var prefix = cookie.secure ? "https://" : "http://";
        if (cookie.domain.charAt(0) == ".")
            prefix += "www";

        return prefix + cookie.domain + cookie.path;
    },
    extrapolateDomainFromMatchURL: function(matchURL) {
        var matches = matchURL.match(".*://(.*)/.*");
        var domain = matches[1];
        if (domain[0] === "*") domain = domain.slice(2);
        return domain;
    },
    getCookiesForDomain: function (domain, cb) {
        chrome.cookies.getAll(
            { domain: Utils.extrapolateDomainFromMatchURL(domain) },
            function(cookies) {
                cb(cookies)
            }
        );
    },
    getURLParams: function () {
        var vars = {};
        var parts = window.location.href.replace(
            /[?&]+([^=&]+)=([^&]*)/gi,
            function(m,key,value) {
                vars[key] = decodeURIComponent(value);
            });
        return vars;
    },
    addURLParam: function(url, parameterName, parameterValue) {
        replaceDuplicates = true;

        if(url.indexOf('#') > 0){
            var cl = url.indexOf('#');
            urlhash = url.substring(url.indexOf('#'),url.length);
        } else {
            urlhash = '';
            cl = url.length;
        }

        sourceUrl = url.substring(0,cl);

        var urlParts = sourceUrl.split("?");
        var newQueryString = "";

        if (urlParts.length > 1)
        {
            var parameters = urlParts[1].split("&");
            for (var i=0; (i < parameters.length); i++)
            {
                var parameterParts = parameters[i].split("=");
                if (!(replaceDuplicates && parameterParts[0] == parameterName))
                {
                    if (newQueryString === "") newQueryString = "?";
                    else newQueryString += "&";
                    newQueryString += parameterParts[0] + "=" + parameterParts[1];
                }
            }
        }
        if (newQueryString === "") newQueryString = "?";
        else newQueryString += "&";
        newQueryString += parameterName + "=" + parameterValue;

        return urlParts[0] + newQueryString + urlhash;
    },
    triggerLoading: function (el, opts) {
        var $el = $(el),
            saveText = $el.text(),
            promise;

        $el.addClass('loading');
        $el.text('loading..');

        if (opts && opts.promise) {
            promise = $.Deferred();
            $.when(promise)
             .then(unload)
            return promise;
        } else {
            setTimeout(unload, 1000);
        }

        function unload() {
            $el.removeClass('loading');
            $el.text(saveText);
        }
    },
    isEmail: function(email) {
        var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
        return regex.test(email);
    },
    settings: {
        waitlistHost: "http://localhost:5000",
        waitlistPaths: {
            reserve: '/u/reserve',
            check: '/u/check',
            setEmail: '/u/email/set',
            inviteCreate: '/i/create',
            inviteAdd: '/i/add',
            inviteClear: '/i/clear'
        }
    }
}

<commit_msg>restore waitlistHost<commit_after>var Utils = {
    /**
      * @param String input  A match pattern
      * @returns  null if input is invalid
      * @returns  String to be passed to the RegExp constructor */
    parse_match_pattern: function (input) {
        if (typeof input !== 'string') return null;
        var match_pattern = '(?:^'
          , regEscape = function(s) {return s.replace(/[[^$.|?*+(){}\\]/g, '\\$&');}
          , result = /^(\*|https?|file|ftp|chrome-extension):\/\//.exec(input);

        // Parse scheme
        if (!result) return null;
        input = input.substr(result[0].length);
        match_pattern += result[1] === '*' ? 'https?://' : result[1] + '://';

        // Parse host if scheme is not `file`
        if (result[1] !== 'file') {
            if (!(result = /^(?:\*|(\*\.)?([^\/*]+))(?=\/)/.exec(input))) return null;
            input = input.substr(result[0].length);
            if (result[0] === '*') {    // host is '*'
                match_pattern += '[^/]+';
            } else {
                if (result[1]) {         // Subdomain wildcard exists
                    match_pattern += '(?:[^/]+\\.)?';
                }
                // Append host (escape special regex characters)
                match_pattern += regEscape(result[2]);
            }
        }
        // Add remainder (path)
        match_pattern += input.split('*').map(regEscape).join('.*');
        match_pattern += '$)';
        return match_pattern;
    },
    urlsAreEqual: function (urlString1, urlString2) {
        var url1 = new URL(urlString1);
        var url2 = new URL(urlString2);

        return url1.hostname === url2.hostname &&
               url1.pathname === url2.pathname;
    },
    extrapolateUrlFromCookie: function (cookie) {
        var prefix = cookie.secure ? "https://" : "http://";
        if (cookie.domain.charAt(0) == ".")
            prefix += "www";

        return prefix + cookie.domain + cookie.path;
    },
    extrapolateDomainFromMatchURL: function(matchURL) {
        var matches = matchURL.match(".*://(.*)/.*");
        var domain = matches[1];
        if (domain[0] === "*") domain = domain.slice(2);
        return domain;
    },
    getCookiesForDomain: function (domain, cb) {
        chrome.cookies.getAll(
            { domain: Utils.extrapolateDomainFromMatchURL(domain) },
            function(cookies) {
                cb(cookies)
            }
        );
    },
    getURLParams: function () {
        var vars = {};
        var parts = window.location.href.replace(
            /[?&]+([^=&]+)=([^&]*)/gi,
            function(m,key,value) {
                vars[key] = decodeURIComponent(value);
            });
        return vars;
    },
    addURLParam: function(url, parameterName, parameterValue) {
        replaceDuplicates = true;

        if(url.indexOf('#') > 0){
            var cl = url.indexOf('#');
            urlhash = url.substring(url.indexOf('#'),url.length);
        } else {
            urlhash = '';
            cl = url.length;
        }

        sourceUrl = url.substring(0,cl);

        var urlParts = sourceUrl.split("?");
        var newQueryString = "";

        if (urlParts.length > 1)
        {
            var parameters = urlParts[1].split("&");
            for (var i=0; (i < parameters.length); i++)
            {
                var parameterParts = parameters[i].split("=");
                if (!(replaceDuplicates && parameterParts[0] == parameterName))
                {
                    if (newQueryString === "") newQueryString = "?";
                    else newQueryString += "&";
                    newQueryString += parameterParts[0] + "=" + parameterParts[1];
                }
            }
        }
        if (newQueryString === "") newQueryString = "?";
        else newQueryString += "&";
        newQueryString += parameterName + "=" + parameterValue;

        return urlParts[0] + newQueryString + urlhash;
    },
    triggerLoading: function (el, opts) {
        var $el = $(el),
            saveText = $el.text(),
            promise;

        $el.addClass('loading');
        $el.text('loading..');

        if (opts && opts.promise) {
            promise = $.Deferred();
            $.when(promise)
             .then(unload)
            return promise;
        } else {
            setTimeout(unload, 1000);
        }

        function unload() {
            $el.removeClass('loading');
            $el.text(saveText);
        }
    },
    isEmail: function(email) {
        var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
        return regex.test(email);
    },
    settings: {
        waitlistHost: "http://share.getwaltz.com",
        waitlistPaths: {
            reserve: '/u/reserve',
            check: '/u/check',
            setEmail: '/u/email/set',
            inviteCreate: '/i/create',
            inviteAdd: '/i/add',
            inviteClear: '/i/clear'
        }
    }
}

<|endoftext|>


<commit_before>// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/

import colors from 'colors/safe';

/**
 * Use need to allow lazy loading of modules for all tasks. Generally,
 * we assume `build-config.js` exists, however *during* the build process
 * this might not be true, which will break certain native module imports that
 * try to eagerly load this file.
 */
 /* eslint global-require: 0 */

import { logger } from './logging';

const Lazy = {
  buildDeps: () => require('./task-build-deps').default(),
  config: options => require('./task-config-builder').overwriteConfig(options),
  saveConfig: options => require('./task-config-builder').saveConfigAsPrev(options),
  buildServices: () => require('./task-build-services').default(),
  buildMainProcess: () => require('./task-build-main-process').default(),
  buildBrowser: () => require('./task-build-browser').default(),
  buildContent: () => require('./task-build-content').default(),
  run: args => require('./task-run').default(args),
  test: args => require('./task-test').default(args),
  serve: () => require('./task-serve').default(),
  package: () => require('./task-package').default(),
  clean: () => require('./task-clean-package').default(),
};

const unwatch = watchers => {
  logger.info(colors.gray('Stopped watching the filesystem for changes.'));
  return Promise.all(watchers.map(w => w.close()));
};

export default {
  async buildDeps() {
    await Lazy.buildDeps();
  },

  async build(config = {}, options = {}) {
    await Lazy.config(config);
    const watchers = [];
    try {
      watchers.push(await Lazy.buildServices());
      watchers.push(await Lazy.buildMainProcess());
      watchers.push(await Lazy.buildBrowser());
      watchers.push(await Lazy.buildContent());
      logger.info(colors.green('Now watching the filesystem for changes...'));
    } catch (e) {
      await unwatch(watchers);
      throw e;
    }
    if (!options.watch) {
      await unwatch(watchers);
    }
    // Now that we've finished building, store the current configuration
    // so that we may diff in the future to avoid unnecessary builds.
    await Lazy.saveConfig();
    return watchers;
  },

  async serve() {
    await Lazy.config();
    const watchers = [
      await Lazy.buildServices(),
    ];
    await unwatch(watchers);
    // Now that we've finished building, store the current configuration
    // so that we may diff in the future to avoid unnecessary builds.
    await Lazy.saveConfig();
    await Lazy.serve();
  },

  async run(args = []) {
    const watchers = await this.build({}, { watch: true });
    await Lazy.run(args);
    await unwatch(watchers);
  },

  async runDev(args = []) {
    const watchers = await this.build({ development: true }, { watch: true });
    await Lazy.run(args);
    await unwatch(watchers);
  },

  async test(args = []) {
    await this.build({ test: true });
    await Lazy.test(args);
  },

  async package() {
    // XXX: All builds (including packaged) currently start their own
    // UA and Contents services. In the future, we should consider
    // hosting these somewhere else other than the user's own machine.
    await this.build();
    await Lazy.clean();
    await Lazy.package();
  },
};
<commit_msg>Fix 'build-config.js' typo in build/tasks.js<commit_after>// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/

import colors from 'colors/safe';

/**
 * Use need to allow lazy loading of modules for all tasks. Generally,
 * we assume `build-config.json` exists, however *during* the build process
 * this might not be true, which will break certain native module imports that
 * try to eagerly load this file.
 */
 /* eslint global-require: 0 */

import { logger } from './logging';

const Lazy = {
  buildDeps: () => require('./task-build-deps').default(),
  config: options => require('./task-config-builder').overwriteConfig(options),
  saveConfig: options => require('./task-config-builder').saveConfigAsPrev(options),
  buildServices: () => require('./task-build-services').default(),
  buildMainProcess: () => require('./task-build-main-process').default(),
  buildBrowser: () => require('./task-build-browser').default(),
  buildContent: () => require('./task-build-content').default(),
  run: args => require('./task-run').default(args),
  test: args => require('./task-test').default(args),
  serve: () => require('./task-serve').default(),
  package: () => require('./task-package').default(),
  clean: () => require('./task-clean-package').default(),
};

const unwatch = watchers => {
  logger.info(colors.gray('Stopped watching the filesystem for changes.'));
  return Promise.all(watchers.map(w => w.close()));
};

export default {
  async buildDeps() {
    await Lazy.buildDeps();
  },

  async build(config = {}, options = {}) {
    await Lazy.config(config);
    const watchers = [];
    try {
      watchers.push(await Lazy.buildServices());
      watchers.push(await Lazy.buildMainProcess());
      watchers.push(await Lazy.buildBrowser());
      watchers.push(await Lazy.buildContent());
      logger.info(colors.green('Now watching the filesystem for changes...'));
    } catch (e) {
      await unwatch(watchers);
      throw e;
    }
    if (!options.watch) {
      await unwatch(watchers);
    }
    // Now that we've finished building, store the current configuration
    // so that we may diff in the future to avoid unnecessary builds.
    await Lazy.saveConfig();
    return watchers;
  },

  async serve() {
    await Lazy.config();
    const watchers = [
      await Lazy.buildServices(),
    ];
    await unwatch(watchers);
    // Now that we've finished building, store the current configuration
    // so that we may diff in the future to avoid unnecessary builds.
    await Lazy.saveConfig();
    await Lazy.serve();
  },

  async run(args = []) {
    const watchers = await this.build({}, { watch: true });
    await Lazy.run(args);
    await unwatch(watchers);
  },

  async runDev(args = []) {
    const watchers = await this.build({ development: true }, { watch: true });
    await Lazy.run(args);
    await unwatch(watchers);
  },

  async test(args = []) {
    await this.build({ test: true });
    await Lazy.test(args);
  },

  async package() {
    // XXX: All builds (including packaged) currently start their own
    // UA and Contents services. In the future, we should consider
    // hosting these somewhere else other than the user's own machine.
    await this.build();
    await Lazy.clean();
    await Lazy.package();
  },
};
<|endoftext|>


<commit_before>/*
 * Twitter Fader jQuery Plugin version 1.1.1
 * Chris Cook - chris@chris-cook.co.uk
 */

(function ($) {

	'use strict';

	$.fn.twitterFader = function (searchTerm, options) {

		var settings = $.extend({
			displayRate : 10000,
			fadeRate : 300,
			returnNum : 5,
			returnType : 'recent',
			returnLanguage : 'en',
			linkify: true
		}, options),
		$fader = $(this);

		function linkify(text) {
			var url_pattern = /(\()((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(\))|(\[)((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(\])|(\{)((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(\})|(<|&(?:lt|#60|#x3c);)((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(>|&(?:gt|#62|#x3e);)|((?:^|[^=\s'"\]])\s*['"]?|[^=\s]\s+)(\b(?:ht|f)tps?:\/\/[a-z0-9\-._~!$'()*+,;=:\/?#[\]@%]+(?:(?!&(?:gt|#0*62|#x0*3e);|&(?:amp|apos|quot|#0*3[49]|#x0*2[27]);[.!&',:?;]?(?:[^a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]|$))&[a-z0-9\-._~!$'()*+,;=:\/?#[\]@%]*)*[a-z0-9\-_~$()*+=\/#[\]@%])/img;
			var url_replace = '$1$4$7$10$13$2$5$8$11$14$3$6$9$12';
			return text.replace(url_pattern, url_replace);
		}

		if (!searchTerm) {
			$fader.html('Error! You need to enter a search term.');
		} else {
			return this.each(function () {
				$fader.html('Loading…');
				update();
				setInterval(update, (settings.displayRate * settings.returnNum) + ((settings.fadeRate * 2) * settings.returnNum));
				function update() {
					$.getJSON(
						'http://search.twitter.com/search.json?callback=?', {
							q : searchTerm,
							rpp : settings.returnNum,
							lang : settings.returnLanguage,
							result_type : settings.returnType
						},
						function (json) {
							$fader.html('');
							if (json.results.length > 0) {
								$.each(json.results, function (i, item) {
									var text = settings.linkify ? linkify(item.text) : item.text;
									$fader.append('
@' + item.from_user + ': ' + text + '
');
								});
								setInterval(function (){ $fader.children('li').first().fadeIn(settings.fadeRate).delay(settings.displayRate).fadeOut(settings.fadeRate, function () { $(this).remove() } ) }, 1);
							} else {
								$fader.append('No results found');
							}
						}
					);
				}
			});
		}

	};

})(jQuery);
<commit_msg>Minor code formatting tweak<commit_after>/*
 * Twitter Fader jQuery Plugin version 1.1.1
 * Chris Cook - chris@chris-cook.co.uk
 */

(function ($) {

	'use strict';

	$.fn.twitterFader = function (searchTerm, options) {

		var settings = $.extend({
			displayRate : 10000,
			fadeRate : 300,
			returnNum : 5,
			returnType : 'recent',
			returnLanguage : 'en',
			linkify: true
		}, options),
		$fader = $(this);

		function linkify(text) {
			var url_pattern = /(\()((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(\))|(\[)((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(\])|(\{)((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(\})|(<|&(?:lt|#60|#x3c);)((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]+)(>|&(?:gt|#62|#x3e);)|((?:^|[^=\s'"\]])\s*['"]?|[^=\s]\s+)(\b(?:ht|f)tps?:\/\/[a-z0-9\-._~!$'()*+,;=:\/?#[\]@%]+(?:(?!&(?:gt|#0*62|#x0*3e);|&(?:amp|apos|quot|#0*3[49]|#x0*2[27]);[.!&',:?;]?(?:[^a-z0-9\-._~!$&'()*+,;=:\/?#[\]@%]|$))&[a-z0-9\-._~!$'()*+,;=:\/?#[\]@%]*)*[a-z0-9\-_~$()*+=\/#[\]@%])/img;
			var url_replace = '$1$4$7$10$13$2$5$8$11$14$3$6$9$12';
			return text.replace(url_pattern, url_replace);
		}

		if (!searchTerm) {
			$fader.html('Error! You need to enter a search term.');
		} else {
			return this.each(function () {
				$fader.html('Loading…');
				update();
				setInterval(update, (settings.displayRate * settings.returnNum) + ((settings.fadeRate * 2) * settings.returnNum));
				function update() {
					$.getJSON(
						'http://search.twitter.com/search.json?callback=?', {
							q : searchTerm,
							rpp : settings.returnNum,
							lang : settings.returnLanguage,
							result_type : settings.returnType
						},
						function (json) {
							$fader.html('');
							if (json.results.length > 0) {
								$.each(json.results, function (i, item) {
									var text = settings.linkify ? linkify(item.text) : item.text;
									$fader.append('
@' + item.from_user + ': ' + text + '
');
								});
								setInterval(function () {
									$fader.children('li').first().fadeIn(settings.fadeRate).delay(settings.displayRate).fadeOut(settings.fadeRate, function () { $(this).remove() } )
								}, 1);
							} else {
								$fader.append('No results found');
							}
						}
					);
				}
			});
		}

	};

})(jQuery);
<|endoftext|>


<commit_before>$(document).ready(function() {

	//snapping
$('body').panelSnap();

$(".carousel-caption").animate({
        marginLeft: "+=9999px",
    }, 1000 );

	//scroling menu
var sections = $('section')
  , nav = $('nav')
  , nav_height = 100;
 //nav.outerHeight()

$(window).on('scroll', function () {
  var cur_pos = $(this).scrollTop();
  sections.each(function() {

    var top = $(this).offset().top - nav_height,
        bottom = top + $(this).outerHeight();
    if (cur_pos >= top && cur_pos <= bottom) {

      sections.removeClass('active');
      $(this).addClass('active');

	  nav.find('a').parent().removeClass('active');
      nav.find('a[href="#'+$(this).attr('id')+'"]').parent().addClass('active');

	  scolor = rgb2hex($(this).css("background-color"));
	  iscolor = getContrast50(scolor);
	  nav.find('a').css("color",iscolor);
	  //nav.find('a').parent().removeClass('active');
	  nav.find('a').parent().addClass('white_back');
    }
  });
});
			//menu_click_scroling
	nav.find('a').on("click", function(){
		event.preventDefault();
		id = $(this).attr("href");
		scrollToID(id, 800);
	});

});

function scrollToID(id, speed){
	var targetOffset = $(id).offset().top;
	$('html,body').animate({scrollTop:targetOffset}, speed);
}

function rgb2hex(rgb){
 rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
 return (rgb && rgb.length === 4) ?
  ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
  ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
  ("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
}

function getContrast50(hexcolor){
    return (parseInt(hexcolor, 16) > 0xffffff/2) ? 'black':'white';
}<commit_msg>white<commit_after>$(document).ready(function() {

	//snapping
$('body').panelSnap();

$(".carousel-caption").animate({
        marginLeft: "+=9999px",
    }, 1000 );

	//scroling menu
var sections = $('section')
  , nav = $('nav')
  , nav_height = 100;
 //nav.outerHeight()

$(window).on('scroll', function () {
  var cur_pos = $(this).scrollTop();
  sections.each(function() {

    var top = $(this).offset().top - nav_height,
        bottom = top + $(this).outerHeight();
    if (cur_pos >= top && cur_pos <= bottom) {

      sections.removeClass('active');
      $(this).addClass('active');

	  nav.find('a').parent().removeClass('active');
      nav.find('a[href="#'+$(this).attr('id')+'"]').parent().addClass('active');

	  scolor = rgb2hex($(this).css("background-color"));
	  iscolor = getContrast50(scolor);
	  nav.find('a').css("color",iscolor);
	  //nav.find('a').parent().removeClass('active');
	  nav.find("a[class='active']").parent().addClass('white_back');
    }
  });
});
			//menu_click_scroling
	nav.find('a').on("click", function(){
		event.preventDefault();
		id = $(this).attr("href");
		scrollToID(id, 800);
	});

});

function scrollToID(id, speed){
	var targetOffset = $(id).offset().top;
	$('html,body').animate({scrollTop:targetOffset}, speed);
}

function rgb2hex(rgb){
 rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
 return (rgb && rgb.length === 4) ?
  ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
  ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
  ("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
}

function getContrast50(hexcolor){
    return (parseInt(hexcolor, 16) > 0xffffff/2) ? 'black':'white';
}<|endoftext|>