<commit_before>import { createSelector } from 'reselect';
import { PokerHelper, ReceiptCache } from 'poker-helper';
import EWT from 'ethereum-web-token';
import { makeSignerAddrSelector } from '../AccountProvider/selectors';

const rc = new ReceiptCache();
const pokerHelper = new PokerHelper(rc);

// direct selectors to state
const tableStateSelector = (state, props) => (state && props) ? state.getIn(['table', props.params.tableAddr]) : null;

const handSelector = (state, props) => (state && props) ? state.getIn(['table', props.params.tableAddr, props.params.handId.toString()]) : null;

const posSelector = (state, props) => (props) ? props.pos : null;

const actionSelector = (action) => action;

const addressSelector = (state, props) => (props) ? props.address : null;

const myPosByAction = createSelector(
  [actionSelector, addressSelector],
  (action, myAddr) => {
    if (!myAddr || !action.hand || !action.hand.lineup) {
      return -1;
    }
    for (let i = 0; i < action.hand.lineup.length; i += 1) {
      if (myAddr === action.hand.lineup[i].address) {
        return i;
      }
    }
    return -1;
  }
);

const isSbTurnByAction = createSelector(
  [actionSelector, myPosByAction],
  (action, myPos) => {
    if (!action.hand) {
      return false;
    }
    const sbPos = pokerHelper.getSbPos(action.hand.lineup, action.hand.dealer);
    if (typeof sbPos === 'undefined' || sbPos < 0) {
      return false;
    }
    const whosTurn = pokerHelper.whosTurn(action.hand);
    if (typeof whosTurn === 'undefined' || whosTurn < 0) {
      return false;
    }
    if (action.hand.state === 'waiting' && whosTurn === sbPos && sbPos === myPos) {
      return true;
    }
    return false;
  }
);

const isBbTurnByAction = createSelector(
  [actionSelector, myPosByAction],
  (action, myPos) => {
    if (!action.hand) {
      return false;
    }
    const bbPos = pokerHelper.getBbPos(action.hand.lineup, action.hand.dealer);
    if (typeof bbPos === 'undefined' || bbPos < 0) {
      return false;
    }
    const whosTurn = pokerHelper.whosTurn(action.hand);
    if (typeof whosTurn === 'undefined' || whosTurn < 0) {
      return false;
    }
    if (action.hand.state === 'dealing' && whosTurn === bbPos && bbPos === myPos) {
      return true;
    }
    return false;
  }
);

const is0rTurnByAction = createSelector(
  [actionSelector, myPosByAction, isSbTurnByAction, isBbTurnByAction],
  (action, myPos, sbTurn, bbTurn) => {
    if (!action.hand || !action.hand.lineup) {
      return false;
    }
    const whosTurn = pokerHelper.whosTurn(action.hand);
    if (typeof whosTurn === 'undefined' || whosTurn < 0) {
      return false;
    }
    if (action.hand.state === 'dealing' && !sbTurn && !bbTurn && whosTurn === myPos) {
      return true;
    }
    return false;
  }
);

const isShowTurnByAction = createSelector(
  [actionSelector, myPosByAction],
  (action, myPos) => {
    if (!action || !action.hand || action.hand.state !== 'showdown') {
      return false;
    }
    const whosTurn = pokerHelper.whosTurn(action.hand);
    if (typeof whosTurn === 'undefined' || whosTurn < 0) {
      return false;
    }
    if (whosTurn === myPos) {
      return true;
    }
    return false;
  }
);

const hasNettingInAction = createSelector(
  [actionSelector, addressSelector],
  (action, myAddr) => {
    // check data available
    console.log(action.hand.netting);
    if (!myAddr || !action || !action.hand || !action.hand.netting) {
      return false;
    }
    // check already signed
    if (action.hand.netting[myAddr]) {
      return false;
    }
    return true;
  }
);

// other selectors
const makeHandSelector = () => createSelector(
  handSelector,
  (hand) => hand
);

const makeHandStateSelector = () => createSelector(
  makeHandSelector(),
  (hand) => (hand) ? hand.get('state') : null
);

const makeBoardSelector = () => createSelector(
  makeHandSelector(),
  (hand) => (hand && hand.get('cards')) ? hand.get('cards').toJS() : []
);

const makeTableDataSelector = () => createSelector(
  tableStateSelector,
  (table) => (table) ? (table.get('data')) : null
);

const makeSbSelector = () => createSelector(
  [makeTableDataSelector()],
  (data) => {
    if (!data || typeof data.get('smallBlind') === 'undefined') {
      return null;
    }
    return data.get('smallBlind');
  }
);

const makeMinSelector = () => createSelector(
  [makeSbSelector(), makeAmountToCallSelector()],
  (sb, amountToCall) => {
    if (!sb) {
      return -1;
    }
    if (amountToCall === 0) {
      return (sb * 2);
    }
    return amountToCall;
  }
);

const makeMaxSelector = () => createSelector(
  [makeMinSelector(), makeMyStackSelector()],
  (min, stack) => (Math.floor(stack / min) * min) + min
);

const makeLineupSelector = () => createSelector(
  [handSelector, tableStateSelector],
  (hand, table) => {
    // we have no table yet
    if (!table || !table.get('data')) {
      return null;
    }

    // we have table, but no hand
    if (!hand || !hand.get('lineup')) {
      return table.getIn(['data', 'seats']);
    }

    // if we have a hand, just get the hand
    return hand.get('lineup');
  }
);

const makeAmountSelector = () => createSelector(
  tableStateSelector,
  (tableState) => (tableState) ? tableState.get('amount') : null
);

const makeComputedSelector = () => createSelector(
  tableStateSelector,
  (tableState) => (tableState) ? tableState.get('computedStyles') : null
);

const makeMyPosSelector = () => createSelector(
  [makeLineupSelector(), makeSignerAddrSelector()],
  (lineup, myAddress) => (lineup && myAddress) ? pokerHelper.getMyPos(lineup.toJS(), myAddress) : -1
);

const makeWhosTurnSelector = () => createSelector(
  makeHandSelector(),
  (hand) => (hand && hand.get('lineup').size > 0) ? pokerHelper.whosTurn(hand.toJS()) : -1
);

const makeIsMyTurnSelector = () => createSelector(
  [makeMyPosSelector(), makeWhosTurnSelector()],
  (myPos, whosTurn) => (myPos > -1 && whosTurn > -1) ? myPos === whosTurn : false
);

const makeMaxBetSelector = () => createSelector(
  [makeHandSelector(), makeLineupSelector()],
  (hand, lineup) => (hand && lineup && lineup.toJS) ? pokerHelper.findMaxBet(lineup.toJS(), hand.get('dealer')).amount : 0
);

const makeMyMaxBetSelector = () => createSelector(
  [makeLineupSelector(), makeSignerAddrSelector()],
  (lineup, myAddress) => (lineup && lineup.toJS && myAddress) ? pokerHelper.getMyMaxBet(lineup.toJS(), myAddress) : 0
);

const makeAmountToCallSelector = () => createSelector(
  [makeMaxBetSelector(), makeMyMaxBetSelector()],
  (maxBet, myMaxbet) => (maxBet && myMaxbet) ? maxBet - myMaxbet : 0
);

const makeMissingHandSelector = () => createSelector(
  [tableStateSelector],
  (table) => {
    if (!table) {
      return null;
    }
    // get state of contract
    const lastHandNetted = table.getIn(['data', 'lastHandNetted']);
    if (typeof lastHandNetted === 'undefined' || lastHandNetted < 1) {
      return null;
    }
    // get progress of state channel
    let maxHand = 0;
    table.keySeq().forEach((k) => {
      if (!isNaN(k)) {
        const handId = parseInt(k, 10);
        if (handId > maxHand) {
          maxHand = handId;
        }
      }
    });
    // handle empty state channel
    if (maxHand <= lastHandNetted) {
      return [lastHandNetted + 1];
    }
    const rsp = [];
    for (let i = lastHandNetted + 1; i < maxHand; i += 1) {
      if (!table.get(i.toString())) {
        rsp.push(i);
      }
    }
    return rsp;
  }
);

const makeLatestHandSelector = () => createSelector(
  [tableStateSelector],
  (table) => {
    if (!table) {
      return null;
    }

    // get progress of state channel
    let maxHand = 2;
    table.keySeq().forEach((k) => {
      if (!isNaN(k)) {
        const handId = parseInt(k, 10);
        if (handId > maxHand) {
          maxHand = handId;
        }
      }
    });

    return maxHand;
  }
);

const makeStackSelector = () => createSelector(
  [tableStateSelector, posSelector],
  selectStack
);

const makeMyStackSelector = () => createSelector(
  [tableStateSelector, makeMyPosSelector()],
  selectStack
);

const makePotSizeSelector = () => createSelector(
  makeLineupSelector(),
  (lineup) => (lineup) ? pokerHelper.calculatePotsize(lineup.toJS()) : 0
);

const selectStack = (table, pos) => {
  // make sure we have a position to work on
  if (typeof pos === 'undefined') {
    return null;
  }
  // get state of contract
  const lastHandNetted = table.getIn(['data', 'lastHandNetted']);
  if (typeof lastHandNetted === 'undefined' || lastHandNetted < 1) {
    return null;
  }
  const addr = table.getIn(['data', 'seats', pos, 'address']);
  let amount = table.getIn(['data', 'amounts', pos]);
  // get progress of state channel
  let maxHand = 0;
  table.keySeq().forEach((k) => {
    if (!isNaN(k)) {
      const handId = parseInt(k, 10);
      if (handId > maxHand) {
        maxHand = handId;
      }
    }
  });
  // handle empty state channel
  if (maxHand === 0) {
    return amount;
  }
  if (maxHand <= lastHandNetted) {
    return amount;
  }
  // sum up state channel
  for (let i = lastHandNetted + 1; i <= maxHand; i += 1) {
    // get all the bets
    const rec = table.getIn([i.toString(), 'lineup', pos, 'last']);
    const bet = (rec) ? EWT.parse(rec).values[1] : 0;
    if (typeof bet !== 'undefined') {
      amount -= bet;
    }
    // get all the winnings
    const distsRec = table.getIn([i.toString(), 'distribution']);
    if (distsRec) {
      const dists = EWT.parse(distsRec);
      for (let j = 0; j < dists.values[2].length; j += 1) {
        const dist = EWT.separate(dists.values[2][j]);
        if (dist.address === addr) {
          amount += dist.amount;
        }
      }
    }
  }
  return amount;
};

export {
    tableStateSelector,
    actionSelector,
    isSbTurnByAction,
    isBbTurnByAction,
    is0rTurnByAction,
    isShowTurnByAction,
    hasNettingInAction,
    makeTableDataSelector,
    makeSbSelector,
    makeAmountSelector,
    makeLineupSelector,
    makeHandStateSelector,
    makeLatestHandSelector,
    makeBoardSelector,
    makeIsMyTurnSelector,
    makeWhosTurnSelector,
    makePotSizeSelector,
    makeAmountToCallSelector,
    makeMyPosSelector,
    makeHandSelector,
    makeMaxBetSelector,
    makeMyMaxBetSelector,
    makeComputedSelector,
    makeMyStackSelector,
    makeMinSelector,
    makeMaxSelector,
    makeStackSelector,
    makeMissingHandSelector,
};

<commit_msg>removed console log from selector<commit_after>import { createSelector } from 'reselect';
import { PokerHelper, ReceiptCache } from 'poker-helper';
import EWT from 'ethereum-web-token';
import { makeSignerAddrSelector } from '../AccountProvider/selectors';

const rc = new ReceiptCache();
const pokerHelper = new PokerHelper(rc);

// direct selectors to state
const tableStateSelector = (state, props) => (state && props) ? state.getIn(['table', props.params.tableAddr]) : null;

const handSelector = (state, props) => (state && props) ? state.getIn(['table', props.params.tableAddr, props.params.handId.toString()]) : null;

const posSelector = (state, props) => (props) ? props.pos : null;

const actionSelector = (action) => action;

const addressSelector = (state, props) => (props) ? props.address : null;

const myPosByAction = createSelector(
  [actionSelector, addressSelector],
  (action, myAddr) => {
    if (!myAddr || !action.hand || !action.hand.lineup) {
      return -1;
    }
    for (let i = 0; i < action.hand.lineup.length; i += 1) {
      if (myAddr === action.hand.lineup[i].address) {
        return i;
      }
    }
    return -1;
  }
);

const isSbTurnByAction = createSelector(
  [actionSelector, myPosByAction],
  (action, myPos) => {
    if (!action.hand) {
      return false;
    }
    const sbPos = pokerHelper.getSbPos(action.hand.lineup, action.hand.dealer);
    if (typeof sbPos === 'undefined' || sbPos < 0) {
      return false;
    }
    const whosTurn = pokerHelper.whosTurn(action.hand);
    if (typeof whosTurn === 'undefined' || whosTurn < 0) {
      return false;
    }
    if (action.hand.state === 'waiting' && whosTurn === sbPos && sbPos === myPos) {
      return true;
    }
    return false;
  }
);

const isBbTurnByAction = createSelector(
  [actionSelector, myPosByAction],
  (action, myPos) => {
    if (!action.hand) {
      return false;
    }
    const bbPos = pokerHelper.getBbPos(action.hand.lineup, action.hand.dealer);
    if (typeof bbPos === 'undefined' || bbPos < 0) {
      return false;
    }
    const whosTurn = pokerHelper.whosTurn(action.hand);
    if (typeof whosTurn === 'undefined' || whosTurn < 0) {
      return false;
    }
    if (action.hand.state === 'dealing' && whosTurn === bbPos && bbPos === myPos) {
      return true;
    }
    return false;
  }
);

const is0rTurnByAction = createSelector(
  [actionSelector, myPosByAction, isSbTurnByAction, isBbTurnByAction],
  (action, myPos, sbTurn, bbTurn) => {
    if (!action.hand || !action.hand.lineup) {
      return false;
    }
    const whosTurn = pokerHelper.whosTurn(action.hand);
    if (typeof whosTurn === 'undefined' || whosTurn < 0) {
      return false;
    }
    if (action.hand.state === 'dealing' && !sbTurn && !bbTurn && whosTurn === myPos) {
      return true;
    }
    return false;
  }
);

const isShowTurnByAction = createSelector(
  [actionSelector, myPosByAction],
  (action, myPos) => {
    if (!action || !action.hand || action.hand.state !== 'showdown') {
      return false;
    }
    const whosTurn = pokerHelper.whosTurn(action.hand);
    if (typeof whosTurn === 'undefined' || whosTurn < 0) {
      return false;
    }
    if (whosTurn === myPos) {
      return true;
    }
    return false;
  }
);

const hasNettingInAction = createSelector(
  [actionSelector, addressSelector],
  (action, myAddr) => {
    // check data available
    if (!myAddr || !action || !action.hand || !action.hand.netting) {
      return false;
    }
    // check already signed
    if (action.hand.netting[myAddr]) {
      return false;
    }
    return true;
  }
);

// other selectors
const makeHandSelector = () => createSelector(
  handSelector,
  (hand) => hand
);

const makeHandStateSelector = () => createSelector(
  makeHandSelector(),
  (hand) => (hand) ? hand.get('state') : null
);

const makeBoardSelector = () => createSelector(
  makeHandSelector(),
  (hand) => (hand && hand.get('cards')) ? hand.get('cards').toJS() : []
);

const makeTableDataSelector = () => createSelector(
  tableStateSelector,
  (table) => (table) ? (table.get('data')) : null
);

const makeSbSelector = () => createSelector(
  [makeTableDataSelector()],
  (data) => {
    if (!data || typeof data.get('smallBlind') === 'undefined') {
      return null;
    }
    return data.get('smallBlind');
  }
);

const makeMinSelector = () => createSelector(
  [makeSbSelector(), makeAmountToCallSelector()],
  (sb, amountToCall) => {
    if (!sb) {
      return -1;
    }
    if (amountToCall === 0) {
      return (sb * 2);
    }
    return amountToCall;
  }
);

const makeMaxSelector = () => createSelector(
  [makeMinSelector(), makeMyStackSelector()],
  (min, stack) => (Math.floor(stack / min) * min) + min
);

const makeLineupSelector = () => createSelector(
  [handSelector, tableStateSelector],
  (hand, table) => {
    // we have no table yet
    if (!table || !table.get('data')) {
      return null;
    }

    // we have table, but no hand
    if (!hand || !hand.get('lineup')) {
      return table.getIn(['data', 'seats']);
    }

    // if we have a hand, just get the hand
    return hand.get('lineup');
  }
);

const makeAmountSelector = () => createSelector(
  tableStateSelector,
  (tableState) => (tableState) ? tableState.get('amount') : null
);

const makeComputedSelector = () => createSelector(
  tableStateSelector,
  (tableState) => (tableState) ? tableState.get('computedStyles') : null
);

const makeMyPosSelector = () => createSelector(
  [makeLineupSelector(), makeSignerAddrSelector()],
  (lineup, myAddress) => (lineup && myAddress) ? pokerHelper.getMyPos(lineup.toJS(), myAddress) : -1
);

const makeWhosTurnSelector = () => createSelector(
  makeHandSelector(),
  (hand) => (hand && hand.get('lineup').size > 0) ? pokerHelper.whosTurn(hand.toJS()) : -1
);

const makeIsMyTurnSelector = () => createSelector(
  [makeMyPosSelector(), makeWhosTurnSelector()],
  (myPos, whosTurn) => (myPos > -1 && whosTurn > -1) ? myPos === whosTurn : false
);

const makeMaxBetSelector = () => createSelector(
  [makeHandSelector(), makeLineupSelector()],
  (hand, lineup) => (hand && lineup && lineup.toJS) ? pokerHelper.findMaxBet(lineup.toJS(), hand.get('dealer')).amount : 0
);

const makeMyMaxBetSelector = () => createSelector(
  [makeLineupSelector(), makeSignerAddrSelector()],
  (lineup, myAddress) => (lineup && lineup.toJS && myAddress) ? pokerHelper.getMyMaxBet(lineup.toJS(), myAddress) : 0
);

const makeAmountToCallSelector = () => createSelector(
  [makeMaxBetSelector(), makeMyMaxBetSelector()],
  (maxBet, myMaxbet) => (maxBet && myMaxbet) ? maxBet - myMaxbet : 0
);

const makeMissingHandSelector = () => createSelector(
  [tableStateSelector],
  (table) => {
    if (!table) {
      return null;
    }
    // get state of contract
    const lastHandNetted = table.getIn(['data', 'lastHandNetted']);
    if (typeof lastHandNetted === 'undefined' || lastHandNetted < 1) {
      return null;
    }
    // get progress of state channel
    let maxHand = 0;
    table.keySeq().forEach((k) => {
      if (!isNaN(k)) {
        const handId = parseInt(k, 10);
        if (handId > maxHand) {
          maxHand = handId;
        }
      }
    });
    // handle empty state channel
    if (maxHand <= lastHandNetted) {
      return [lastHandNetted + 1];
    }
    const rsp = [];
    for (let i = lastHandNetted + 1; i < maxHand; i += 1) {
      if (!table.get(i.toString())) {
        rsp.push(i);
      }
    }
    return rsp;
  }
);

const makeLatestHandSelector = () => createSelector(
  [tableStateSelector],
  (table) => {
    if (!table) {
      return null;
    }

    // get progress of state channel
    let maxHand = 2;
    table.keySeq().forEach((k) => {
      if (!isNaN(k)) {
        const handId = parseInt(k, 10);
        if (handId > maxHand) {
          maxHand = handId;
        }
      }
    });

    return maxHand;
  }
);

const makeStackSelector = () => createSelector(
  [tableStateSelector, posSelector],
  selectStack
);

const makeMyStackSelector = () => createSelector(
  [tableStateSelector, makeMyPosSelector()],
  selectStack
);

const makePotSizeSelector = () => createSelector(
  makeLineupSelector(),
  (lineup) => (lineup) ? pokerHelper.calculatePotsize(lineup.toJS()) : 0
);

const selectStack = (table, pos) => {
  // make sure we have a position to work on
  if (typeof pos === 'undefined') {
    return null;
  }
  // get state of contract
  const lastHandNetted = table.getIn(['data', 'lastHandNetted']);
  if (typeof lastHandNetted === 'undefined' || lastHandNetted < 1) {
    return null;
  }
  const addr = table.getIn(['data', 'seats', pos, 'address']);
  let amount = table.getIn(['data', 'amounts', pos]);
  // get progress of state channel
  let maxHand = 0;
  table.keySeq().forEach((k) => {
    if (!isNaN(k)) {
      const handId = parseInt(k, 10);
      if (handId > maxHand) {
        maxHand = handId;
      }
    }
  });
  // handle empty state channel
  if (maxHand === 0) {
    return amount;
  }
  if (maxHand <= lastHandNetted) {
    return amount;
  }
  // sum up state channel
  for (let i = lastHandNetted + 1; i <= maxHand; i += 1) {
    // get all the bets
    const rec = table.getIn([i.toString(), 'lineup', pos, 'last']);
    const bet = (rec) ? EWT.parse(rec).values[1] : 0;
    if (typeof bet !== 'undefined') {
      amount -= bet;
    }
    // get all the winnings
    const distsRec = table.getIn([i.toString(), 'distribution']);
    if (distsRec) {
      const dists = EWT.parse(distsRec);
      for (let j = 0; j < dists.values[2].length; j += 1) {
        const dist = EWT.separate(dists.values[2][j]);
        if (dist.address === addr) {
          amount += dist.amount;
        }
      }
    }
  }
  return amount;
};

export {
    tableStateSelector,
    actionSelector,
    isSbTurnByAction,
    isBbTurnByAction,
    is0rTurnByAction,
    isShowTurnByAction,
    hasNettingInAction,
    makeTableDataSelector,
    makeSbSelector,
    makeAmountSelector,
    makeLineupSelector,
    makeHandStateSelector,
    makeLatestHandSelector,
    makeBoardSelector,
    makeIsMyTurnSelector,
    makeWhosTurnSelector,
    makePotSizeSelector,
    makeAmountToCallSelector,
    makeMyPosSelector,
    makeHandSelector,
    makeMaxBetSelector,
    makeMyMaxBetSelector,
    makeComputedSelector,
    makeMyStackSelector,
    makeMinSelector,
    makeMaxSelector,
    makeStackSelector,
    makeMissingHandSelector,
};

<|endoftext|>


<commit_before>// Copyright 2013-2016, University of Colorado Boulder

/**
 * Configuration file for development and production deployments.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

require.config( {
  // depends on all of Scenery, Kite, Dot, Axon and phet-core
  deps: [ 'main', 'KITE/main', 'DOT/main', 'AXON/main', 'PHET_CORE/main' ],

  paths: {

    // plugins
    image: '../../chipper/js/requirejs-plugins/image',
    ifphetio: '../../chipper/js/requirejs-plugins/ifphetio',

    // third-party libs
    text: '../../sherpa/lib/text-2.0.12',

    SCENERY: '.',
    KITE: '../../kite/js',
    DOT: '../../dot/js',
    PHET_CORE: '../../phet-core/js',
    AXON: '../../axon/js',

    TANDEM: '../../tandem/js',
    REPOSITORY: '..'
  },

  // optional cache buster to make browser refresh load all included scripts, can be disabled with ?cacheBuster=false
  urlArgs: Date.now()
} );
<commit_msg>brand === phet-io for Brand.phetioEnabled, https://github.com/phetsims/phet-io/issues/1106<commit_after>// Copyright 2013-2016, University of Colorado Boulder

/**
 * Configuration file for development and production deployments.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

require.config( {
  // depends on all of Scenery, Kite, Dot, Axon and phet-core
  deps: [ 'main', 'KITE/main', 'DOT/main', 'AXON/main', 'PHET_CORE/main' ],

  paths: {

    // plugins
    image: '../../chipper/js/requirejs-plugins/image',
    ifphetio: '../../chipper/js/requirejs-plugins/ifphetio',

    // third-party libs
    text: '../../sherpa/lib/text-2.0.12',

    AXON: '../../axon/js',

    // Needs to be compatible in the sim, and also with scenery unit tests.
    BRAND: '../../brand/' + (window.phet && phet.chipper && phet.chipper.brand ? phet.chipper.brand : 'adapted-from-phet') + '/js',
    DOT: '../../dot/js',
    KITE: '../../kite/js',
    PHET_CORE: '../../phet-core/js',
    SCENERY: '.',
    TANDEM: '../../tandem/js',

    REPOSITORY: '..'
  },

  // optional cache buster to make browser refresh load all included scripts, can be disabled with ?cacheBuster=false
  urlArgs: Date.now()
} );
<|endoftext|>


<commit_before>var Schema = require('./../Schema');

function BuildController(mongoose){

    var convert = function(build){
        return build
    };

    this.get = function (req, res) {
        var Build = mongoose.model('Build', Schema.buildSchema);
        Build.findOne({"blueprint.owner": req.params.owner, "blueprint.repo": req.params.repo}, {}, { sort: { 'created_at' : 1 } }, function(err, build){
            if(err || build === null) res.status(404).json({message: 'No build found'});
            else res.json(convert(build));
        });
    };
}

module.exports = BuildController;<commit_msg>Convert file paths to urls<commit_after>var _ = require('underscore'),
    Schema = require('./../Schema'),
    CONFIG = require('config');

function BuildController(mongoose){

    var convert = function(build){

        var makeUrl = function(owner, repo, name, type){
            return CONFIG.url + '/file/' + owner + '/' + repo + '/' + name + '/' + type;
        };

        var documents = []

        _.each(build.documents, function (document) {
            var files = [];
            _.each(build.document.files, function(file){
                files.push({
                    type: file.type,
                    name: file.name,
                    url: makeUrl(build.blueprint.owner, build.blueprint.repo, build.documents.name, file.type)
                });
            });
            document.files = files;
            documents.push(document);
        });
        build.documents = documents;
        return build;
    };

    this.get = function (req, res) {
        var Build = mongoose.model('Build', Schema.buildSchema);
        Build.findOne({"blueprint.owner": req.params.owner, "blueprint.repo": req.params.repo}, {}, { sort: { 'created_at' : 1 } }, function(err, build){
            if(err || build === null) res.status(404).json({message: 'No build found'});
            else res.json(convert(build));
        });
    };
}

module.exports = BuildController;<|endoftext|>


<commit_before>/*	Responsive Boilerplate V.2.3.
	  Designed & Built by Fernando Monteiro, http://www.newaeonweb.com.br
	  Licensed under MIT license, http://opensource.org/licenses/mit-license.php

*/

//Hide the url bar on smartphones
/*
  * Normalized hide address bar for iOS & Android
  * (c) Scott Jehl, scottjehl.com
  * MIT License
*/
(function( win ){
  var doc = win.document;

  // If there's a hash, or addEventListener is undefined, stop here
  if( !location.hash && win.addEventListener ){

    //scroll to 1
    window.scrollTo( 0, 1 );
    var scrollTop = 1,
      getScrollTop = function(){
        return win.pageYOffset || doc.compatMode === "CSS1Compat" && doc.documentElement.scrollTop || doc.body.scrollTop || 0;
      },

      //reset to 0 on bodyready, if needed
      bodycheck = setInterval(function(){
        if( doc.body ){
          clearInterval( bodycheck );
          scrollTop = getScrollTop();
          win.scrollTo( 0, scrollTop === 1 ? 0 : 1 );
        }
      }, 15 );

    win.addEventListener( "load", function(){
      setTimeout(function(){
        //at load, if user hasn't scrolled more than 20 or so...
        if( getScrollTop() < 20 ){
          //reset to hide addr bar at onload
          win.scrollTo( 0, scrollTop === 1 ? 0 : 1 );
        }
      }, 0);
    } );
  }
})( this );

//Simple function to a responsive menu
(function() {
   $("#nav").before('
 &#9776
');

    $("#menu").on('click', function(){
        $("#nav").toggle();
    });

    $(window).resize(function(){
      if(window.innerWidth > 768) {
        $("#nav").removeAttr("style");
        }
    });
})( this );
//apply to any markap with nav like this:
/*

Link

Link

Link

Link

Link

*/

//Add your scripts here
<commit_msg>removed unused white space<commit_after>/*	Responsive Boilerplate V.2.3.
 Designed & Built by Fernando Monteiro, http://www.newaeonweb.com.br
 Licensed under MIT license, http://opensource.org/licenses/mit-license.php

 */

//Hide the url bar on smartphones
/*
 * Normalized hide address bar for iOS & Android
 * (c) Scott Jehl, scottjehl.com
 * MIT License
 */
(function (win) {
    var doc = win.document;

    // If there's a hash, or addEventListener is undefined, stop here
    if (!location.hash && win.addEventListener) {

        //scroll to 1
        window.scrollTo(0, 1);
        var scrollTop = 1,
            getScrollTop = function () {
                return win.pageYOffset || doc.compatMode === "CSS1Compat" && doc.documentElement.scrollTop || doc.body.scrollTop || 0;
            },

        //reset to 0 on bodyready, if needed
            bodycheck = setInterval(function () {
                if (doc.body) {
                    clearInterval(bodycheck);
                    scrollTop = getScrollTop();
                    win.scrollTo(0, scrollTop === 1 ? 0 : 1);
                }
            }, 15);

        win.addEventListener("load", function () {
            setTimeout(function () {
                //at load, if user hasn't scrolled more than 20 or so...
                if (getScrollTop() < 20) {
                    //reset to hide addr bar at onload
                    win.scrollTo(0, scrollTop === 1 ? 0 : 1);
                }
            }, 0);
        });
    }
})(this);

//Simple function to a responsive menu
(function () {
    $("#nav").before('
 &#9776
');

    $("#menu").on('click', function () {
        $("#nav").toggle();
    });

    $(window).resize(function () {
        if (window.innerWidth > 768) {
            $("#nav").removeAttr("style");
        }
    });
})(this);
//apply to any markup with nav like this:
/*

Link

Link

Link

Link

Link

 */

//Add your scripts here
<|endoftext|>


<commit_before>"use strict";

var
Objects = require('./objects');

exports.newPlugin = Objects.factory({

  initialize: function (spec) {
    this.initializer = spec.initialize;
  },

  initPlugin: function (API, configs) {
    return this.initializer.call(null, API, configs);
  }
});
<commit_msg>Fix bug in plugin initializer.<commit_after>"use strict";

var
Objects = require('./objects');

exports.newPlugin = Objects.factory({

  initialize: function (spec) {
    this.initializer = spec.initialize;
  },

  initPlugin: function (API) {
    var
    initializer = this.initializer;
    return function () {
      return initializer.call(null, API);
    };
  }
});
<|endoftext|>


<commit_before>/*
 * component-builder-handlebars
 * https://github.com/kewah/component-builder-handlebars
 *
 * Copyright (c) 2013 Antoine Lehurt
 * Licensed under the MIT license.
 */

'use strict';

/**
 * Module dependencies.
 */
var fs = require('fs');
var path = require('path');
var Handlebars = require('handlebars');

/**
 * Precompile Handlebars templates and partials.
 * @param  {Object} opts  - extname: define the handlebars extension name.
 *                        - partialRegex: Regex to determine if the file is a partial.
 *
 * @return {Function}     Handlebars plugin for builder.js
 */
module.exports = function(opts) {
  opts = opts || {};
  // by default the extension name is .hbs
  var extname = opts.extname || '.hbs';
  // by default the partial file name have to start with _
  var partialRegex = opts.partialRegex || /^_/;

  var isHandlebarsTemplate = function(file) {
    return extname === path.extname(file);
  };

  var removePartialPrefix = function(partial) {
    return partial.replace(partialRegex, '');
  };

  return function(builder) {
    builder.hook('before scripts', function(pkg, complete) {
      var tpl = pkg.conf.templates;
      var componentName = pkg.conf.name;
      var runtimeFilepath, runtime;

      // we include the runtime only for the root.
      if (pkg.root) {
        // add handlebars runtime script.
        // If the file, in the Handlebars module, does not exists
        // we use the runtime file from /lib.
        runtimeFilepath = path.join(__dirname, '../node_modules/handlebars/dist/handlebars.runtime.js');
        if (!fs.existsSync(runtimeFilepath)) {
          runtimeFilepath = path.join(__dirname, '/handlebars.runtime.js');
        }

        runtime = fs.readFileSync(runtimeFilepath);
        builder.addFile('scripts', 'handlebars.runtime.js', runtime + 'window.Handlebars = Handlebars;');

        // auto-invoke the module
        builder.append('require("' + componentName + '/handlebars.runtime");');
      }

      if (!tpl) {
        return complete();
      }

      tpl = tpl.filter(isHandlebarsTemplate);

      // list of partials that we will process after.
      var partials = [];

      // precompile handlebars templates and partials.
      tpl.forEach(function(modulePath) {
        var absolutepath = pkg.path(modulePath);
        var filename = path.basename(absolutepath, extname);

        // precompile handlebars templates.
        var src = fs.readFileSync(absolutepath, 'utf-8');
        var compiled = Handlebars.precompile(src);
        var output = 'Handlebars.template(' + compiled + ')';

        if (partialRegex.test(filename)) {
          // add namespace to the partial.
          modulePath = modulePath.replace(filename + extname, '');
          filename = removePartialPrefix(filename);
          partials.push('Handlebars.registerPartial("' + componentName + '/' + modulePath + filename + '", ' + output + ');');

          return;
        }

        // add the template as a module.
        modulePath = modulePath.replace(extname, '.js');
        pkg.addFile('scripts', modulePath, 'module.exports = ' + output);
      });

      if (partials.length === 0) {
        return complete();
      }

      // add all partials into the same module 'handlebars.partials.js'.
      pkg.addFile('scripts', 'handlebars.partials.js', partials.join('\n'));

      // auto-invoke the module to automatically register partials.
      builder.append('require("' + componentName + '/handlebars.partials");');

      return complete();
    });
  };
};<commit_msg>Fix: change .conf -> .config<commit_after>/*
 * component-builder-handlebars
 * https://github.com/kewah/component-builder-handlebars
 *
 * Copyright (c) 2013 Antoine Lehurt
 * Licensed under the MIT license.
 */

'use strict';

/**
 * Module dependencies.
 */
var fs = require('fs');
var path = require('path');
var Handlebars = require('handlebars');

/**
 * Precompile Handlebars templates and partials.
 * @param  {Object} opts  - extname: define the handlebars extension name.
 *                        - partialRegex: Regex to determine if the file is a partial.
 *
 * @return {Function}     Handlebars plugin for builder.js
 */
module.exports = function(opts) {
  opts = opts || {};
  // by default the extension name is .hbs
  var extname = opts.extname || '.hbs';
  // by default the partial file name have to start with _
  var partialRegex = opts.partialRegex || /^_/;

  var isHandlebarsTemplate = function(file) {
    return extname === path.extname(file);
  };

  var removePartialPrefix = function(partial) {
    return partial.replace(partialRegex, '');
  };

  return function(builder) {
    builder.hook('before scripts', function(pkg, complete) {
      var tpl = pkg.config.templates;
      var componentName = pkg.config.name;
      var runtimeFilepath, runtime;

      // we include the runtime only for the root.
      if (pkg.root) {
        // add handlebars runtime script.
        // If the file, in the Handlebars module, does not exists
        // we use the runtime file from /lib.
        runtimeFilepath = path.join(__dirname, '../node_modules/handlebars/dist/handlebars.runtime.js');
        if (!fs.existsSync(runtimeFilepath)) {
          runtimeFilepath = path.join(__dirname, '/handlebars.runtime.js');
        }

        runtime = fs.readFileSync(runtimeFilepath);
        builder.addFile('scripts', 'handlebars.runtime.js', runtime + 'window.Handlebars = Handlebars;');

        // auto-invoke the module
        builder.append('require("' + componentName + '/handlebars.runtime");');
      }

      if (!tpl) {
        return complete();
      }

      tpl = tpl.filter(isHandlebarsTemplate);

      // list of partials that we will process after.
      var partials = [];

      // precompile handlebars templates and partials.
      tpl.forEach(function(modulePath) {
        var absolutepath = pkg.path(modulePath);
        var filename = path.basename(absolutepath, extname);

        // precompile handlebars templates.
        var src = fs.readFileSync(absolutepath, 'utf-8');
        var compiled = Handlebars.precompile(src);
        var output = 'Handlebars.template(' + compiled + ')';

        if (partialRegex.test(filename)) {
          // add namespace to the partial.
          modulePath = modulePath.replace(filename + extname, '');
          filename = removePartialPrefix(filename);
          partials.push('Handlebars.registerPartial("' + componentName + '/' + modulePath + filename + '", ' + output + ');');

          return;
        }

        // add the template as a module.
        modulePath = modulePath.replace(extname, '.js');
        pkg.addFile('scripts', modulePath, 'module.exports = ' + output);
      });

      if (partials.length === 0) {
        return complete();
      }

      // add all partials into the same module 'handlebars.partials.js'.
      pkg.addFile('scripts', 'handlebars.partials.js', partials.join('\n'));

      // auto-invoke the module to automatically register partials.
      builder.append('require("' + componentName + '/handlebars.partials");');

      return complete();
    });
  };
};<|endoftext|>


<commit_before>const fs = require('fs');
const fse = require('fs-extra');
const path = require('path');
const { spawnSync } = require('child_process');
const tomlParse = require('@iarna/toml/parse-string');

/**
 * poetry install
 */
function pyprojectTomlToRequirements() {
  if (!this.options.usePoetry || !isPoetryProject(this.servicePath)) {
    return;
  }

  this.serverless.cli.log('Generating requirements.txt from pyproject.toml...');

  const res = spawnSync(
    'poetry',
    ['export', '--without-hashes', '-f', 'requirements.txt'],
    {
      cwd: this.servicePath
    }
  );
  if (res.error) {
    if (res.error.code === 'ENOENT') {
      throw new Error(
        `poetry not found! Install it according to the poetry docs.`
      );
    }
    throw new Error(res.error);
  }
  if (res.status !== 0) {
    throw new Error(res.stderr);
  }

  const editableLine = new RegExp(/^-e /gm);
  const sourceRequirements = path.join(this.servicePath, 'requirements.txt');
  const requirementsContents = fse.readFileSync(sourceRequirements, { encoding: 'utf-8' });

  if (requirementsContents.match(editableLine)) {
    this.serverless.cli.log('The generated file contains -e lines, removing them...');
    fse.writeFileSync(sourceRequirements, requirementsContents.replace(editableLine, ''))
  }

  fse.ensureDirSync(path.join(this.servicePath, '.serverless'));
  fse.moveSync(
    sourceRequirements,
    path.join(this.servicePath, '.serverless', 'requirements.txt')
  );
}

/**
 * Check if pyproject.toml file exists and is a poetry project.
 */
function isPoetryProject(servicePath) {
  const pyprojectPath = path.join(servicePath, 'pyproject.toml');

  if (!fse.existsSync(pyprojectPath)) {
    return false;
  }

  const pyprojectToml = fs.readFileSync(pyprojectPath);
  const pyproject = tomlParse(pyprojectToml);

  const buildSystemReqs =
    (pyproject['build-system'] && pyproject['build-system']['requires']) || [];

  for (var i = 0; i < buildSystemReqs.length; i++) {
    if (buildSystemReqs[i].startsWith('poetry')) {
      return true;
    }
  }

  return false;
}

module.exports = { pyprojectTomlToRequirements };
<commit_msg>Run prettier on poetry.js<commit_after>const fs = require('fs');
const fse = require('fs-extra');
const path = require('path');
const { spawnSync } = require('child_process');
const tomlParse = require('@iarna/toml/parse-string');

/**
 * poetry install
 */
function pyprojectTomlToRequirements() {
  if (!this.options.usePoetry || !isPoetryProject(this.servicePath)) {
    return;
  }

  this.serverless.cli.log('Generating requirements.txt from pyproject.toml...');

  const res = spawnSync(
    'poetry',
    ['export', '--without-hashes', '-f', 'requirements.txt'],
    {
      cwd: this.servicePath
    }
  );
  if (res.error) {
    if (res.error.code === 'ENOENT') {
      throw new Error(
        `poetry not found! Install it according to the poetry docs.`
      );
    }
    throw new Error(res.error);
  }
  if (res.status !== 0) {
    throw new Error(res.stderr);
  }

  const editableLine = new RegExp(/^-e /gm);
  const sourceRequirements = path.join(this.servicePath, 'requirements.txt');
  const requirementsContents = fse.readFileSync(sourceRequirements, {
    encoding: 'utf-8'
  });

  if (requirementsContents.match(editableLine)) {
    this.serverless.cli.log(
      'The generated file contains -e lines, removing them...'
    );
    fse.writeFileSync(
      sourceRequirements,
      requirementsContents.replace(editableLine, '')
    );
  }

  fse.ensureDirSync(path.join(this.servicePath, '.serverless'));
  fse.moveSync(
    sourceRequirements,
    path.join(this.servicePath, '.serverless', 'requirements.txt')
  );
}

/**
 * Check if pyproject.toml file exists and is a poetry project.
 */
function isPoetryProject(servicePath) {
  const pyprojectPath = path.join(servicePath, 'pyproject.toml');

  if (!fse.existsSync(pyprojectPath)) {
    return false;
  }

  const pyprojectToml = fs.readFileSync(pyprojectPath);
  const pyproject = tomlParse(pyprojectToml);

  const buildSystemReqs =
    (pyproject['build-system'] && pyproject['build-system']['requires']) || [];

  for (var i = 0; i < buildSystemReqs.length; i++) {
    if (buildSystemReqs[i].startsWith('poetry')) {
      return true;
    }
  }

  return false;
}

module.exports = { pyprojectTomlToRequirements };
<|endoftext|>


<commit_before>const _ = require('lodash/fp')
const Queue = require('queue-promise')
const plugins = require('./plugins')
const notifier = require('./notifier')
const T = require('./time')
const logger = require('./logger')
const cashOutTx = require('./cash-out/cash-out-tx')
const cashInTx = require('./cash-in/cash-in-tx')
const sanctionsUpdater = require('./ofac/update')
const sanctions = require('./ofac/index')
const coinAtmRadar = require('./coinatmradar/coinatmradar')
const configManager = require('./new-config-manager')
const complianceTriggers = require('./compliance-triggers')
const { asyncLocalStorage, defaultStore } = require('./async-storage')
const settingsLoader = require('./new-settings-loader')
const NodeCache = require('node-cache')
const util = require('util')
const db = require('./db')
const state = require('./middlewares/state')
const processBatches = require('./tx-batching-processing')

const INCOMING_TX_INTERVAL = 30 * T.seconds
const LIVE_INCOMING_TX_INTERVAL = 5 * T.seconds
const INCOMING_TX_INTERVAL_FILTER = 1 * T.minute
const LIVE_INCOMING_TX_INTERVAL_FILTER = 10 * T.seconds
const UNNOTIFIED_INTERVAL = 10 * T.seconds
const SWEEP_HD_INTERVAL = T.minute
const TRADE_INTERVAL = 60 * T.seconds
const PONG_INTERVAL = 10 * T.seconds
const LOGS_CLEAR_INTERVAL = 1 * T.day
const SANCTIONS_INITIAL_DOWNLOAD_INTERVAL = 5 * T.minutes
const SANCTIONS_UPDATE_INTERVAL = 1 * T.day
const RADAR_UPDATE_INTERVAL = 5 * T.minutes
const PRUNE_MACHINES_HEARTBEAT = 1 * T.day
const TRANSACTION_BATCH_LIFECYCLE = 20 * T.minutes
const TICKER_RATES_INTERVAL = 59 * T.seconds

const CHECK_NOTIFICATION_INTERVAL = 20 * T.seconds
const PENDING_INTERVAL = 10 * T.seconds
const CACHE_ENTRY_TTL = 3600 // seconds

const FAST_QUEUE_WAIT = 1 * T.seconds
const SLOW_QUEUE_WAIT = 10 * T.seconds

const FAST_QUEUE = new Queue({
  concurrent: 600,
  interval: FAST_QUEUE_WAIT
})

const SLOW_QUEUE = new Queue({
  concurrent: 10,
  interval: SLOW_QUEUE_WAIT
})

// Fix for asyncLocalStorage store being lost due to callback-based queue
FAST_QUEUE.enqueue = util.promisify(FAST_QUEUE.enqueue)
SLOW_QUEUE.enqueue = util.promisify(SLOW_QUEUE.enqueue)

const QUEUE = {
  FAST: FAST_QUEUE,
  SLOW: SLOW_QUEUE
}

const coinFilter = ['ETH']
const schemaCallbacks = new Map()

const cachedVariables = new NodeCache({
  stdTTL: CACHE_ENTRY_TTL,
  checkperiod: CACHE_ENTRY_TTL,
  deleteOnExpire: false,
  useClones: false // pass values by reference instead of cloning
})

cachedVariables.on('expired', (key, val) => {
  if (!val.isReloading) {
    // since val is passed by reference we don't need to do cachedVariables.set()
    val.isReloading = true
    return reload(key)
  }
})

db.connect({ direct: true }).then(sco => {
  sco.client.on('notification', data => {
    const parsedData = JSON.parse(data.payload)
    return reload(parsedData.schema)
  })
  return sco.none('LISTEN $1:name', 'reload')
}).catch(console.error)

function reload (schema) {
  const store = defaultStore()
  store.set('schema', schema)
  // set asyncLocalStorage so settingsLoader loads settings for the right schema
  return asyncLocalStorage.run(store, () => {
    return settingsLoader.loadLatest()
      .then(settings => {
        const pi = plugins(settings)
        cachedVariables.set(schema, { settings, pi, isReloading: false })
        logger.debug(`Settings for schema '${schema}' reloaded in poller`)
        return updateAndLoadSanctions()
      })
  })
}

function pi () { return cachedVariables.get(asyncLocalStorage.getStore().get('schema')).pi }
function settings () { return cachedVariables.get(asyncLocalStorage.getStore().get('schema')).settings }

function initialSanctionsDownload () {
  const structs = sanctions.getStructs()
  const isEmptyStructs = _.isNil(structs) || _.flow(_.values, _.all(_.isEmpty))(structs)

  if (!isEmptyStructs) return Promise.resolve()

  return updateAndLoadSanctions()
}

function updateAndLoadSanctions () {
  const triggers = configManager.getTriggers(settings().config)
  const hasSanctions = complianceTriggers.hasSanctions(triggers)

  if (!hasSanctions) return Promise.resolve()

  logger.info('Updating sanctions database...')
  return sanctionsUpdater.update()
    .then(sanctions.load)
    .then(() => logger.info('Sanctions database updated.'))
}

function updateCoinAtmRadar () {
  return pi().getRawRates()
    .then(rates => coinAtmRadar.update(rates, settings()))
}

function initializeEachSchema (schemas = ['public']) {
  // for each schema set "thread variables" and do polling
  return _.forEach(schema => {
    const store = defaultStore()
    store.set('schema', schema)
    return asyncLocalStorage.run(store, () => {
      return settingsLoader.loadLatest().then(settings => {
        // prevent inadvertedly clearing the array without clearing timeouts
        if (schemaCallbacks.has(schema)) throw new Error(`The schema "${schema}" cannot be initialized twice on poller`)
        const pi = plugins(settings)
        cachedVariables.set(schema, { settings, pi, isReloading: false })
        schemaCallbacks.set(schema, [])
        return doPolling(schema)
      })
    }).catch(console.error)
  }, schemas)
}

function addToQueue (func, interval, schema, queue, ...vars) {
  return schemaCallbacks.get(schema).push(setInterval(() => {
    return queue.enqueue().then(() => {
      // get plugins or settings from the cache every time func is run
      const loadVariables = vars.length > 0 && typeof vars[0] === 'function'
      if (loadVariables) {
        const funcVars = [...vars]
        funcVars[0] = vars[0]()
        return func(...funcVars)
      }
      return func(...vars)
    }).catch(console.error)
  }, interval))
}

function doPolling (schema) {
  pi().executeTrades()
  pi().pong()
  pi().clearOldLogs()
  cashOutTx.monitorLiveIncoming(settings(), false, coinFilter)
  cashOutTx.monitorStaleIncoming(settings(), false, coinFilter)
  if (!_.isEmpty(coinFilter)) {
    cashOutTx.monitorLiveIncoming(settings(), true, coinFilter)
    cashOutTx.monitorStaleIncoming(settings(), true, coinFilter)
  }
  cashOutTx.monitorUnnotified(settings())
  pi().sweepHd()
  notifier.checkNotification(pi())
  updateCoinAtmRadar()

  addToQueue(pi().getRawRates, TICKER_RATES_INTERVAL, schema, QUEUE.FAST)
  addToQueue(pi().executeTrades, TRADE_INTERVAL, schema, QUEUE.FAST)
  addToQueue(cashOutTx.monitorLiveIncoming, LIVE_INCOMING_TX_INTERVAL, schema, QUEUE.FAST, settings, false, coinFilter)
  addToQueue(cashOutTx.monitorStaleIncoming, INCOMING_TX_INTERVAL, schema, QUEUE.FAST, settings, false, coinFilter)
  if (!_.isEmpty(coinFilter)) {
    addToQueue(cashOutTx.monitorLiveIncoming, LIVE_INCOMING_TX_INTERVAL_FILTER, schema, QUEUE.FAST, settings, true, coinFilter)
    addToQueue(cashOutTx.monitorStaleIncoming, INCOMING_TX_INTERVAL_FILTER, schema, QUEUE.FAST, settings, true, coinFilter)
  }
  addToQueue(cashOutTx.monitorUnnotified, UNNOTIFIED_INTERVAL, schema, QUEUE.FAST, settings)
  addToQueue(cashInTx.monitorPending, PENDING_INTERVAL, schema, QUEUE.FAST, settings)
  addToQueue(processBatches, UNNOTIFIED_INTERVAL, schema, QUEUE.FAST, settings, TRANSACTION_BATCH_LIFECYCLE)
  addToQueue(pi().sweepHd, SWEEP_HD_INTERVAL, schema, QUEUE.FAST, settings)
  addToQueue(pi().pong, PONG_INTERVAL, schema, QUEUE.FAST)
  addToQueue(pi().clearOldLogs, LOGS_CLEAR_INTERVAL, schema, QUEUE.SLOW)
  addToQueue(notifier.checkNotification, CHECK_NOTIFICATION_INTERVAL, schema, QUEUE.FAST, pi)
  addToQueue(initialSanctionsDownload, SANCTIONS_INITIAL_DOWNLOAD_INTERVAL, schema, QUEUE.SLOW)
  addToQueue(updateAndLoadSanctions, SANCTIONS_UPDATE_INTERVAL, schema, QUEUE.SLOW)
  addToQueue(updateCoinAtmRadar, RADAR_UPDATE_INTERVAL, schema, QUEUE.SLOW)
  addToQueue(pi().pruneMachinesHeartbeat(), PRUNE_MACHINES_HEARTBEAT, schema, QUEUE.SLOW, settings)
}

function setup (schemasToAdd = [], schemasToRemove = []) {
  // clear callback array for each schema in schemasToRemove and clear cached variables
  _.forEach(schema => {
    const callbacks = schemaCallbacks.get(schema)
    _.forEach(clearInterval, callbacks)
    schemaCallbacks.delete(schema)
    cachedVariables.del(schema)
  }, schemasToRemove)

  return initializeEachSchema(schemasToAdd)
}

const getActiveSchemas = () => Array.from(schemaCallbacks.keys())

module.exports = { setup, reload, getActiveSchemas }
<commit_msg>fix: prune heartbeat only being executed once<commit_after>const _ = require('lodash/fp')
const Queue = require('queue-promise')
const plugins = require('./plugins')
const notifier = require('./notifier')
const T = require('./time')
const logger = require('./logger')
const cashOutTx = require('./cash-out/cash-out-tx')
const cashInTx = require('./cash-in/cash-in-tx')
const sanctionsUpdater = require('./ofac/update')
const sanctions = require('./ofac/index')
const coinAtmRadar = require('./coinatmradar/coinatmradar')
const configManager = require('./new-config-manager')
const complianceTriggers = require('./compliance-triggers')
const { asyncLocalStorage, defaultStore } = require('./async-storage')
const settingsLoader = require('./new-settings-loader')
const NodeCache = require('node-cache')
const util = require('util')
const db = require('./db')
const state = require('./middlewares/state')
const processBatches = require('./tx-batching-processing')

const INCOMING_TX_INTERVAL = 30 * T.seconds
const LIVE_INCOMING_TX_INTERVAL = 5 * T.seconds
const INCOMING_TX_INTERVAL_FILTER = 1 * T.minute
const LIVE_INCOMING_TX_INTERVAL_FILTER = 10 * T.seconds
const UNNOTIFIED_INTERVAL = 10 * T.seconds
const SWEEP_HD_INTERVAL = T.minute
const TRADE_INTERVAL = 60 * T.seconds
const PONG_INTERVAL = 10 * T.seconds
const LOGS_CLEAR_INTERVAL = 1 * T.day
const SANCTIONS_INITIAL_DOWNLOAD_INTERVAL = 5 * T.minutes
const SANCTIONS_UPDATE_INTERVAL = 1 * T.day
const RADAR_UPDATE_INTERVAL = 5 * T.minutes
const PRUNE_MACHINES_HEARTBEAT = 1 * T.day
const TRANSACTION_BATCH_LIFECYCLE = 20 * T.minutes
const TICKER_RATES_INTERVAL = 59 * T.seconds

const CHECK_NOTIFICATION_INTERVAL = 20 * T.seconds
const PENDING_INTERVAL = 10 * T.seconds
const CACHE_ENTRY_TTL = 3600 // seconds

const FAST_QUEUE_WAIT = 1 * T.seconds
const SLOW_QUEUE_WAIT = 10 * T.seconds

const FAST_QUEUE = new Queue({
  concurrent: 600,
  interval: FAST_QUEUE_WAIT
})

const SLOW_QUEUE = new Queue({
  concurrent: 10,
  interval: SLOW_QUEUE_WAIT
})

// Fix for asyncLocalStorage store being lost due to callback-based queue
FAST_QUEUE.enqueue = util.promisify(FAST_QUEUE.enqueue)
SLOW_QUEUE.enqueue = util.promisify(SLOW_QUEUE.enqueue)

const QUEUE = {
  FAST: FAST_QUEUE,
  SLOW: SLOW_QUEUE
}

const coinFilter = ['ETH']
const schemaCallbacks = new Map()

const cachedVariables = new NodeCache({
  stdTTL: CACHE_ENTRY_TTL,
  checkperiod: CACHE_ENTRY_TTL,
  deleteOnExpire: false,
  useClones: false // pass values by reference instead of cloning
})

cachedVariables.on('expired', (key, val) => {
  if (!val.isReloading) {
    // since val is passed by reference we don't need to do cachedVariables.set()
    val.isReloading = true
    return reload(key)
  }
})

db.connect({ direct: true }).then(sco => {
  sco.client.on('notification', data => {
    const parsedData = JSON.parse(data.payload)
    return reload(parsedData.schema)
  })
  return sco.none('LISTEN $1:name', 'reload')
}).catch(console.error)

function reload (schema) {
  const store = defaultStore()
  store.set('schema', schema)
  // set asyncLocalStorage so settingsLoader loads settings for the right schema
  return asyncLocalStorage.run(store, () => {
    return settingsLoader.loadLatest()
      .then(settings => {
        const pi = plugins(settings)
        cachedVariables.set(schema, { settings, pi, isReloading: false })
        logger.debug(`Settings for schema '${schema}' reloaded in poller`)
        return updateAndLoadSanctions()
      })
  })
}

function pi () { return cachedVariables.get(asyncLocalStorage.getStore().get('schema')).pi }
function settings () { return cachedVariables.get(asyncLocalStorage.getStore().get('schema')).settings }

function initialSanctionsDownload () {
  const structs = sanctions.getStructs()
  const isEmptyStructs = _.isNil(structs) || _.flow(_.values, _.all(_.isEmpty))(structs)

  if (!isEmptyStructs) return Promise.resolve()

  return updateAndLoadSanctions()
}

function updateAndLoadSanctions () {
  const triggers = configManager.getTriggers(settings().config)
  const hasSanctions = complianceTriggers.hasSanctions(triggers)

  if (!hasSanctions) return Promise.resolve()

  logger.info('Updating sanctions database...')
  return sanctionsUpdater.update()
    .then(sanctions.load)
    .then(() => logger.info('Sanctions database updated.'))
}

function updateCoinAtmRadar () {
  return pi().getRawRates()
    .then(rates => coinAtmRadar.update(rates, settings()))
}

function initializeEachSchema (schemas = ['public']) {
  // for each schema set "thread variables" and do polling
  return _.forEach(schema => {
    const store = defaultStore()
    store.set('schema', schema)
    return asyncLocalStorage.run(store, () => {
      return settingsLoader.loadLatest().then(settings => {
        // prevent inadvertedly clearing the array without clearing timeouts
        if (schemaCallbacks.has(schema)) throw new Error(`The schema "${schema}" cannot be initialized twice on poller`)
        const pi = plugins(settings)
        cachedVariables.set(schema, { settings, pi, isReloading: false })
        schemaCallbacks.set(schema, [])
        return doPolling(schema)
      })
    }).catch(console.error)
  }, schemas)
}

function addToQueue (func, interval, schema, queue, ...vars) {
  return schemaCallbacks.get(schema).push(setInterval(() => {
    return queue.enqueue().then(() => {
      // get plugins or settings from the cache every time func is run
      const loadVariables = vars.length > 0 && typeof vars[0] === 'function'
      if (loadVariables) {
        const funcVars = [...vars]
        funcVars[0] = vars[0]()
        return func(...funcVars)
      }
      return func(...vars)
    }).catch(console.error)
  }, interval))
}

function doPolling (schema) {
  pi().executeTrades()
  pi().pong()
  pi().clearOldLogs()
  cashOutTx.monitorLiveIncoming(settings(), false, coinFilter)
  cashOutTx.monitorStaleIncoming(settings(), false, coinFilter)
  if (!_.isEmpty(coinFilter)) {
    cashOutTx.monitorLiveIncoming(settings(), true, coinFilter)
    cashOutTx.monitorStaleIncoming(settings(), true, coinFilter)
  }
  cashOutTx.monitorUnnotified(settings())
  pi().sweepHd()
  notifier.checkNotification(pi())
  updateCoinAtmRadar()

  addToQueue(pi().getRawRates, TICKER_RATES_INTERVAL, schema, QUEUE.FAST)
  addToQueue(pi().executeTrades, TRADE_INTERVAL, schema, QUEUE.FAST)
  addToQueue(cashOutTx.monitorLiveIncoming, LIVE_INCOMING_TX_INTERVAL, schema, QUEUE.FAST, settings, false, coinFilter)
  addToQueue(cashOutTx.monitorStaleIncoming, INCOMING_TX_INTERVAL, schema, QUEUE.FAST, settings, false, coinFilter)
  if (!_.isEmpty(coinFilter)) {
    addToQueue(cashOutTx.monitorLiveIncoming, LIVE_INCOMING_TX_INTERVAL_FILTER, schema, QUEUE.FAST, settings, true, coinFilter)
    addToQueue(cashOutTx.monitorStaleIncoming, INCOMING_TX_INTERVAL_FILTER, schema, QUEUE.FAST, settings, true, coinFilter)
  }
  addToQueue(cashOutTx.monitorUnnotified, UNNOTIFIED_INTERVAL, schema, QUEUE.FAST, settings)
  addToQueue(cashInTx.monitorPending, PENDING_INTERVAL, schema, QUEUE.FAST, settings)
  addToQueue(processBatches, UNNOTIFIED_INTERVAL, schema, QUEUE.FAST, settings, TRANSACTION_BATCH_LIFECYCLE)
  addToQueue(pi().sweepHd, SWEEP_HD_INTERVAL, schema, QUEUE.FAST, settings)
  addToQueue(pi().pong, PONG_INTERVAL, schema, QUEUE.FAST)
  addToQueue(pi().clearOldLogs, LOGS_CLEAR_INTERVAL, schema, QUEUE.SLOW)
  addToQueue(notifier.checkNotification, CHECK_NOTIFICATION_INTERVAL, schema, QUEUE.FAST, pi)
  addToQueue(initialSanctionsDownload, SANCTIONS_INITIAL_DOWNLOAD_INTERVAL, schema, QUEUE.SLOW)
  addToQueue(updateAndLoadSanctions, SANCTIONS_UPDATE_INTERVAL, schema, QUEUE.SLOW)
  addToQueue(updateCoinAtmRadar, RADAR_UPDATE_INTERVAL, schema, QUEUE.SLOW)
  addToQueue(pi().pruneMachinesHeartbeat, PRUNE_MACHINES_HEARTBEAT, schema, QUEUE.SLOW, settings)
}

function setup (schemasToAdd = [], schemasToRemove = []) {
  // clear callback array for each schema in schemasToRemove and clear cached variables
  _.forEach(schema => {
    const callbacks = schemaCallbacks.get(schema)
    _.forEach(clearInterval, callbacks)
    schemaCallbacks.delete(schema)
    cachedVariables.del(schema)
  }, schemasToRemove)

  return initializeEachSchema(schemasToAdd)
}

const getActiveSchemas = () => Array.from(schemaCallbacks.keys())

module.exports = { setup, reload, getActiveSchemas }
<|endoftext|>


<commit_before>const util = require('util');

const userMiddleware = require('../middlewares/user');
const { initializeProfilerMiddleware, finishProfilerMiddleware } = require('../middlewares/profiler');
const authorizationMiddleware = require('../middlewares/authorization');
const errorMiddleware = require('../middlewares/error');

function JobController(userDatabaseService, jobService, statsdClient) {
    this.userDatabaseService = userDatabaseService;
    this.jobService = jobService;
    this.statsdClient = statsdClient;
}

module.exports = JobController;

JobController.prototype.route = function (app) {
    const { base_url } = global.settings;
    const jobMiddlewares = composeJobMiddlewares(
        this.userDatabaseService,
        this.jobService,
        this.statsdClient
    );

    app.get(`${base_url}/jobs-wip`, listWorkInProgressJobs(this.jobService), errorMiddleware());
    app.post(`${base_url}/sql/job`, checkBodyPayloadSize(), jobMiddlewares('create', createJob));
    app.get(`${base_url}/sql/job/:job_id`, jobMiddlewares('retrieve', getJob));
    app.delete(`${base_url}/sql/job/:job_id`, jobMiddlewares('cancel', cancelJob));
};

function composeJobMiddlewares (userDatabaseService, jobService, statsdClient) {
    return function jobMiddlewares (action, middleware) {
        const forceToBeAuthenticated = true;

        return [
            initializeProfilerMiddleware('job'),
            userMiddleware(),
            authorizationMiddleware(userDatabaseService, forceToBeAuthenticated),
            middleware(jobService),
            setServedByDBHostHeader(),
            finishProfilerMiddleware(),
            logJobResult(action),
            incrementSuccessMetrics(statsdClient),
            incrementErrorMetrics(statsdClient),
            errorMiddleware()
        ];
    };
}

function cancelJob (jobService) {
    return function cancelJobMiddleware (req, res, next) {
        const { job_id } = req.params;

        jobService.cancel(job_id, (err, job) => {
            if (req.profiler) {
                req.profiler.done('cancelJob');
            }

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

            res.status(200).send(job.serialize());

            next();
        });
    };
}

function getJob (jobService) {
    return function getJobMiddleware (req, res, next) {
        const { job_id } = req.params;

        jobService.get(job_id, (err, job) => {
            if (req.profiler) {
                req.profiler.done('getJob');
            }

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

            res.status(200).send(job.serialize());

            next();
        });
    };
}

function createJob (jobService) {
    return function createJobMiddleware (req, res, next) {
        const params = Object.assign({}, req.query, req.body);

        var data = {
            user: res.locals.user,
            query: params.query,
            host: res.locals.userDbParams.host,
            port: res.locals.userDbParams.port,
            pass: res.locals.userDbParams.pass,
            dbname: res.locals.userDbParams.dbname,
            dbuser: res.locals.userDbParams.user
        };

        jobService.create(data, (err, job) => {
            if (req.profiler) {
                req.profiler.done('createJob');
            }

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

            res.locals.job_id = job.job_id;

            res.status(201).send(job.serialize());

            next();
        });
    };
}

function listWorkInProgressJobs (jobService) {
    return function listWorkInProgressJobsMiddleware (req, res, next) {
        jobService.listWorkInProgressJobs((err, list) => {
            if (err) {
                return next(err);
            }

            res.status(200).send(list);

            next();
        });
    };
}

function checkBodyPayloadSize () {
    return function checkBodyPayloadSizeMiddleware(req, res, next) {
        const payload = JSON.stringify(req.body);

        if (payload.length > MAX_LIMIT_QUERY_SIZE_IN_BYTES) {
            return next(new Error(getMaxSizeErrorMessage(payload)), res);
        }

        next();
    };
}

const ONE_KILOBYTE_IN_BYTES = 1024;
const MAX_LIMIT_QUERY_SIZE_IN_KB = 16;
const MAX_LIMIT_QUERY_SIZE_IN_BYTES = MAX_LIMIT_QUERY_SIZE_IN_KB * ONE_KILOBYTE_IN_BYTES;

function getMaxSizeErrorMessage(sql) {
    return util.format([
            'Your payload is too large: %s bytes. Max size allowed is %s bytes (%skb).',
            'Are you trying to import data?.',
            'Please, check out import api http://docs.cartodb.com/cartodb-platform/import-api/'
        ].join(' '),
        sql.length,
        MAX_LIMIT_QUERY_SIZE_IN_BYTES,
        Math.round(MAX_LIMIT_QUERY_SIZE_IN_BYTES / ONE_KILOBYTE_IN_BYTES)
    );
}

module.exports.MAX_LIMIT_QUERY_SIZE_IN_BYTES = MAX_LIMIT_QUERY_SIZE_IN_BYTES;
module.exports.getMaxSizeErrorMessage = getMaxSizeErrorMessage;

function setServedByDBHostHeader () {
    return function setServedByDBHostHeaderMiddleware (req, res, next) {
        const { userDbParams } = res.locals;

        if (userDbParams.host) {
            res.header('X-Served-By-DB-Host', res.locals.userDbParams.host);
        }

        next();
    };
}

function logJobResult (action) {
    return function logJobResultMiddleware (req, res, next) {
        if (process.env.NODE_ENV !== 'test') {
            console.info(JSON.stringify({
                type: 'sql_api_batch_job',
                username: res.locals.user,
                action: action,
                job_id: req.params.job_id || res.locals.job_id
            }));
        }

        next();
    };
}

const METRICS_PREFIX = 'sqlapi.job';

function incrementSuccessMetrics (statsdClient) {
    return function incrementSuccessMetricsMiddleware (req, res, next) {
        if (statsdClient !== undefined) {
            statsdClient.increment(`${METRICS_PREFIX}.success`);
        }

        next();
    };
}

function incrementErrorMetrics (statsdClient) {
    return function incrementErrorMetricsMiddleware (err, req, res, next) {
        if (statsdClient !== undefined) {
            statsdClient.increment(`${METRICS_PREFIX}.error`);
        }

        next(err);
    };
}
<commit_msg>Improve naming<commit_after>const util = require('util');

const userMiddleware = require('../middlewares/user');
const { initializeProfilerMiddleware, finishProfilerMiddleware } = require('../middlewares/profiler');
const authorizationMiddleware = require('../middlewares/authorization');
const errorMiddleware = require('../middlewares/error');

function JobController(userDatabaseService, jobService, statsdClient) {
    this.userDatabaseService = userDatabaseService;
    this.jobService = jobService;
    this.statsdClient = statsdClient;
}

module.exports = JobController;

JobController.prototype.route = function (app) {
    const { base_url } = global.settings;
    const jobMiddlewares = composeJobMiddlewares(
        this.userDatabaseService,
        this.jobService,
        this.statsdClient
    );

    app.get(`${base_url}/jobs-wip`, listWorkInProgressJobs(this.jobService), errorMiddleware());
    app.post(`${base_url}/sql/job`, checkBodyPayloadSize(), jobMiddlewares('create', createJob));
    app.get(`${base_url}/sql/job/:job_id`, jobMiddlewares('retrieve', getJob));
    app.delete(`${base_url}/sql/job/:job_id`, jobMiddlewares('cancel', cancelJob));
};

function composeJobMiddlewares (userDatabaseService, jobService, statsdClient) {
    return function jobMiddlewares (action, jobMiddleware) {
        const forceToBeAuthenticated = true;

        return [
            initializeProfilerMiddleware('job'),
            userMiddleware(),
            authorizationMiddleware(userDatabaseService, forceToBeAuthenticated),
            jobMiddleware(jobService),
            setServedByDBHostHeader(),
            finishProfilerMiddleware(),
            logJobResult(action),
            incrementSuccessMetrics(statsdClient),
            incrementErrorMetrics(statsdClient),
            errorMiddleware()
        ];
    };
}

function cancelJob (jobService) {
    return function cancelJobMiddleware (req, res, next) {
        const { job_id } = req.params;

        jobService.cancel(job_id, (err, job) => {
            if (req.profiler) {
                req.profiler.done('cancelJob');
            }

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

            res.status(200).send(job.serialize());

            next();
        });
    };
}

function getJob (jobService) {
    return function getJobMiddleware (req, res, next) {
        const { job_id } = req.params;

        jobService.get(job_id, (err, job) => {
            if (req.profiler) {
                req.profiler.done('getJob');
            }

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

            res.status(200).send(job.serialize());

            next();
        });
    };
}

function createJob (jobService) {
    return function createJobMiddleware (req, res, next) {
        const params = Object.assign({}, req.query, req.body);

        var data = {
            user: res.locals.user,
            query: params.query,
            host: res.locals.userDbParams.host,
            port: res.locals.userDbParams.port,
            pass: res.locals.userDbParams.pass,
            dbname: res.locals.userDbParams.dbname,
            dbuser: res.locals.userDbParams.user
        };

        jobService.create(data, (err, job) => {
            if (req.profiler) {
                req.profiler.done('createJob');
            }

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

            res.locals.job_id = job.job_id;

            res.status(201).send(job.serialize());

            next();
        });
    };
}

function listWorkInProgressJobs (jobService) {
    return function listWorkInProgressJobsMiddleware (req, res, next) {
        jobService.listWorkInProgressJobs((err, list) => {
            if (err) {
                return next(err);
            }

            res.status(200).send(list);

            next();
        });
    };
}

function checkBodyPayloadSize () {
    return function checkBodyPayloadSizeMiddleware(req, res, next) {
        const payload = JSON.stringify(req.body);

        if (payload.length > MAX_LIMIT_QUERY_SIZE_IN_BYTES) {
            return next(new Error(getMaxSizeErrorMessage(payload)), res);
        }

        next();
    };
}

const ONE_KILOBYTE_IN_BYTES = 1024;
const MAX_LIMIT_QUERY_SIZE_IN_KB = 16;
const MAX_LIMIT_QUERY_SIZE_IN_BYTES = MAX_LIMIT_QUERY_SIZE_IN_KB * ONE_KILOBYTE_IN_BYTES;

function getMaxSizeErrorMessage(sql) {
    return util.format([
            'Your payload is too large: %s bytes. Max size allowed is %s bytes (%skb).',
            'Are you trying to import data?.',
            'Please, check out import api http://docs.cartodb.com/cartodb-platform/import-api/'
        ].join(' '),
        sql.length,
        MAX_LIMIT_QUERY_SIZE_IN_BYTES,
        Math.round(MAX_LIMIT_QUERY_SIZE_IN_BYTES / ONE_KILOBYTE_IN_BYTES)
    );
}

module.exports.MAX_LIMIT_QUERY_SIZE_IN_BYTES = MAX_LIMIT_QUERY_SIZE_IN_BYTES;
module.exports.getMaxSizeErrorMessage = getMaxSizeErrorMessage;

function setServedByDBHostHeader () {
    return function setServedByDBHostHeaderMiddleware (req, res, next) {
        const { userDbParams } = res.locals;

        if (userDbParams.host) {
            res.header('X-Served-By-DB-Host', res.locals.userDbParams.host);
        }

        next();
    };
}

function logJobResult (action) {
    return function logJobResultMiddleware (req, res, next) {
        if (process.env.NODE_ENV !== 'test') {
            console.info(JSON.stringify({
                type: 'sql_api_batch_job',
                username: res.locals.user,
                action: action,
                job_id: req.params.job_id || res.locals.job_id
            }));
        }

        next();
    };
}

const METRICS_PREFIX = 'sqlapi.job';

function incrementSuccessMetrics (statsdClient) {
    return function incrementSuccessMetricsMiddleware (req, res, next) {
        if (statsdClient !== undefined) {
            statsdClient.increment(`${METRICS_PREFIX}.success`);
        }

        next();
    };
}

function incrementErrorMetrics (statsdClient) {
    return function incrementErrorMetricsMiddleware (err, req, res, next) {
        if (statsdClient !== undefined) {
            statsdClient.increment(`${METRICS_PREFIX}.error`);
        }

        next(err);
    };
}
<|endoftext|>


<commit_before>var exports,console,process$,empty;//IGNORE
function Comparison(x){}//IGNORE
function Entry(a,b){}//IGNORE
function Singleton(x){}//IGNORE
function SequenceBuilder(){}//IGNORE
function String$(f,x){}//IGNORE

var larger = Comparison("larger");
function getLarger() { return larger }
var smaller = Comparison("smaller");
function getSmaller() { return smaller }
var equal = Comparison("equal");
function getEqual() { return equal }

exports.getLarger=getLarger;
exports.getSmaller=getSmaller;
exports.getEqual=getEqual;

//These are operators for handling nulls
function exists(value) {
    return value !== null && value !== undefined;
}
function nonempty(value) {
    return value !== null && value !== undefined && !value.getEmpty();
}

function isOfType(obj, type) {
    if (type && type.t) {
        if (type.t == 'i' || type.t == 'u') {
            return isOfTypes(obj, type);
        }
        if (obj === null) {
            return type.t===Null || type.t===Anything;
        }
        var typeName = type.t.$$.T$name;
        if (obj.getT$all && typeName in obj.getT$all()) {
            if (type.a && obj.$$targs$$) {
                for (var i=0; i<type.a.length; i++) {
                    if (!extendsType(obj.$$targs$$[i], type.a[i])) {
                        return false;
                    }
                }
            }
            return true;
        }
    }
    return false;
}
function isOfTypes(obj, types) {
    if (obj===null) {
        for (var i=0; i < types.l.length; i++) {
            if(types.l[i].t===Null || types.l[i].t===Anything) return true;
        }
        return false;
    }
    var unions = false;
    var inters = true;
    var _ints=false;
    var objTypes = obj.getT$all();
    for (var i = 0; i < types.l.length; i++) {
        var t = types.l[i];
        var partial = isOfType(obj, t);
        if (types.t==='u') {
            unions = partial || unions;
        } else {
            inters = partial && inters;
            _ints=true;
        }
    }
    return _ints ? inters||unions : unions;
}
function extendsType(t1, t2) {
    if (t1.t === 'u' || t1.t === 'i') {
        var unions = false;
        var inters = true;
        var _ints = false;
        for (var i = 0; i < t1.l.length; i++) {
            var partial = extendsType(t1.l[i], t2);
            if (t1.t==='u') {
                unions = partial||unions;
            } else {
                inters = partial&&inters;
                _ints=true;
            }
        }
        return _ints ? inters||unions : unions;
    }
    if (t2.t == 'u' || t2.t == 'i') {
        var unions = false;
        var inters = true;
        var _ints = false;
        for (var i = 0; i < t2.l.length; i++) {
            var partial = extendsType(t1, t2.l[i]);
            if (t2.t==='u') {
                unions = partial||unions;
            } else {
                inters = partial&&inters;
                _ints=true;
            }
        }
        return _ints ? inters||unions : unions;
    }
    for (t in t1.t.$$.T$all) {
        if (t === t2.t.$$.T$name || t === 'ceylon.language::Nothing') {
            return true;
        }
    }
    return false;
}

function className(obj) {
    function _typename(t) {
        if (t.t==='i' || t.t==='u') {
            var _sep = t.t==='i'?'&':'|';
            var ct = '';
            for (var i=0; i < t.l.length; i++) {
                if (i>0) { ct+=_sep; }
                ct += _typename(t.l[i]);
            }
            return String$(ct);
        } else {
            var tn = t.t.$$.T$name;
            if (t.a) {
                tn += '<';
                for (var i = 0; i < t.a.length; i++) {
                    if (i>0) { tn += ','; }
                    tn += _typename(t.a[i]);
                }
                tn += '>';
            }
            return tn;
        }
    }
    if (obj === null) return String$('ceylon.language::Null');
    var tn = obj.getT$name();
    if (obj.$$targs$$) {
        /*tn += '<';
        for (var i=0; i < obj.$$targs$$.length; i++) {
            if (i>0) { tn += ','; }
            tn += _typename(obj.$$targs$$[i]);
        }
        tn += '>';*/
    }
    return String$(tn);
}

function identityHash(obj) {
    return obj.BasicID;
}

function set_type_args(obj, targs) {
    if (obj.$$targs$$ === undefined) {
        obj.$$targs$$=targs;
    } else {
        for (x in targs) {
            obj.$$targs$$[x] = targs[x];
        }
    }
}
function add_type_arg(obj, name, type) {
    if (obj.$$targs$$ === undefined) {
        obj.$$targs$$={};
    }
    obj.$$targs$$[name]=type;
}

exports.set_type_args=set_type_args;
exports.add_type_arg=add_type_arg;
exports.exists=exists;
exports.nonempty=nonempty;
exports.isOfType=isOfType;
exports.className=className;
exports.identityHash=identityHash;
<commit_msg>isOfTypes didn't handle deep unions checking for null<commit_after>var exports,console,process$,empty;//IGNORE
function Comparison(x){}//IGNORE
function Entry(a,b){}//IGNORE
function Singleton(x){}//IGNORE
function SequenceBuilder(){}//IGNORE
function String$(f,x){}//IGNORE

var larger = Comparison("larger");
function getLarger() { return larger }
var smaller = Comparison("smaller");
function getSmaller() { return smaller }
var equal = Comparison("equal");
function getEqual() { return equal }

exports.getLarger=getLarger;
exports.getSmaller=getSmaller;
exports.getEqual=getEqual;

//These are operators for handling nulls
function exists(value) {
    return value !== null && value !== undefined;
}
function nonempty(value) {
    return value !== null && value !== undefined && !value.getEmpty();
}

function isOfType(obj, type) {
    if (type && type.t) {
        if (type.t == 'i' || type.t == 'u') {
            return isOfTypes(obj, type);
        }
        if (obj === null) {
            return type.t===Null || type.t===Anything;
        }
        var typeName = type.t.$$.T$name;
        if (obj.getT$all && typeName in obj.getT$all()) {
            if (type.a && obj.$$targs$$) {
                for (var i=0; i<type.a.length; i++) {
                    if (!extendsType(obj.$$targs$$[i], type.a[i])) {
                        return false;
                    }
                }
            }
            return true;
        }
    }
    return false;
}
function isOfTypes(obj, types) {
    if (obj===null) {
        for (var i=0; i < types.l.length; i++) {
            if(types.l[i].t===Null || types.l[i].t===Anything) return true;
            else if (types.l[i].t==='u') {
                if (isOfTypes(null, types.l[i])) return true;
            }
        }
        return false;
    }
    var unions = false;
    var inters = true;
    var _ints=false;
    var objTypes = obj.getT$all();
    for (var i = 0; i < types.l.length; i++) {
        var t = types.l[i];
        var partial = isOfType(obj, t);
        if (types.t==='u') {
            unions = partial || unions;
        } else {
            inters = partial && inters;
            _ints=true;
        }
    }
    return _ints ? inters||unions : unions;
}
function extendsType(t1, t2) {
    if (t1.t === 'u' || t1.t === 'i') {
        var unions = false;
        var inters = true;
        var _ints = false;
        for (var i = 0; i < t1.l.length; i++) {
            var partial = extendsType(t1.l[i], t2);
            if (t1.t==='u') {
                unions = partial||unions;
            } else {
                inters = partial&&inters;
                _ints=true;
            }
        }
        return _ints ? inters||unions : unions;
    }
    if (t2.t == 'u' || t2.t == 'i') {
        var unions = false;
        var inters = true;
        var _ints = false;
        for (var i = 0; i < t2.l.length; i++) {
            var partial = extendsType(t1, t2.l[i]);
            if (t2.t==='u') {
                unions = partial||unions;
            } else {
                inters = partial&&inters;
                _ints=true;
            }
        }
        return _ints ? inters||unions : unions;
    }
    for (t in t1.t.$$.T$all) {
        if (t === t2.t.$$.T$name || t === 'ceylon.language::Nothing') {
            return true;
        }
    }
    return false;
}

function className(obj) {
    function _typename(t) {
        if (t.t==='i' || t.t==='u') {
            var _sep = t.t==='i'?'&':'|';
            var ct = '';
            for (var i=0; i < t.l.length; i++) {
                if (i>0) { ct+=_sep; }
                ct += _typename(t.l[i]);
            }
            return String$(ct);
        } else {
            var tn = t.t.$$.T$name;
            if (t.a) {
                tn += '<';
                for (var i = 0; i < t.a.length; i++) {
                    if (i>0) { tn += ','; }
                    tn += _typename(t.a[i]);
                }
                tn += '>';
            }
            return tn;
        }
    }
    if (obj === null) return String$('ceylon.language::Null');
    var tn = obj.getT$name();
    if (obj.$$targs$$) {
        /*tn += '<';
        for (var i=0; i < obj.$$targs$$.length; i++) {
            if (i>0) { tn += ','; }
            tn += _typename(obj.$$targs$$[i]);
        }
        tn += '>';*/
    }
    return String$(tn);
}

function identityHash(obj) {
    return obj.BasicID;
}

function set_type_args(obj, targs) {
    if (obj.$$targs$$ === undefined) {
        obj.$$targs$$=targs;
    } else {
        for (x in targs) {
            obj.$$targs$$[x] = targs[x];
        }
    }
}
function add_type_arg(obj, name, type) {
    if (obj.$$targs$$ === undefined) {
        obj.$$targs$$={};
    }
    obj.$$targs$$[name]=type;
}

exports.set_type_args=set_type_args;
exports.add_type_arg=add_type_arg;
exports.exists=exists;
exports.nonempty=nonempty;
exports.isOfType=isOfType;
exports.className=className;
exports.identityHash=identityHash;
<|endoftext|>


<commit_before>require("../javascripts/common")

require("../javascripts/application")
<commit_msg>Fixed js<commit_after>require("../javascripts/common")

//require("../javascripts/application")
<|endoftext|>


<commit_before>module.exports = (function() {
  var crypto = require('crypto');
  var request = require('request');

  var Pusher = function(options) {
    this.options = options;

    // support appKey being provided instead of key for legacy support
    if( this.options.appKey ) {
      this.options.key = this.options.appKey;
      delete this.options.appKey;
    }

    return this;
  };

  /**
   * @private
   * Used for testing so that modules can be overidden.
   */
  Pusher.modules = {
    request: request,
    crypto: crypto
  };

  Pusher.prototype = {
    domain: 'api.pusherapp.com',
    scheme: 'http',
    port: 80
  };

  Pusher.prototype.auth = function(socketId, channel, channelData) {
    var returnHash = {}
    var channelDataStr = ''
    if (channelData) {
      channelData = JSON.stringify(channelData);
      channelDataStr = ':' + channelData;
      returnHash['channel_data'] = channelData;
    }
    var stringToSign = socketId + ':' + channel + channelDataStr;
    returnHash['auth'] = this.options.key + ':' + crypto.createHmac('sha256', this.options.secret).update(stringToSign).digest('hex');
    return(returnHash);
  };

  /**
   * Legacy supporting function for fetching a channel object.
   */
  Pusher.prototype.channel = function( channelName ) {
    return new Channel( channelName, this );
  };

  /**
   * Trigger an event
   *
   * The callback receives (error, request, response). A successful request
   * will receive (!error && response.statusCode == 200), both should be checked.
   *
   * On transport errors, the error object will be populated.
   * Application errors are delivered through the response status code,
   *   e.g. 413 if the event message is > 10kb
   */
  Pusher.prototype.trigger = function(channels, event, message, socketId, callback) {

    if( ( channels instanceof Array ) === false ) {
      // add single channel to array for multi trigger compatibility
      channels = [ channels ];
    }

    var eventData = {
      "name": event,
      "data": ( typeof message === 'object' ? JSON.stringify( message ) : message ),
      "channels": channels
    };

    if( socketId ) {
      eventData.socket_id = socketId;
    }

    return this.post( { path: '/events', body: eventData }, callback );
  };

  /**
   * Make a post request to Pusher. Authentication is handled for you.
   *
   * The callback receives (error, request, response). A successful request
   * will receive (!error && response.statusCode == 200), both should be checked.
   *
   * @param {{
   *  path: String, // the path for the request
   *  body: String  // the body of the request
   * }} options
   * @param {Function} callback called when the post has completed
   */
  Pusher.prototype.post = function( options, callback ) {
    var path = '/apps/' + this.options.appId + options.path;
    var requestBody = JSON.stringify( options.body );
    var queryString = this.createSignedQueryString( { method: 'POST', path: path, body: requestBody } );

    var url = this.scheme + '://' + this.domain + ( this.port === 80? '' : ':' + this.port ) + path;
    url += '?' + queryString

    Pusher.modules.request.post({
      url: url,
      headers: {
        'content-type': 'application/json'
      },
      body: requestBody
    }, function( err, res, resBody ) {
      // although using request module the callback signature
      // needs to be maintained
      if( typeof callback === 'function' ) {
        callback( err, this.req, res );
      }
    });

    return this;
  };

  /**
   * Make a get request to Pusher. Authentication is handled for you.
   *
   * @param {{
   *  path: String, // the path for the request
   * }} options
   */
  Pusher.prototype.get = function( options, callback ) {
    var path = '/apps/' + this.options.appId + options.path;
    var queryString = this.createSignedQueryString( { method: 'GET', path: path, params: options.params } );

    var url = this.scheme + '://' + this.domain + ( this.port === 80? '' : ':' + this.port ) + path;
    url += '?' + queryString

    Pusher.modules.request.get({
      url: url,
    }, function( err, res, resBody ) {
      if( typeof callback === 'function' ) {
        callback( err, this.req, res );
      }
    });

    return this;
  };

  /**
   * Create a query string which has been signed and can be used when making a request to Pusher.
   *
   * @param {{
   *  method: String, // GET or POST
   *  body: String,   // body, required if making a POST
   *  params: Object  // key value pairs for parameters
   * }} options
   */
  Pusher.prototype.createSignedQueryString = function( options ) {

    var timestamp = parseInt(new Date().getTime() / 1000);

    var params = {};
    params[ 'auth_key' ] = this.options.key;
    params[ 'auth_timestamp' ] = timestamp;
    params[ 'auth_version' ] = '1.0';

    if( options.body ) {
      var hash = Pusher.modules.crypto.createHash('md5').update(options.body, 'utf8').digest('hex');
      params[ 'body_md5' ] = hash;
    }

    if( options.params ) {
      for( var name in options.params ) {
        if( params[ name ] !== undefined ) {
          throw Error( name + ' is a required parameter and cannot be overidden' );
        }
        params[ name ] = options.params[ name ];
      }
    }

    var sortedKeyVal = toOrderedArray( params );
    var queryString = sortedKeyVal.join( '&' );

    var signData = [ options.method, options.path, queryString ].join('\n');
    var signature = Pusher.modules.crypto.createHmac('sha256', this.options.secret).update(signData).digest('hex');

    queryString += '&auth_signature=' + signature;

    return queryString;
  };

  /**
   * Channel object used for legacy support. Should not be extended.
   */
  function Channel( channelName, pusher ) {
    this._channelName = channelName;
    this._pusher = pusher;
  }

  /**
   * Trigger an event on a channel.
   */
  Channel.prototype.trigger = function( event, message, callback ) {
    var socketId = null;
    this._pusher.trigger( this._channelName, event, message, socketId, callback );
  };

  /* Utility */
  function toOrderedArray( map ) {
    var items = [];
    for( var name in map ) {
      items.push( name + '=' + map[ name ] );
    }
    items.slice(0).sort(function(a, b) {
      return a - b;
    });
    return items;
  }

  return Pusher;
})();<commit_msg>Remove Pusher.modules after changing mocks<commit_after>module.exports = (function() {
  var crypto = require('crypto');
  var request = require('request');

  var Pusher = function(options) {
    this.options = options;

    // support appKey being provided instead of key for legacy support
    if( this.options.appKey ) {
      this.options.key = this.options.appKey;
      delete this.options.appKey;
    }

    return this;
  };

  Pusher.prototype = {
    domain: 'api.pusherapp.com',
    scheme: 'http',
    port: 80
  };

  Pusher.prototype.auth = function(socketId, channel, channelData) {
    var returnHash = {}
    var channelDataStr = ''
    if (channelData) {
      channelData = JSON.stringify(channelData);
      channelDataStr = ':' + channelData;
      returnHash['channel_data'] = channelData;
    }
    var stringToSign = socketId + ':' + channel + channelDataStr;
    returnHash['auth'] = this.options.key + ':' + crypto.createHmac('sha256', this.options.secret).update(stringToSign).digest('hex');
    return(returnHash);
  };

  /**
   * Legacy supporting function for fetching a channel object.
   */
  Pusher.prototype.channel = function( channelName ) {
    return new Channel( channelName, this );
  };

  /**
   * Trigger an event
   *
   * The callback receives (error, request, response). A successful request
   * will receive (!error && response.statusCode == 200), both should be checked.
   *
   * On transport errors, the error object will be populated.
   * Application errors are delivered through the response status code,
   *   e.g. 413 if the event message is > 10kb
   */
  Pusher.prototype.trigger = function(channels, event, message, socketId, callback) {

    if( ( channels instanceof Array ) === false ) {
      // add single channel to array for multi trigger compatibility
      channels = [ channels ];
    }

    var eventData = {
      "name": event,
      "data": ( typeof message === 'object' ? JSON.stringify( message ) : message ),
      "channels": channels
    };

    if( socketId ) {
      eventData.socket_id = socketId;
    }

    return this.post( { path: '/events', body: eventData }, callback );
  };

  /**
   * Make a post request to Pusher. Authentication is handled for you.
   *
   * The callback receives (error, request, response). A successful request
   * will receive (!error && response.statusCode == 200), both should be checked.
   *
   * @param {{
   *  path: String, // the path for the request
   *  body: String  // the body of the request
   * }} options
   * @param {Function} callback called when the post has completed
   */
  Pusher.prototype.post = function( options, callback ) {
    var path = '/apps/' + this.options.appId + options.path;
    var requestBody = JSON.stringify( options.body );
    var queryString = this.createSignedQueryString( { method: 'POST', path: path, body: requestBody } );

    var url = this.scheme + '://' + this.domain + ( this.port === 80? '' : ':' + this.port ) + path;
    url += '?' + queryString

    request.post({
      url: url,
      headers: {
        'content-type': 'application/json'
      },
      body: requestBody
    }, function( err, res, resBody ) {
      // although using request module the callback signature
      // needs to be maintained
      if( typeof callback === 'function' ) {
        callback( err, this.req, res );
      }
    });

    return this;
  };

  /**
   * Make a get request to Pusher. Authentication is handled for you.
   *
   * @param {{
   *  path: String, // the path for the request
   * }} options
   */
  Pusher.prototype.get = function( options, callback ) {
    var path = '/apps/' + this.options.appId + options.path;
    var queryString = this.createSignedQueryString( { method: 'GET', path: path, params: options.params } );

    var url = this.scheme + '://' + this.domain + ( this.port === 80? '' : ':' + this.port ) + path;
    url += '?' + queryString

    request.get({
      url: url,
    }, function( err, res, resBody ) {
      if( typeof callback === 'function' ) {
        callback( err, this.req, res );
      }
    });

    return this;
  };

  /**
   * Create a query string which has been signed and can be used when making a request to Pusher.
   *
   * @param {{
   *  method: String, // GET or POST
   *  body: String,   // body, required if making a POST
   *  params: Object  // key value pairs for parameters
   * }} options
   */
  Pusher.prototype.createSignedQueryString = function( options ) {

    var timestamp = parseInt(new Date().getTime() / 1000);

    var params = {};
    params[ 'auth_key' ] = this.options.key;
    params[ 'auth_timestamp' ] = timestamp;
    params[ 'auth_version' ] = '1.0';

    if( options.body ) {
      var hash = crypto.createHash('md5').update(options.body, 'utf8').digest('hex');
      params[ 'body_md5' ] = hash;
    }

    if( options.params ) {
      for( var name in options.params ) {
        if( params[ name ] !== undefined ) {
          throw Error( name + ' is a required parameter and cannot be overidden' );
        }
        params[ name ] = options.params[ name ];
      }
    }

    var sortedKeyVal = toOrderedArray( params );
    var queryString = sortedKeyVal.join( '&' );

    var signData = [ options.method, options.path, queryString ].join('\n');
    var signature = crypto.createHmac('sha256', this.options.secret).update(signData).digest('hex');

    queryString += '&auth_signature=' + signature;

    return queryString;
  };

  /**
   * Channel object used for legacy support. Should not be extended.
   */
  function Channel( channelName, pusher ) {
    this._channelName = channelName;
    this._pusher = pusher;
  }

  /**
   * Trigger an event on a channel.
   */
  Channel.prototype.trigger = function( event, message, callback ) {
    var socketId = null;
    this._pusher.trigger( this._channelName, event, message, socketId, callback );
  };

  /* Utility */
  function toOrderedArray( map ) {
    var items = [];
    for( var name in map ) {
      items.push( name + '=' + map[ name ] );
    }
    items.slice(0).sort(function(a, b) {
      return a - b;
    });
    return items;
  }

  return Pusher;
})();<|endoftext|>


<commit_before>"use strict";
const _NTS = ['A','C','G','T'];
const _MAX = Math.pow(2,32);

class RandomSeeded {
  constructor (seed) {
    if (!seed) { seed = Math.floor(_MAX*Math.random()); }
    this._seed = seed+101;
  }
  random () {
    // adapted from stackoverflow.com/questions/521295/javascript-random-seeds answer
    let x = Math.sin(this._seed++)*1000000;
    return x - Math.floor(x);
  }
  choice (arr) {
    return arr[Math.floor(arr.length*this.random())]
  }
}
exports.RandomSeeded = RandomSeeded;
<commit_msg>adding a UUID4 to our seeded random<commit_after>"use strict";
const _NTS = ['A','C','G','T'];
const _MAX = Math.pow(2,32);

class RandomSeeded {
  constructor (options) {
    if (! options) options = {};
    if (options.seed) { this._seed = options.seed+101; }
  }
  random () {
    // IMPORTANT All methods of RandomSeeded must use this as the generator.
    if (! this._seed) return Math.random();
    // adapted from stackoverflow.com/questions/521295/javascript-random-seeds answer
    let x = Math.sin(this._seed++)*1000000;
    return x - Math.floor(x);
  }
  choice (arr) {
    return arr[Math.floor(arr.length*this.random())];
  }
  randInt(min,max) {
    return Math.floor(this.random()*(max-min)+min);
  }
  uuid4 () {
    return new uuid4({random:this});
  }
}

class uuid4 {
  // Without options it should act as a true uuid4
  constructor(options) {
    if (! options) options = {};
    if (! options.random) this._random = new RandomSeeded();
    else this._random = options.random;
    // Go ahead and set it up.  when we make one we make one.
    this._data = Buffer(16);
    for (let i = 0; i < 16; i++) { // fill out the byte array
      this._data.writeUInt8(this._random.randInt(0,256),i);
    }
    this._data.writeUInt8((0x0F & this._data.readUInt8(6)) | 0x40,6); // this is certain
    let c = this._random.choice([8,9,10,11]) <<4;
    this._data.writeUInt8((0x0F & this._data.readUInt8(8)) | c,8);
  }
  toString () {
    var ostr = '';
    ostr += this._data.slice(0,4).toString('hex')+'-';
    ostr += this._data.slice(4,6).toString('hex')+'-';
    ostr += this._data.slice(6,8).toString('hex')+'-';
    ostr += this._data.slice(8,10).toString('hex')+'-';
    ostr += this._data.slice(10,16).toString('hex');
    return ostr;
  }
  get bytes () {
    return this._data;
  }
}

exports.RandomSeeded = RandomSeeded;
exports.uuid4 = uuid4;
<|endoftext|>


<commit_before>/*
 *  random.js
 *
 *  David Janes
 *  IOTDB.org
 *  2016-02-03
 *
 *  Copyright [2013-2016] [David P. Janes]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

"use strict";

var crypto = require('crypto');

/**
 *  Generate a random ID
 */
var generate_id = function (length) {
    length = Math.min(length || 128, 128);

    var hasher = crypto.createHash("sha512");
    hasher.update("" + Math.random());

    return hasher.digest("hex").substring(0, length);
};

var random_integer = function (n) {
    return Math.floor(Math.random() * n);
};

var choose = function (vs) {
    return vs[random_integer(vs.length)];
};

var short = function (vs) {
    var hasher = crypto.createHash("sha512");
    hasher.update("" + Math.random());

    var v = hasher.digest("base64").substring(0, 8);
    v = v.replace(/\//g, '_');
    v = v.replace(/[+]/g, '-');

    return v;
};

exports.random = {
    id: generate_id,
    integer: random_integer,
    choose: choose,
    short: short,
};
<commit_msg>make funny random names<commit_after>/*
 *  random.js
 *
 *  David Janes
 *  IOTDB.org
 *  2016-02-03
 *
 *  Copyright [2013-2016] [David P. Janes]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

"use strict";

const crypto = require('crypto');

const _adjectives = ['adorable', 'beautiful', 'clean', 'drab', 'elegant', 'fancy', 'glamorous', 'handsome', 'long', 'magnificent', 'old-fashioned', 'plain', 'quaint', 'sparkling', 'ugliest', 'unsightly', 'angry', 'bewildered', 'clumsy', 'defeated', 'embarrassed', 'fierce', 'grumpy', 'helpless', 'itchy', 'jealous', 'lazy', 'mysterious', 'nervous', 'obnoxious', 'panicky', 'repulsive', 'scary', 'thoughtless', 'uptight', 'worried'];
const _nouns = ['women', 'men', 'children', 'teeth', 'feet', 'people', 'leaves', 'mice', 'geese', 'halves', 'knives', 'wives', 'lives', 'elves', 'loaves', 'potatoes', 'tomatoes', 'cacti', 'foci', 'fungi', 'nuclei', 'syllabuses', 'analyses', 'diagnoses', 'oases', 'theses', 'crises', 'phenomena', 'criteria', 'data'];

/**
 *  Generate a random ID
 */
const generate_id = function (length) {
    length = Math.min(length || 128, 128);

    const hasher = crypto.createHash("sha512");
    hasher.update("" + Math.random());

    return hasher.digest("hex").substring(0, length);
};

const random_integer = function (n) {
    return Math.floor(Math.random() * n);
};

const choose = function (vs) {
    return vs[random_integer(vs.length)];
};

const short = function (vs) {
    var hasher = crypto.createHash("sha512");
    hasher.update("" + Math.random());

    var v = hasher.digest("base64").substring(0, 8);
    v = v.replace(/\//g, '_');
    v = v.replace(/[+]/g, '-');

    return v;
};

exports.random = {
    id: generate_id,
    integer: random_integer,
    choose: choose,
    short: short,
    name: () => `${choose(_adjectives)}-${choose(_adjectives)}-${choose(_nouns)}`,
};
<|endoftext|>