<commit_before>import EventEmitter from 'events';
import {Map} from 'immutable';
import {isArray} from 'lodash/lang';
import {pull, unique} from 'lodash/array';
import {contains} from 'lodash/collection';
import {callOnceAfterTick} from '../utils/call-once-after-tick';
import {
  addNode, addEdge, defineEntryNode, findNodesDisconnectedFromEntryNodes, pruneNodeAndUniqueDependencies
} from './node';

/*
Events
------

started <nodes>
traced => <node name>
error => err, <node name>
complete <nodes>
pruned => <nodes removed>, <nodes impacted>

*/

export function createGraph({nodes=Map(), getDependencies}={}) {
  const events = new EventEmitter;
  const pendingJobs = [];
  let previousState = nodes;
  let errors = [];
  let hasSignalledStart = false;

  // Enable multiple call sites to enqueue a 'complete' check that
  // will occur asynchronously. Our events are emitted synchronously,
  // so executing this check asynchronously enables code to respond to
  // state changes by enqueueing more jobs before the 'complete' signal
  // is emitted
  const signalIfCompleted = callOnceAfterTick(
    function signalIfCompleted() {
      const hasPendingJobs = pendingJobs.some(job => job.isActive);
      if (hasPendingJobs) {
        return;
      }

      const signal = {
        state: nodes,
        previousState: previousState,
        errors
      };

      errors = [];
      previousState = nodes;
      hasSignalledStart = false;

      events.emit('complete', signal);
    }
  );

  function traceNode(name) {
    const job = {
      node: name,
      isValid: true
    };

    // Invalidate any currently pending jobs for the same node
    pendingJobs.forEach(job => {
      if (job.node === name) {
        job.isValid = false;
      }
    });

    // Ensure the job can be tracked elsewhere
    pendingJobs.push(job);

    // Force an asynchronous start to the tracing so that other parts of a
    // codebase can synchronously trigger the job to be invalidated. This
    // helps to avoid any unnecessary work that may no longer be relevant
    process.nextTick(startTracingNode);

    if (!hasSignalledStart) {
      hasSignalledStart = true;
      events.emit('started', {state: nodes, node: name});
    }

    function startTracingNode() {
      if (!job.isValid) {
        pull(pendingJobs, job);
        return;
      }

      getDependencies(name, (err, dependencies) => {
        // Indicate that this job is no longer blocking the `complete` stage
        pull(pendingJobs, job);

        // If this job has been invalidated, we can ignore anything that may
        // have resulted from it
        if (!job.isValid) {
          return;
        }

        if (err) {
          const signal = {
            error: err,
            node: name,
            state: nodes
          };
          errors.push(signal);
          events.emit('error', signal);
          return signalIfCompleted();
        }

        // Sanity check
        if (!isArray(dependencies)) {
          throw new Error(`Dependencies should be specified in an array. Received ${dependencies}`);
        }

        const previousState = nodes;

        if (!isNodeDefined(nodes, name)) {
          nodes = addNode(nodes, name);
        }

        // If there are any dependencies encountered that we don't already
        // know about, we start tracing them
        dependencies.forEach(depName => {
          if (
            !isNodeDefined(nodes, depName) &&
            !isNodePending(pendingJobs, depName)
          ) {
            traceNode(depName);
          }

          if (!isNodeDefined(nodes, depName)) {
            nodes = addNode(nodes, depName);
          }

          nodes = addEdge(nodes, name, depName);
        });

        // Enable progress updates
        events.emit('traced', {
          node: name,
          state: nodes,
          previousState
        });

        signalIfCompleted();
      });
    }
  }

  return {
    pendingJobs,
    events,
    getNodes() {
      return nodes;
    },
    traceNode,
    setNodeAsEntry(name) {
      // Dependency graphs emerge from one or more entry nodes. The ability to
      // distinguish an entry node from a normal dependency node allows us to
      // aggressively prune a node and all of its dependencies.
      //
      // As a basic example of why the concept is important, if `a -> b -> c`
      // and we want to prune `b`, we know that we can safely prune `c` as well.
      //
      // But if `a -> b -> c -> a` and we want to prune `b`, then we need to know
      // that `a` is an entry node, so that we don't traverse the cyclic graph
      // and prune every node.
      //
      // This concept becomes increasingly important once we start dealing with
      // more complicated cyclic graphs, as pruning can result in disconnected
      // sub-graphs. For example, if we have `a -> b -> c -> d -> b` and we want
      // to prune `a`, we can't safely prune `b -> c -> d -> b` as well, as `b`
      // has a dependent `d`. However, if we don't prune them, then they are
      // left disconnected from the other nodes.
      //
      // Our solution to the problem is to prune all dependencies which are no
      // longer needed, then walk the graph from the entries and look for
      // sub-graphs which we can't reach. Once we've identified these, we know
      // we can safely prune them.
      //
      // In summary, always denote the entry nodes before pruning

      nodes = defineEntryNode(nodes, name);
    },
    pruneFromNode(name) {
      const isDefined = isNodeDefined(nodes, name);
      const isPending = isNodePending(pendingJobs, name);

      // If we don't know about the node and there are no pending jobs,
      // then there's nothing to do
      if (!isDefined && !isPending) {
        return;
      }

      // If the node is still pending, we just invalidate the associated
      // job so that it becomes a no-op
      if (isPending && !isDefined) {
        invalidatePendingJobsForNode(pendingJobs, name);
        return signalIfCompleted();
      }

      // We prune the node from the graph, then walk through its dependencies
      // and try to prune any that aren't depended on by other nodes
      let {
        nodes: updatedNodes,
        pruned
      } = pruneNodeAndUniqueDependencies(nodes, name);

      // There are edge-cases where particular circular graphs may not have
      // been pruned completely at this point, so we may still be persisting
      // references to nodes which are disconnected to the entry nodes.
      //
      // An easy example of a situation that would cause this is a tournament.
      // https://en.wikipedia.org/wiki/Tournament_(graph_theory)
      //
      // To get around this problem, we need to walk the graph from the entry
      // nodes, find any that are unreachable, and then prune them directly
      const disconnectedNodes = findNodesDisconnectedFromEntryNodes(updatedNodes);
      disconnectedNodes.forEach(name => {
        if (isNodeDefined(updatedNodes, name)) {
          const data = pruneNodeAndUniqueDependencies(updatedNodes, name);
          updatedNodes = data.nodes;
          pruned.push.apply(pruned, data.pruned);
        }
      });

      // If a node's associated data is invalid and we're pruning it, it is
      // more than likely that any pending jobs are equally invalid
      pruned.forEach(name => {
        invalidatePendingJobsForNode(pendingJobs, name)
      });

      const previousState = nodes;
      nodes = updatedNodes;

      // If a node has been invalidated, it's possible that a dependent may
      // also need to be invalidated if its state depends the dependencies.
      // So, we also indicate the nodes that are likely to impacted by the
      // pruning
      let nodesImpacted = [];
      pruned.forEach(name => {
        const prunedNode = previousState.get(name);
        prunedNode.dependents.forEach(dependentName => {
          if (nodes.has(dependentName)) {
            nodesImpacted.push(dependentName);
          }
        });
      });
      // The iteration over `pruned` can produce duplicate node names
      nodesImpacted = unique(nodesImpacted);

      const signal = {
        state: nodes,
        previousState,
        pruned,
        nodesImpacted
      };

      events.emit('pruned', signal);

      signalIfCompleted();
    },
    hasNodeCompleted(name) {
      return isNodeDefined(nodes, name);
    }
  };
}

export function isNodeDefined(nodes, name) {
  return nodes.has(name);
}

export function isNodePending(pendingJobs, name) {
  return pendingJobs.some(job => {
    return job.isValid && job.node === name;
  });
}

function invalidatePendingJobsForNode(pendingJobs, name) {
  pendingJobs
    .filter(job => job.node === name)
    .forEach(job => job.isValid = false);
}<commit_msg>Cleanup<commit_after>import EventEmitter from 'events';
import {Map} from 'immutable';
import {isArray} from 'lodash/lang';
import {pull, unique} from 'lodash/array';
import {contains} from 'lodash/collection';
import {callOnceAfterTick} from '../utils/call-once-after-tick';
import {
  addNode, addEdge, defineEntryNode, findNodesDisconnectedFromEntryNodes, pruneNodeAndUniqueDependencies
} from './node';

export function createGraph({nodes=Map(), getDependencies}={}) {
  const events = new EventEmitter;
  const pendingJobs = [];
  let previousState = nodes;
  let errors = [];
  let hasSignalledStart = false;

  // Enable multiple call sites to enqueue a 'complete' check that
  // will occur asynchronously. Our events are emitted synchronously,
  // so executing this check asynchronously enables code to respond to
  // state changes by enqueueing more jobs before the 'complete' signal
  // is emitted
  const signalIfCompleted = callOnceAfterTick(
    function signalIfCompleted() {
      const hasPendingJobs = pendingJobs.some(job => job.isActive);
      if (hasPendingJobs) {
        return;
      }

      const signal = {
        state: nodes,
        previousState: previousState,
        errors
      };

      errors = [];
      previousState = nodes;
      hasSignalledStart = false;

      events.emit('complete', signal);
    }
  );

  function traceNode(name) {
    const job = {
      node: name,
      isValid: true
    };

    // Invalidate any currently pending jobs for the same node
    pendingJobs.forEach(job => {
      if (job.node === name) {
        job.isValid = false;
      }
    });

    // Ensure the job can be tracked elsewhere
    pendingJobs.push(job);

    // Force an asynchronous start to the tracing so that other parts of a
    // codebase can synchronously trigger the job to be invalidated. This
    // helps to avoid any unnecessary work that may no longer be relevant
    process.nextTick(startTracingNode);

    if (!hasSignalledStart) {
      hasSignalledStart = true;
      events.emit('started', {state: nodes, node: name});
    }

    function startTracingNode() {
      if (!job.isValid) {
        pull(pendingJobs, job);
        return;
      }

      getDependencies(name, (err, dependencies) => {
        // Indicate that this job is no longer blocking the `complete` stage
        pull(pendingJobs, job);

        // If this job has been invalidated, we can ignore anything that may
        // have resulted from it
        if (!job.isValid) {
          return;
        }

        if (err) {
          const signal = {
            error: err,
            node: name,
            state: nodes
          };
          errors.push(signal);
          events.emit('error', signal);
          return signalIfCompleted();
        }

        // Sanity check
        if (!isArray(dependencies)) {
          throw new Error(`Dependencies should be specified in an array. Received ${dependencies}`);
        }

        const previousState = nodes;

        if (!isNodeDefined(nodes, name)) {
          nodes = addNode(nodes, name);
        }

        // If there are any dependencies encountered that we don't already
        // know about, we start tracing them
        dependencies.forEach(depName => {
          if (
            !isNodeDefined(nodes, depName) &&
            !isNodePending(pendingJobs, depName)
          ) {
            traceNode(depName);
          }

          if (!isNodeDefined(nodes, depName)) {
            nodes = addNode(nodes, depName);
          }

          nodes = addEdge(nodes, name, depName);
        });

        // Enable progress updates
        events.emit('traced', {
          node: name,
          state: nodes,
          previousState
        });

        signalIfCompleted();
      });
    }
  }

  return {
    pendingJobs,
    events,
    getNodes() {
      return nodes;
    },
    traceNode,
    setNodeAsEntry(name) {
      // Dependency graphs emerge from one or more entry nodes. The ability to
      // distinguish an entry node from a normal dependency node allows us to
      // aggressively prune a node and all of its dependencies.
      //
      // As a basic example of why the concept is important, if `a -> b -> c`
      // and we want to prune `b`, we know that we can safely prune `c` as well.
      //
      // But if `a -> b -> c -> a` and we want to prune `b`, then we need to know
      // that `a` is an entry node, so that we don't traverse the cyclic graph
      // and prune every node.
      //
      // This concept becomes increasingly important once we start dealing with
      // more complicated cyclic graphs, as pruning can result in disconnected
      // sub-graphs. For example, if we have `a -> b -> c -> d -> b` and we want
      // to prune `a`, we can't safely prune `b -> c -> d -> b` as well, as `b`
      // has a dependent `d`. However, if we don't prune them, then they are
      // left disconnected from the other nodes.
      //
      // Our solution to the problem is to prune all dependencies which are no
      // longer needed, then walk the graph from the entries and look for
      // sub-graphs which we can't reach. Once we've identified these, we know
      // we can safely prune them.
      //
      // In summary, always denote the entry nodes before pruning

      nodes = defineEntryNode(nodes, name);
    },
    pruneFromNode(name) {
      const isDefined = isNodeDefined(nodes, name);
      const isPending = isNodePending(pendingJobs, name);

      // If we don't know about the node and there are no pending jobs,
      // then there's nothing to do
      if (!isDefined && !isPending) {
        return;
      }

      // If the node is still pending, we just invalidate the associated
      // job so that it becomes a no-op
      if (isPending && !isDefined) {
        invalidatePendingJobsForNode(pendingJobs, name);
        return signalIfCompleted();
      }

      // We prune the node from the graph, then walk through its dependencies
      // and try to prune any that aren't depended on by other nodes
      let {
        nodes: updatedNodes,
        pruned
      } = pruneNodeAndUniqueDependencies(nodes, name);

      // There are edge-cases where particular circular graphs may not have
      // been pruned completely at this point, so we may still be persisting
      // references to nodes which are disconnected to the entry nodes.
      //
      // An easy example of a situation that would cause this is a tournament.
      // https://en.wikipedia.org/wiki/Tournament_(graph_theory)
      //
      // To get around this problem, we need to walk the graph from the entry
      // nodes, find any that are unreachable, and then prune them directly
      const disconnectedNodes = findNodesDisconnectedFromEntryNodes(updatedNodes);
      disconnectedNodes.forEach(name => {
        if (isNodeDefined(updatedNodes, name)) {
          const data = pruneNodeAndUniqueDependencies(updatedNodes, name);
          updatedNodes = data.nodes;
          pruned.push.apply(pruned, data.pruned);
        }
      });

      // If a node's associated data is invalid and we're pruning it, it is
      // more than likely that any pending jobs are equally invalid
      pruned.forEach(name => {
        invalidatePendingJobsForNode(pendingJobs, name)
      });

      const previousState = nodes;
      nodes = updatedNodes;

      // If a node has been invalidated, it's possible that a dependent may
      // also need to be invalidated if its state depends the dependencies.
      // So, we also indicate the nodes that are likely to impacted by the
      // pruning
      let nodesImpacted = [];
      pruned.forEach(name => {
        const prunedNode = previousState.get(name);
        prunedNode.dependents.forEach(dependentName => {
          if (nodes.has(dependentName)) {
            nodesImpacted.push(dependentName);
          }
        });
      });
      // The iteration over `pruned` can produce duplicate node names
      nodesImpacted = unique(nodesImpacted);

      const signal = {
        state: nodes,
        previousState,
        pruned,
        nodesImpacted
      };

      events.emit('pruned', signal);

      signalIfCompleted();
    },
    hasNodeCompleted(name) {
      return isNodeDefined(nodes, name);
    }
  };
}

export function isNodeDefined(nodes, name) {
  return nodes.has(name);
}

export function isNodePending(pendingJobs, name) {
  return pendingJobs.some(job => {
    return job.isValid && job.node === name;
  });
}

function invalidatePendingJobsForNode(pendingJobs, name) {
  pendingJobs
    .filter(job => job.node === name)
    .forEach(job => job.isValid = false);
}<|endoftext|>


<commit_before>const { COINS, ALL_CRYPTOS } = require('lamassu-coins')
const _ = require('lodash/fp')

const { ALL } = require('../../plugins/common/ccxt')

const { BTC, BCH, DASH, ETH, LTC, ZEC, USDT, XMR } = COINS
const { bitpay, coinbase, itbit, bitstamp, kraken, binanceus, cex, ftx } = ALL

const TICKER = 'ticker'
const WALLET = 'wallet'
const LAYER_2 = 'layer2'
const EXCHANGE = 'exchange'
const SMS = 'sms'
const ID_VERIFIER = 'idVerifier'
const EMAIL = 'email'
const ZERO_CONF = 'zeroConf'

const ALL_ACCOUNTS = [
  { code: 'binanceus', display: 'Binance.us', class: TICKER, cryptos: binanceus.CRYPTO },
  { code: 'cex', display: 'CEX', class: TICKER, cryptos: cex.CRYPTO },
  { code: 'ftx', display: 'FTX', class: TICKER, cryptos: ftx.CRYPTO },
  { code: 'bitpay', display: 'Bitpay', class: TICKER, cryptos: bitpay.CRYPTO },
  { code: 'kraken', display: 'Kraken', class: TICKER, cryptos: kraken.CRYPTO },
  { code: 'bitstamp', display: 'Bitstamp', class: TICKER, cryptos: bitstamp.CRYPTO },
  { code: 'coinbase', display: 'Coinbase', class: TICKER, cryptos: coinbase.CRYPTO },
  { code: 'itbit', display: 'itBit', class: TICKER, cryptos: itbit.CRYPTO },
  { code: 'mock-ticker', display: 'Mock (Caution!)', class: TICKER, cryptos: ALL_CRYPTOS, dev: true },
  { code: 'bitcoind', display: 'bitcoind', class: WALLET, cryptos: [BTC] },
  { code: 'no-layer2', display: 'No Layer 2', class: LAYER_2, cryptos: ALL_CRYPTOS },
  { code: 'infura', display: 'Infura', class: WALLET, cryptos: [ETH, USDT] },
  { code: 'geth', display: 'geth', class: WALLET, cryptos: [ETH, USDT] },
  { code: 'zcashd', display: 'zcashd', class: WALLET, cryptos: [ZEC] },
  { code: 'litecoind', display: 'litecoind', class: WALLET, cryptos: [LTC] },
  { code: 'dashd', display: 'dashd', class: WALLET, cryptos: [DASH] },
  { code: 'monerod', display: 'monerod', class: WALLET, cryptos: [XMR] },
  { code: 'bitcoincashd', display: 'bitcoincashd', class: WALLET, cryptos: [BCH] },
  { code: 'bitgo', display: 'BitGo', class: WALLET, cryptos: [BTC, ZEC, LTC, BCH, DASH] },
  { code: 'bitstamp', display: 'Bitstamp', class: EXCHANGE, cryptos: bitstamp.CRYPTO },
  { code: 'itbit', display: 'itBit', class: EXCHANGE, cryptos: itbit.CRYPTO },
  { code: 'kraken', display: 'Kraken', class: EXCHANGE, cryptos: kraken.CRYPTO },
  { code: 'binanceus', display: 'Binance.us', class: EXCHANGE, cryptos: binanceus.CRYPTO },
  { code: 'cex', display: 'CEX', class: EXCHANGE, cryptos: cex.CRYPTO },
  { code: 'ftx', display: 'FTX', class: EXCHANGE, cryptos: ftx.CRYPTO },
  { code: 'mock-wallet', display: 'Mock (Caution!)', class: WALLET, cryptos: ALL_CRYPTOS, dev: true },
  { code: 'no-exchange', display: 'No exchange', class: EXCHANGE, cryptos: ALL_CRYPTOS },
  { code: 'mock-exchange', display: 'Mock exchange', class: EXCHANGE, cryptos: ALL_CRYPTOS, dev: true },
  { code: 'mock-sms', display: 'Mock SMS', class: SMS, dev: true },
  { code: 'mock-id-verify', display: 'Mock ID verifier', class: ID_VERIFIER, dev: true },
  { code: 'twilio', display: 'Twilio', class: SMS },
  { code: 'mailgun', display: 'Mailgun', class: EMAIL },
  { code: 'none', display: 'None', class: ZERO_CONF, cryptos: [BTC, ZEC, LTC, DASH, BCH, ETH, XMR] },
  { code: 'blockcypher', display: 'Blockcypher', class: ZERO_CONF, cryptos: [BTC] },
  { code: 'mock-zero-conf', display: 'Mock 0-conf', class: ZERO_CONF, cryptos: ALL_CRYPTOS, dev: true }
]

const devMode = require('minimist')(process.argv.slice(2)).dev
const ACCOUNT_LIST = devMode ? ALL_ACCOUNTS : _.filter(it => !it.dev)(ALL_ACCOUNTS)

module.exports = { ACCOUNT_LIST }
<commit_msg>chore: add ciphertrace and mock scoring to the accounts array<commit_after>const { COINS, ALL_CRYPTOS } = require('lamassu-coins')
const _ = require('lodash/fp')

const { ALL } = require('../../plugins/common/ccxt')

const { BTC, BCH, DASH, ETH, LTC, ZEC, USDT, XMR } = COINS
const { bitpay, coinbase, itbit, bitstamp, kraken, binanceus, cex, ftx } = ALL

const TICKER = 'ticker'
const WALLET = 'wallet'
const LAYER_2 = 'layer2'
const EXCHANGE = 'exchange'
const SMS = 'sms'
const ID_VERIFIER = 'idVerifier'
const EMAIL = 'email'
const ZERO_CONF = 'zeroConf'
const WALLET_SCORING = 'wallet_scoring'

const ALL_ACCOUNTS = [
  { code: 'binanceus', display: 'Binance.us', class: TICKER, cryptos: binanceus.CRYPTO },
  { code: 'cex', display: 'CEX', class: TICKER, cryptos: cex.CRYPTO },
  { code: 'ftx', display: 'FTX', class: TICKER, cryptos: ftx.CRYPTO },
  { code: 'bitpay', display: 'Bitpay', class: TICKER, cryptos: bitpay.CRYPTO },
  { code: 'kraken', display: 'Kraken', class: TICKER, cryptos: kraken.CRYPTO },
  { code: 'bitstamp', display: 'Bitstamp', class: TICKER, cryptos: bitstamp.CRYPTO },
  { code: 'coinbase', display: 'Coinbase', class: TICKER, cryptos: coinbase.CRYPTO },
  { code: 'itbit', display: 'itBit', class: TICKER, cryptos: itbit.CRYPTO },
  { code: 'mock-ticker', display: 'Mock (Caution!)', class: TICKER, cryptos: ALL_CRYPTOS, dev: true },
  { code: 'bitcoind', display: 'bitcoind', class: WALLET, cryptos: [BTC] },
  { code: 'no-layer2', display: 'No Layer 2', class: LAYER_2, cryptos: ALL_CRYPTOS },
  { code: 'infura', display: 'Infura', class: WALLET, cryptos: [ETH, USDT] },
  { code: 'geth', display: 'geth', class: WALLET, cryptos: [ETH, USDT] },
  { code: 'zcashd', display: 'zcashd', class: WALLET, cryptos: [ZEC] },
  { code: 'litecoind', display: 'litecoind', class: WALLET, cryptos: [LTC] },
  { code: 'dashd', display: 'dashd', class: WALLET, cryptos: [DASH] },
  { code: 'monerod', display: 'monerod', class: WALLET, cryptos: [XMR] },
  { code: 'bitcoincashd', display: 'bitcoincashd', class: WALLET, cryptos: [BCH] },
  { code: 'bitgo', display: 'BitGo', class: WALLET, cryptos: [BTC, ZEC, LTC, BCH, DASH] },
  { code: 'bitstamp', display: 'Bitstamp', class: EXCHANGE, cryptos: bitstamp.CRYPTO },
  { code: 'itbit', display: 'itBit', class: EXCHANGE, cryptos: itbit.CRYPTO },
  { code: 'kraken', display: 'Kraken', class: EXCHANGE, cryptos: kraken.CRYPTO },
  { code: 'binanceus', display: 'Binance.us', class: EXCHANGE, cryptos: binanceus.CRYPTO },
  { code: 'cex', display: 'CEX', class: EXCHANGE, cryptos: cex.CRYPTO },
  { code: 'ftx', display: 'FTX', class: EXCHANGE, cryptos: ftx.CRYPTO },
  { code: 'mock-wallet', display: 'Mock (Caution!)', class: WALLET, cryptos: ALL_CRYPTOS, dev: true },
  { code: 'no-exchange', display: 'No exchange', class: EXCHANGE, cryptos: ALL_CRYPTOS },
  { code: 'mock-exchange', display: 'Mock exchange', class: EXCHANGE, cryptos: ALL_CRYPTOS, dev: true },
  { code: 'mock-sms', display: 'Mock SMS', class: SMS, dev: true },
  { code: 'mock-id-verify', display: 'Mock ID verifier', class: ID_VERIFIER, dev: true },
  { code: 'twilio', display: 'Twilio', class: SMS },
  { code: 'mailgun', display: 'Mailgun', class: EMAIL },
  { code: 'none', display: 'None', class: ZERO_CONF, cryptos: [BTC, ZEC, LTC, DASH, BCH, ETH, XMR] },
  { code: 'blockcypher', display: 'Blockcypher', class: ZERO_CONF, cryptos: [BTC] },
  { code: 'mock-zero-conf', display: 'Mock 0-conf', class: ZERO_CONF, cryptos: ALL_CRYPTOS, dev: true },
  { code: 'ciphertrace', display: 'CipherTrace', class: WALLET_SCORING, cryptos: [BTC, ETH, LTC, BCH] },
  { code: 'mock-scoring', display: 'Mock scoring', class: WALLET_SCORING, cryptos: ALL_CRYPTOS, dev: true }
]

const devMode = require('minimist')(process.argv.slice(2)).dev
const ACCOUNT_LIST = devMode ? ALL_ACCOUNTS : _.filter(it => !it.dev)(ALL_ACCOUNTS)

module.exports = { ACCOUNT_LIST }
<|endoftext|>


<commit_before>'use strict';

class MemoryLeakHandler {

    constructor(options) {
        if(!options) {
            options = {};
        }

        if(options.autostart === undefined) {
            options.autostart = true;
        }

        this.max_rss = options.max_rss || 128;
        this.check_interval = options.check_interval || 1000;

        if(options.on_exit && typeof options.on_exit == 'function') {
            this.on_exit = options.on_exit;
        }

        if(options.autostart) {
            this.start();
        }
    }

    start() {
        this.interval = setInterval(() => {
            const rss = process.memoryUsage().rss / (1024 * 1024);
            if(rss > this.max_rss) {
                this.on_exit(() => {
                    process.exit(1);
                });
            }
        }, this.check_interval);
    }

    stop() {
        clearInterval(this.interval);
    }

    on_exit(callback) {
        return callback();
    }

}

module.exports = MemoryLeakHandler;
<commit_msg>fix equality check<commit_after>'use strict';

class MemoryLeakHandler {

    constructor(options) {
        if(!options) {
            options = {};
        }

        if(options.autostart === undefined) {
            options.autostart = true;
        }

        this.max_rss = options.max_rss || 128;
        this.check_interval = options.check_interval || 1000;

        if(options.on_exit && typeof options.on_exit === 'function') {
            this.on_exit = options.on_exit;
        }

        if(options.autostart) {
            this.start();
        }
    }

    start() {
        this.interval = setInterval(() => {
            const rss = process.memoryUsage().rss / (1024 * 1024);
            if(rss > this.max_rss) {
                this.on_exit(() => {
                    process.exit(1);
                });
            }
        }, this.check_interval);
    }

    stop() {
        clearInterval(this.interval);
    }

    on_exit(callback) {
        return callback();
    }

}

module.exports = MemoryLeakHandler;
<|endoftext|>


<commit_before>"use strict";
var Ajv = require('ajv');
var fs = require('fs');
var http = require('http');
var jsonlint = require('jsonlint');
var selectObjectFromJson = require('./selectObjectFromJson');
var localize = require('ajv-i18n');

var chosenLanguage = localize.de;

function doValidate(json, validated_version, file, success, failure) {
	var retval = false;
	var version = json.X3D["@version"];
	var error = ""
	if (typeof validated_version !== 'undefined') {
		var valid = validated_version(json);
		if (!valid) {
			chosenLanguage(validated_version.errors);
			console.error("================================================================================");
			console.error("File:", file);
			var errs = validated_version.errors;
			for (var e in errs) {
				error += "\r\n keyword: " + errs[e].keyword + "\r\n";
				var dataPath = errs[e].dataPath.replace(/^\./, "").replace(/[\.\[\]']+/g, " > ").replace(/ >[ \t]*$/, "");

				error += " dataPath: " + dataPath+ "\r\n";
				var selectedObject = selectObjectFromJson(json, dataPath);
				error += " value: " + JSON.stringify(selectedObject,
					function(k, v) {
					    var v2 = JSON.parse(JSON.stringify(v));
					    if (typeof v2 === 'object') {
						    for (var o in v2) {
					    		if (typeof v2[o] === 'object') {
								    v2[o] = "|omitted|";
							}
					            }
					    }
					    return v2;
					}) + "\r\n";
				error += " message: " + errs[e].message + "\r\n";
				error += " params: " + JSON.stringify(errs[e].params) + "\r\n";
				error += " file: " + file + "\r\n";
				error += " version: " + version + "\r\n";
			}
			failure(error);
		} else {
			if (typeof success == 'function') {
				success();
			} else {
				failure("No success function");
			}
		}
	} else {
		failure("Schema not loaded");
	}
}

function loadSchema(json, file, doValidate, success, failure) {
	var versions = { "3.0":true,"3.1":true,"3.2":true,"3.3":true,"3.4":true, "4.0":true }
	var version = json.X3D["@version"];
	if (!versions[version]) {
		console.error("Can only validate version 3.0-4.0 presently. Switching version to 3.3.");
		version = "3.3";
	}
	var validated_version = validate[version];
        if (typeof validated_version === 'undefined') {
		var ajv = new Ajv({ allErrors:true});
		ajv.addFormat("uri", /^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@\/?]|%[0-9a-f]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'()*+,;=:@\/?]|%[0-9a-f]{2})*)?$/i);

		console.error("Loading meta schema");
		var metaschema = fs.readFileSync('draft-04-JSONSchema.json');
		console.error("Parsing meta schema");
		var metaschemajson = JSON.parse(metaschema.toString());
		console.error("Adding meta schema");
		ajv.addMetaSchema(metaschemajson);
		console.error("Loading schema");
		var schema = fs.readFileSync("x3d-"+version+"-JSONSchema.json");
		console.error("Parsing schema");
		var schemajson = JSON.parse(schema.toString());
		console.error("Adding schema");
		ajv.addSchema(schemajson);
		console.error("Schema", version, "added");
		validated_version = ajv.compile(schemajson);
		validate[version] = validated_version;
		if (typeof validated_version === 'undefined') {
			console.error("Schema", version, "not compiled");
		} else {
			console.error("Schema", version, "compiled");
		}
		doValidate(json, validated_version, file, success, failure);
	} else {
		doValidate(json, validated_version, file, success, failure);
	}
}

function validateJSON(files) {

	for (var f in files) {
		var file = files[f];
		var str = fs.readFileSync(file).toString();
		if (typeof str === 'undefined') {
			throw("Read nothing, or possbile error");
		}
		try {
			var json = jsonlint.parse(str);
			var version = json.X3D["@version"];
			loadSchema(json, file, doValidate, function() {
				console.error("Success reading", file);
			}, function(e) {
				console.error("Error reading", file, e);

			});
		} catch (e) {
			console.error("================================================================================");
			console.error("File:", file);
			console.error(e);
		}
	}
}
function exchangeajvmessage(msg) {
        var str = fs.readFileSync("wordMap2.json").toString();
        var json = jsonlint.parse(str);
        var newString="";
        var object = json;
        var k=0;
        var flag=false;
        var begin,value,values=[],m=0;
        for (var i=0; i < msg.length ; i++) {
                newString+=msg[i];
                if ( newString=="" && object[newString].prototype.keys()[0]=="(*)" && !flag) {
                        object=object[newString];
                        flag=true;
                        begin=i;
                }
                if (flag) {
                        if (msg[i]==' ') {
                                newString="";
                        }
                        value+=msg[i];
                }
                if (object[newString]!=undefined) {
                        object=object[newString];
                        newString="";
                        i++;
                        k++;
                        values.push(value);
                        flag=false;
                        m=i;
                }
        }
        return object['en'] + '' + ',to stand X3D json validation requirements.'+ values[0]+ ' ' + values[1];
}
//alx:
//console.log('alx: '+exchangeajvmessage('should NOT have 123 then abc'));

module.exports = validateJSON
<commit_msg>Added validate<commit_after>"use strict";
var Ajv = require('ajv');
var fs = require('fs');
var http = require('http');
var jsonlint = require('jsonlint');
var selectObjectFromJson = require('./selectObjectFromJson');
var localize = require('ajv-i18n');

var validate = function() { return false; }

var chosenLanguage = localize.de;

function doValidate(json, validated_version, file, success, failure) {
	var retval = false;
	var version = json.X3D["@version"];
	var error = ""
	if (typeof validated_version !== 'undefined') {
		var valid = validated_version(json);
		if (!valid) {
			chosenLanguage(validated_version.errors);
			console.error("================================================================================");
			console.error("File:", file);
			var errs = validated_version.errors;
			for (var e in errs) {
				error += "\r\n keyword: " + errs[e].keyword + "\r\n";
				var dataPath = errs[e].dataPath.replace(/^\./, "").replace(/[\.\[\]']+/g, " > ").replace(/ >[ \t]*$/, "");

				error += " dataPath: " + dataPath+ "\r\n";
				var selectedObject = selectObjectFromJson(json, dataPath);
				error += " value: " + JSON.stringify(selectedObject,
					function(k, v) {
					    var v2 = JSON.parse(JSON.stringify(v));
					    if (typeof v2 === 'object') {
						    for (var o in v2) {
					    		if (typeof v2[o] === 'object') {
								    v2[o] = "|omitted|";
							}
					            }
					    }
					    return v2;
					}) + "\r\n";
				error += " message: " + errs[e].message + "\r\n";
				error += " params: " + JSON.stringify(errs[e].params) + "\r\n";
				error += " file: " + file + "\r\n";
				error += " version: " + version + "\r\n";
			}
			failure(error);
		} else {
			if (typeof success == 'function') {
				success();
			} else {
				failure("No success function");
			}
		}
	} else {
		failure("Schema not loaded");
	}
}

function loadSchema(json, file, doValidate, success, failure) {
	var versions = { "3.0":true,"3.1":true,"3.2":true,"3.3":true,"3.4":true, "4.0":true }
	var version = json.X3D["@version"];
	if (!versions[version]) {
		console.error("Can only validate version 3.0-4.0 presently. Switching version to 3.3.");
		version = "3.3";
	}
	var validated_version = validate[version];
        if (typeof validated_version === 'undefined') {
		var ajv = new Ajv({ allErrors:true});
		ajv.addFormat("uri", /^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@\/?]|%[0-9a-f]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'()*+,;=:@\/?]|%[0-9a-f]{2})*)?$/i);

		console.error("Loading meta schema");
		var metaschema = fs.readFileSync('draft-04-JSONSchema.json');
		console.error("Parsing meta schema");
		var metaschemajson = JSON.parse(metaschema.toString());
		console.error("Adding meta schema");
		ajv.addMetaSchema(metaschemajson);
		console.error("Loading schema");
		var schema = fs.readFileSync("x3d-"+version+"-JSONSchema.json");
		console.error("Parsing schema");
		var schemajson = JSON.parse(schema.toString());
		console.error("Adding schema");
		ajv.addSchema(schemajson);
		console.error("Schema", version, "added");
		validated_version = ajv.compile(schemajson);
		validate[version] = validated_version;
		if (typeof validated_version === 'undefined') {
			console.error("Schema", version, "not compiled");
		} else {
			console.error("Schema", version, "compiled");
		}
		doValidate(json, validated_version, file, success, failure);
	} else {
		doValidate(json, validated_version, file, success, failure);
	}
}

function validateJSON(files) {

	for (var f in files) {
		var file = files[f];
		var str = fs.readFileSync(file).toString();
		if (typeof str === 'undefined') {
			throw("Read nothing, or possbile error");
		}
		try {
			var json = jsonlint.parse(str);
			var version = json.X3D["@version"];
			loadSchema(json, file, doValidate, function() {
				console.error("Success reading", file);
			}, function(e) {
				console.error("Error reading", file, e);

			});
		} catch (e) {
			console.error("================================================================================");
			console.error("File:", file);
			console.error(e);
		}
	}
}
function exchangeajvmessage(msg) {
        var str = fs.readFileSync("wordMap2.json").toString();
        var json = jsonlint.parse(str);
        var newString="";
        var object = json;
        var k=0;
        var flag=false;
        var begin,value,values=[],m=0;
        for (var i=0; i < msg.length ; i++) {
                newString+=msg[i];
                if ( newString=="" && object[newString].prototype.keys()[0]=="(*)" && !flag) {
                        object=object[newString];
                        flag=true;
                        begin=i;
                }
                if (flag) {
                        if (msg[i]==' ') {
                                newString="";
                        }
                        value+=msg[i];
                }
                if (object[newString]!=undefined) {
                        object=object[newString];
                        newString="";
                        i++;
                        k++;
                        values.push(value);
                        flag=false;
                        m=i;
                }
        }
        return object['en'] + '' + ',to stand X3D json validation requirements.'+ values[0]+ ' ' + values[1];
}
//alx:
//console.log('alx: '+exchangeajvmessage('should NOT have 123 then abc'));

module.exports = validateJSON
<|endoftext|>


<commit_before>var html = require('choo/html')
var css = require('sheetify')
var choo = require('choo')

var speakerData = require('./speakers.json')
var date = {
  dayOfWeek: 'Thursday',
  time: '7pm',
  date: 'May 4th'
}

css('tachyons')

css`
  .js-yellow { color: #f7df1e }
  .bg-js-yellow { background-color: #f7df1e }
`

var logo = css`
  :host {
    font-size: 4rem;
    text-shadow:
      -1px 1px black,
      -2px 2px black,
      -3px 3px black,
      -4px 4px black;
  }

  @media screen and (min-width: 60em) {
    :host {
      font-size: 12rem;
      text-shadow:
        -3px 3px black,
        -6px 6px black,
        -9px 9px black,
        -12px 12px black;
    }
  }
`

var app = choo()
app.route('/', mainView)
if (module.parent) module.exports = app
else app.mount('body')

function mainView () {
  return html`

      ${nav()}

        ${speakers()}
        ${codeOfConduct()}
        ${sponsor()}

      ${footer()}

  `
}

function nav () {
  return html`

          berlin.js

JSConf EU 2017 special

        ${date.dayOfWeek} ${date.date}

        ${date.time} at

          co.up

  `
}

function speakers () {
  return html`

          Featuring amazing speakers

            ${speakerData.map(speaker)}

  `
  function speaker (data) {
    return html`

          ${data.name}

          ${data.description}

    `
  }
}

function codeOfConduct () {
  return html`

            We care about human beings

          Our goal is to have an awesome, inclusive and safe community meetup
          where people meet, hang out together, chat, listen to talks, exchange
          ideas and make new friends.

            Any harmful or discriminating behaviour
            will not be tolerated and results in the offending person being
            expelled from the meetup.

          For details on what kinds of behaviour are not tolerated and
          consequences for violating these rules, we refer to the

            Berlin Code of Conduct.

  `
}

function sponsor () {
  return html`

          Kindly sponsored by

            co.up coworking

  `
}

function footer () {
  return html`

          We're on Twitter

          And on Meetup

          We also have a Slack

          And a mailing list

  `
}
<commit_msg>chore: add intro<commit_after>var html = require('choo/html')
var css = require('sheetify')
var choo = require('choo')

var speakerData = require('./speakers.json')
var date = {
  dayOfWeek: 'Thursday',
  time: '7pm',
  date: 'May 4th'
}

css('tachyons')

css`
  .js-yellow { color: #f7df1e }
  .bg-js-yellow { background-color: #f7df1e }
`

var logo = css`
  :host {
    font-size: 4rem;
    text-shadow:
      -1px 1px black,
      -2px 2px black,
      -3px 3px black,
      -4px 4px black;
  }

  @media screen and (min-width: 60em) {
    :host {
      font-size: 12rem;
      text-shadow:
        -3px 3px black,
        -6px 6px black,
        -9px 9px black,
        -12px 12px black;
    }
  }
`

var app = choo()
app.route('/', mainView)
if (module.parent) module.exports = app
else app.mount('body')

function mainView () {
  return html`

      ${nav()}

        ${intro()}
        ${speakers()}
        ${codeOfConduct()}
        ${sponsor()}

      ${footer()}

  `
}

function nav () {
  return html`

          berlin.js

JSConf EU 2017 special

        ${date.dayOfWeek} ${date.date}

        ${date.time} at

          co.up

  `
}

function speakers () {
  return html`

          Featuring amazing speakers

            ${speakerData.map(speaker)}

  `
  function speaker (data) {
    return html`

          ${data.name}

          ${data.description}

    `
  }
}

function intro () {
  return html`

            Wait, what's this?

          Welcome to our JSConf EU special, a
          special occasion for the Berlin JavaScript community to mix and mingle
          with people coming to JSConf EU 2017 from all over the world.

          We will have talks and plenty of space to meet new people. See you there!

  `
}

function codeOfConduct () {
  return html`

            We care about human beings

          Our goal is to have an awesome, inclusive and safe community meetup
          where people meet, hang out together, chat, listen to talks, exchange
          ideas and make new friends.

            Any harmful or discriminating behaviour
            will not be tolerated and results in the offending person being
            expelled from the meetup.

          For details on what kinds of behaviour are not tolerated and
          consequences for violating these rules, we refer to the

            Berlin Code of Conduct.

  `
}

function sponsor () {
  return html`

          Kindly sponsored by

            co.up coworking

  `
}

function footer () {
  return html`

          We're on Twitter

          And on Meetup

          We also have a Slack

          And a mailing list

  `
}
<|endoftext|>


<commit_before>var _ = require('underscore');

var livereload = require('livereload');
var server = livereload.createServer();
server.watch(__dirname + '/public');

var express = require('express');
var app = express();

var http = require('http').Server(app);
var io = require('socket.io')(http);

app.use(express.static(__dirname + '/public'));
http.listen(8080, function() {
    console.log('listening on 8080');
});

var width = 10;
var height = 6;

var players = [];

var gameState = [];

for (var i = 0; i < height; i++) {
    gameState.push([]);
}

var numPlayers = 5;

for (var x = 0; x < width; x++) {
    for (var y = 0; y < height; y++) {
        gameState[y][x] = Math.floor(Math.random() * numPlayers);
    }
}

var checkPlayField = function() {
    var shouldBeDeleted = [];
    for (var y = 0; y < height; y++) {
        for (var x = 0; x < width; x++) {
            // ignore empty elements
            if (gameState[y][x] === -1) {
                continue;
            }
            // check neighbors, but only if we're not going out of bounds
            if ((y > 0          && gameState[y][x] === gameState[y - 1][x])     ||
                (x > 0          && gameState[y][x] === gameState[y]    [x - 1]) ||
                (y < height - 1 && gameState[y][x] === gameState[y + 1][x])     ||
                (x < width - 1  && gameState[y][x] === gameState[y]    [x + 1])) {
                shouldBeDeleted.push({x: x, y: y});
            }
        }
    }

    if (shouldBeDeleted.length) {
        for (var i = 0; i < shouldBeDeleted.length; i++) {
            var x = shouldBeDeleted[i].x;
            var y = shouldBeDeleted[i].y;

            // loop from top of playfield above removed element,
            // drop every piece down one step
            for (var j = y - 1; j >= 0; j--) {
                gameState[j + 1][x] = gameState[j][x];
            }
            gameState[0][x] = -1;
        }

        // call recursively until there is nothing more to delete
        checkPlayField();
    }
};

// check playfield once before starting game
checkPlayField();

var drawGameState = function() {
    console.log(gameState);
    /*
    for (var y = 0; y < height; y++) {
        for (var x = 0; x < width; x++) {
            process.stdout.write(gameState[x][y] + ', ');
        }
        process.stdout.write('\n');
    }
    */
};
drawGameState();

var doMove = function(pos, color) {
    var posCharacter = pos;
    pos = pos.charCodeAt(0) - pos.charCodeAt('a');

    if (pos < 0 || pos > width - 1) {
        console.log('invalid move!');
        return;
    }

    if (gameState[0][pos] !== -1) {
        console.log('invalid move! column ' + posCharacter + ' is full.');
        return;
    }

    // search first piece that either contains a piece or is beyond the array
    // (undefined), put new piece on top of it
    var y;
    for (var i = 0; i < height; i++) {
        if (gameState[i][pos] !== -1) {
            y = i - 1;
            gameState[i - 1][pos] = color;
            break;
        }
    }

    checkPlayField();
    drawGameState();

    var move = {
        x: pos,
        y: y,
        color: color
    };
    io.sockets.emit('doMove', move);
};

io.on('connection', function(socket) {
    socket.emit('gameState', gameState);
});

var initPlayer = function(msg) {
    console.log(msg.from.first_name + ' joined the game with id: ' + msg.from.id);

    var player = {
        name: msg.from.first_name,
        id: msg.from.id
    }

    // return new index
    return players.push(player) - 1;
};

try {
    var token = require(process.env.HOME + '/.diagram-bot-token.js');
    var Bot = require('node-telegram-bot');

    var bot = new Bot({
        token: token
    })
    .on('message', function(msg) {
        if (msg.text) {
            msg.text = msg.text.toLowerCase();

            var color = _.findIndex(players, function(player) {
                return player.id === msg.from.id;
            });

            if (msg.text.indexOf('/start')) {
                if (!color) {
                    color = initPlayer(msg);
                }

                bot.sendMessage({
                    chat_id: msg.chat ? msg.chat.id : msg.from.id,
                    reply_to_message_id: msg.message_id,
                    reply_markup: {
                        keyboard: [
                            ['/a', '/b', '/c', '/d', '/e'],
                            ['/f', '/g', '/h', '/i', '/j']
                        ],
                        resize_keyboard: true,
                        selective: true
                    }
                }, function(err) {
                    if (err) {
                        console.log('error on sendMessage:');
                        console.log(err);
                    }
                });
            // drop piece commands
            } else if (msg.text.substr(0, 1) === '/' &&
                       msg.charCodeAt(1) >= 'a'.charCodeAt(0) &&
                       msg.charCodeAt(1) <= 'z'.charCodeAt(0)) {
                if (!color) {
                    color = initPlayer(msg);
                }

                doMove(msg.text.substr(1, 2), color);
            } else {
                console.log('error: unknown command!');
                console.log(msg.text);
            }
        }
    });

    bot.start();
} catch(e) {
    console.log('error initializing telegram bot API!');
    console.log(e);
    console.log('did you forget to write your API key to ~/.diagram-bot-token.js?');
    console.log('will use stdin for input instead (TODO)');
}
<commit_msg>fix a typo<commit_after>var _ = require('underscore');

var livereload = require('livereload');
var server = livereload.createServer();
server.watch(__dirname + '/public');

var express = require('express');
var app = express();

var http = require('http').Server(app);
var io = require('socket.io')(http);

app.use(express.static(__dirname + '/public'));
http.listen(8080, function() {
    console.log('listening on 8080');
});

var width = 10;
var height = 6;

var players = [];

var gameState = [];

for (var i = 0; i < height; i++) {
    gameState.push([]);
}

var numPlayers = 5;

for (var x = 0; x < width; x++) {
    for (var y = 0; y < height; y++) {
        gameState[y][x] = Math.floor(Math.random() * numPlayers);
    }
}

var checkPlayField = function() {
    var shouldBeDeleted = [];
    for (var y = 0; y < height; y++) {
        for (var x = 0; x < width; x++) {
            // ignore empty elements
            if (gameState[y][x] === -1) {
                continue;
            }
            // check neighbors, but only if we're not going out of bounds
            if ((y > 0          && gameState[y][x] === gameState[y - 1][x])     ||
                (x > 0          && gameState[y][x] === gameState[y]    [x - 1]) ||
                (y < height - 1 && gameState[y][x] === gameState[y + 1][x])     ||
                (x < width - 1  && gameState[y][x] === gameState[y]    [x + 1])) {
                shouldBeDeleted.push({x: x, y: y});
            }
        }
    }

    if (shouldBeDeleted.length) {
        for (var i = 0; i < shouldBeDeleted.length; i++) {
            var x = shouldBeDeleted[i].x;
            var y = shouldBeDeleted[i].y;

            // loop from top of playfield above removed element,
            // drop every piece down one step
            for (var j = y - 1; j >= 0; j--) {
                gameState[j + 1][x] = gameState[j][x];
            }
            gameState[0][x] = -1;
        }

        // call recursively until there is nothing more to delete
        checkPlayField();
    }
};

// check playfield once before starting game
checkPlayField();

var drawGameState = function() {
    console.log(gameState);
    /*
    for (var y = 0; y < height; y++) {
        for (var x = 0; x < width; x++) {
            process.stdout.write(gameState[x][y] + ', ');
        }
        process.stdout.write('\n');
    }
    */
};
drawGameState();

var doMove = function(pos, color) {
    var posCharacter = pos;
    pos = pos.charCodeAt(0) - pos.charCodeAt('a');

    if (pos < 0 || pos > width - 1) {
        console.log('invalid move!');
        return;
    }

    if (gameState[0][pos] !== -1) {
        console.log('invalid move! column ' + posCharacter + ' is full.');
        return;
    }

    // search first piece that either contains a piece or is beyond the array
    // (undefined), put new piece on top of it
    var y;
    for (var i = 0; i < height; i++) {
        if (gameState[i][pos] !== -1) {
            y = i - 1;
            gameState[i - 1][pos] = color;
            break;
        }
    }

    checkPlayField();
    drawGameState();

    var move = {
        x: pos,
        y: y,
        color: color
    };
    io.sockets.emit('doMove', move);
};

io.on('connection', function(socket) {
    socket.emit('gameState', gameState);
});

var initPlayer = function(msg) {
    console.log(msg.from.first_name + ' joined the game with id: ' + msg.from.id);

    var player = {
        name: msg.from.first_name,
        id: msg.from.id
    }

    // return new index
    return players.push(player) - 1;
};

try {
    var token = require(process.env.HOME + '/.diagram-bot-token.js');
    var Bot = require('node-telegram-bot');

    var bot = new Bot({
        token: token
    })
    .on('message', function(msg) {
        console.log(msg);

        if (msg.text) {
            msg.text = msg.text.toLowerCase();

            var color = _.findIndex(players, function(player) {
                return player.id === msg.from.id;
            });

            if (msg.text.indexOf('/start')) {
                if (!color) {
                    color = initPlayer(msg);
                }

                bot.sendMessage({
                    text: 'Welcome to diagram!',
                    chat_id: msg.chat ? msg.chat.id : msg.from.id,
                    reply_to_message_id: msg.message_id,
                    reply_markup: {
                        keyboard: [
                            ['/a', '/b', '/c', '/d', '/e'],
                            ['/f', '/g', '/h', '/i', '/j']
                        ],
                        resize_keyboard: true,
                        selective: true
                    }
                }, function(err) {
                    if (err) {
                        console.log('error on sendMessage:');
                        console.log(err);
                    }
                });
            // drop piece commands
            } else if (msg.text.substr(0, 1) === '/' &&
                       msg.text.charCodeAt(1) >= 'a'.charCodeAt(0) &&
                       msg.text.charCodeAt(1) <= 'z'.charCodeAt(0)) {
                if (!color) {
                    color = initPlayer(msg);
                }

                doMove(msg.text.substr(1, 2), color);
            } else {
                console.log('error: unknown command!');
                console.log(msg.text);
            }
        }
    });

    bot.start();
} catch(e) {
    console.log('error initializing telegram bot API!');
    console.log(e);
    console.log('did you forget to write your API key to ~/.diagram-bot-token.js?');
    console.log('will use stdin for input instead (TODO)');

    process.stdin.on('readable', function() {
        var chunk = process.stdin.read();
        if (chunk !== null) {
            process.stdout.write('data: ' + chunk);
        }
    });
}
<|endoftext|>


<commit_before>'use strict';

var assign = require('object-assign');
var babel = require('babel-core');
var loaderUtils = require('loader-utils');
var cache = require('./lib/fs-cache.js');
var resolveRc = require('./lib/resolve-rc.js');
var pkg = require('./package.json');
var babelrc = resolveRc(process.cwd());

var transpile = function(source, options) {
  var result = babel.transform(source, options);
  var code = result.code;
  var map = result.map;

  if (map && (!map.sourcesContent || !map.sourcesContent.length)) {
    map.sourcesContent = [source];
  }

  return {
    code: code,
    map: map,
  };
};

module.exports = function(source, inputSourceMap) {
  var result = {};
  // Handle options
  var defaultOptions = {
    inputSourceMap: inputSourceMap,
    filename: loaderUtils.getRemainingRequest(this),
    cacheIdentifier: JSON.stringify({
      'babel-loader': pkg.version,
      'babel-core': babel.version,
      babelrc: babelrc || '',
    }),
  };
  var globalOptions = this.options.babel || {};
  var loaderOptions = loaderUtils.parseQuery(this.query);
  var options = assign({}, defaultOptions, globalOptions, loaderOptions);

  if (options.sourceMap === undefined) {
    options.sourceMap = this.sourceMap;
  }

  var cacheDirectory = options.cacheDirectory;
  var cacheIdentifier = options.cacheIdentifier;

  delete options.cacheDirectory;
  delete options.cacheIdentifier;

  this.cacheable();

  if (cacheDirectory) {
    var callback = this.async();
    return cache({
      directory: cacheDirectory,
      identifier: cacheIdentifier,
      source: source,
      options: options,
      transform: transpile,
    }, function(err, result) {
      if (err) { return callback(err); }
      return callback(null, result.code, result.map);
    });
  }

  result = transpile(source, options);
  this.callback(null, result.code, result.map);
};
<commit_msg>Set source file name relative to options.sourceRoot<commit_after>'use strict';

var assign = require('object-assign');
var babel = require('babel-core');
var loaderUtils = require('loader-utils');
var cache = require('./lib/fs-cache.js');
var resolveRc = require('./lib/resolve-rc.js');
var pkg = require('./package.json');
var babelrc = resolveRc(process.cwd());
var path = require('path');

var transpile = function(source, options) {
  var result = babel.transform(source, options);
  var code = result.code;
  var map = result.map;

  if (map && (!map.sourcesContent || !map.sourcesContent.length)) {
    map.sourcesContent = [source];
  }

  return {
    code: code,
    map: map,
  };
};

module.exports = function(source, inputSourceMap) {
  var result = {};
  // Handle options
  var defaultOptions = {
    inputSourceMap: inputSourceMap,
    sourceRoot: process.cwd(),
    filename: loaderUtils.getRemainingRequest(this),
    cacheIdentifier: JSON.stringify({
      'babel-loader': pkg.version,
      'babel-core': babel.version,
      babelrc: babelrc || '',
    }),
  };
  var globalOptions = this.options.babel || {};
  var loaderOptions = loaderUtils.parseQuery(this.query);
  var options = assign({}, defaultOptions, globalOptions, loaderOptions);

  if (options.sourceMap === undefined) {
    options.sourceMap = this.sourceMap;
  }

  if (options.sourceFileName === undefined) {
    options.sourceFileName = path.relative(
        options.sourceRoot,
        options.filename
    );
  }

  var cacheDirectory = options.cacheDirectory;
  var cacheIdentifier = options.cacheIdentifier;

  delete options.cacheDirectory;
  delete options.cacheIdentifier;

  this.cacheable();

  if (cacheDirectory) {
    var callback = this.async();
    return cache({
      directory: cacheDirectory,
      identifier: cacheIdentifier,
      source: source,
      options: options,
      transform: transpile,
    }, function(err, result) {
      if (err) { return callback(err); }
      return callback(null, result.code, result.map);
    });
  }

  result = transpile(source, options);
  this.callback(null, result.code, result.map);
};
<|endoftext|>


<commit_before>var CachingWriter = require('broccoli-caching-writer');
var path = require('path');
var mkdirp = require('mkdirp');
var fs = require('fs');
var walkSync = require('walk-sync');

var port = 35729;

var snippet = [
  "<!-- livereload snippet -->",
  "<script>document.write('<script src=\"http://'",
  " + (location.host || 'localhost').split(':')[0]",
  " + ':" + port + "/livereload.js?snipver=1\"><\\/script>')",
  "</script>",
  ""
].join('\n');

var handleFile = function (srcDir, destDir, relativePath) {
  var fullInputPath = path.join(srcDir, relativePath);
  var fullOutputPath = path.join(destDir, relativePath);
  var contents;
  if (isHtml(relativePath)) {
    contents = fs.readFileSync(fullInputPath, 'utf-8');
    contents = contents.replace(/<\/body>/, function (w) {
      return snippet + w;
    });
  } else {
    contents = fs.readFileSync(fullInputPath);
  }
  mkdirp.sync(path.dirname(fullOutputPath));
  fs.writeFileSync(fullOutputPath, contents);
};

function InjectLivereload(inputTree, options) {
  if (!(this instanceof InjectLivereload)) {
    return new InjectLivereload(inputTree, options);
  }
  this.enforceSingleInputTree = true;
  CachingWriter.apply(this, arguments);
}

var isHtml = function (filename) {
  return filename.slice(-5) === '.html';
};

InjectLivereload.prototype = Object.create(CachingWriter.prototype);
InjectLivereload.prototype.constructor = InjectLivereload;

InjectLivereload.prototype.updateCache = function (srcDir, destDir) {
  console.log('updateCache');
  walkSync(srcDir).forEach(function (relativePath) {
    if (relativePath.slice(-1) !== '/') {
      handleFile(srcDir, destDir, relativePath);
    }
  });
};

module.exports = InjectLivereload;
<commit_msg>Remove console.log statement<commit_after>var CachingWriter = require('broccoli-caching-writer');
var path = require('path');
var mkdirp = require('mkdirp');
var fs = require('fs');
var walkSync = require('walk-sync');

var port = 35729;

var snippet = [
  "<!-- livereload snippet -->",
  "<script>document.write('<script src=\"http://'",
  " + (location.host || 'localhost').split(':')[0]",
  " + ':" + port + "/livereload.js?snipver=1\"><\\/script>')",
  "</script>",
  ""
].join('\n');

var handleFile = function (srcDir, destDir, relativePath) {
  var fullInputPath = path.join(srcDir, relativePath);
  var fullOutputPath = path.join(destDir, relativePath);
  var contents;
  if (isHtml(relativePath)) {
    contents = fs.readFileSync(fullInputPath, 'utf-8');
    contents = contents.replace(/<\/body>/, function (w) {
      return snippet + w;
    });
  } else {
    contents = fs.readFileSync(fullInputPath);
  }
  mkdirp.sync(path.dirname(fullOutputPath));
  fs.writeFileSync(fullOutputPath, contents);
};

function InjectLivereload(inputTree, options) {
  if (!(this instanceof InjectLivereload)) {
    return new InjectLivereload(inputTree, options);
  }
  this.enforceSingleInputTree = true;
  CachingWriter.apply(this, arguments);
}

var isHtml = function (filename) {
  return filename.slice(-5) === '.html';
};

InjectLivereload.prototype = Object.create(CachingWriter.prototype);
InjectLivereload.prototype.constructor = InjectLivereload;

InjectLivereload.prototype.updateCache = function (srcDir, destDir) {
  walkSync(srcDir).forEach(function (relativePath) {
    if (relativePath.slice(-1) !== '/') {
      handleFile(srcDir, destDir, relativePath);
    }
  });
};

module.exports = InjectLivereload;
<|endoftext|>


<commit_before>"use strict";

const assert = require("assert");
const Cache = require("./cache.js");
const util = require("./util.js");
const cachesByDir = Object.create(null);
const BABEL_CACHE_DIR = process.env.BABEL_CACHE_DIR;
let options; // Lazily initialized.

// Make sure that module.importSync and module.export are defined in the
// current Node process.
const Module = module.constructor;
require("reify/lib/runtime").enable(Module.prototype);

// Options passed to compile will completely replace the default options,
// so if you only want to modify the default options, call this function
// first, modify the result, and then pass those options to compile.
function getDefaultOptions(features) {
  options = options || require("./options.js");
  return options.getDefaults(features);
}
exports.getDefaultOptions = getDefaultOptions;

function getMinifierOptions(features) {
  options = options || require("./options.js");
  return options.getMinifierDefaults(features);
}
exports.getMinifierOptions = getMinifierOptions;

// If you have already imported meteor-babel as a package, and this file
// (index.js) has been evaluated, then there is very little additional
// cost to calling meteorBabel.getMinimumModernBrowserVersions. However,
// if you want to avoid importing meteor-babel, but need to know the
// minimum browser versions, you should import the modern-versions.js
// module directly: require("meteor-babel/modern-versions.js").get().
exports.getMinimumModernBrowserVersions = function () {
  return require("./modern-versions.js").get();
};

const parse = exports.parse = require("./parser").parse;

let didWarnAboutNoCache = false;

exports.compile = function (source, babelOptions, cacheOptions) {
  babelOptions = babelOptions || getDefaultOptions();

  if (cacheOptions !== false) {
    if (cacheOptions &&
        typeof cacheOptions.cacheDirectory === "string") {
      return getOrCreateCache(
        cacheOptions.cacheDirectory
      ).get(source, babelOptions, cacheOptions.cacheDeps);
    }

    // If cacheOptions.cacheDirectory was not provided, and cacheOptions
    // does not have a cacheDeps property, use the whole cacheOptions object
    // as cacheDeps when computing the cache key.
    const cacheDeps = cacheOptions && cacheOptions.cacheDeps || cacheOptions;

    // If no babelOptions.cacheDir was provided, but the BABEL_CACHE_DIR
    // environment variable is set, then respect that.
    if (BABEL_CACHE_DIR) {
      return getOrCreateCache(BABEL_CACHE_DIR)
        .get(source, babelOptions, cacheDeps);
    }

    // If neither babelOptions.cacheDir nor BABEL_CACHE_DIR were provided,
    // use the first cache directory registered so far.
    for (var cacheDirectory in cachesByDir) {
      return getOrCreateCache(cacheDirectory)
        .get(source, babelOptions, cacheDeps);
    }

    // Otherwise fall back to compiling without a cache.
    if (! didWarnAboutNoCache) {
      console.warn("Compiling " + babelOptions.filename +
                  " with meteor-babel without a cache");
      console.trace();
      didWarnAboutNoCache = true;
    }
  }

  return compile(source, babelOptions);
};

function compile(source, options) {
  const babelCore = require("@babel/core");
  let result = { code: source };

  const optionsCopy = util.deepClone(options);
  const { ast, plugins, presets } = optionsCopy;
  delete optionsCopy.plugins;
  delete optionsCopy.typescript;
  optionsCopy.ast = true;

  if (options.typescript) {
    precompileTypeScript(result, options);
  }

  function transform(presets) {
    optionsCopy.plugins = [{
      parserOverride: parse
    }];

    optionsCopy.presets = presets;
    optionsCopy.sourceMaps = true;
    if (result.map) {
      optionsCopy.inputSourceMap = result.map;
    }

    if (result.ast) {
      result = babelCore.transformFromAstSync(
        result.ast,
        result.code,
        optionsCopy
      );
    } else {
      result = babelCore.transformSync(result.code, optionsCopy);
    }

    if (ast === false) {
      delete result.ast;
    }
  }

  if (plugins && plugins.length > 0) {
    const presetOfPlugins = { plugins };
    transform([presetOfPlugins]);
  }

  if (presets) {
    transform(presets);
  }

  return result;
}

function precompileTypeScript(result, options) {
  const fileName = options.filename || options.sourceFileName;
  if (fileName && ! fileName.endsWith(".ts") && ! fileName.endsWith(".tsx")) {
    return;
  }

  const ts = require("typescript");
  let tsResult;
  try {
    tsResult = ts.transpileModule(result.code, {
      fileName,
      compilerOptions: {
        target: ts.ScriptTarget.ESNext,
        // Leave module syntax intact so that Babel/Reify can handle it.
        module: ts.ModuleKind.ESNext,
        // This used to be false by default, but appears to have become
        // true by default around the release of typescript@3.7. It's
        // important to disable this option because enabling it allows
        // TypeScript to use helpers like __importDefault, which are much
        // better handled by Babel/Reify later in the pipeline.
        esModuleInterop: false,
        sourceMap: true,
        inlineSources: true,
      }
    });
  } catch (e) {
    e.message = "While compiling " + fileName + ": " + e.message;
    throw e;
  }

  result.code = tsResult.outputText.replace(
    /\/\/# sourceMappingURL=.*?(\n|$)/g,
    "$1" // preserve trailing \n characters
  );

  result.map = JSON.parse(tsResult.sourceMapText);
  if (fileName) {
    result.map.file = fileName;
    result.map.sources = [fileName];
  }
}

exports.minify = function minify(source, options) {
  // We are not compiling the code in this step, only minifying, so reify
  // is not used.
  return require("@babel/core").transformFromAst(
    parse(source),
    source,
    options || getMinifierOptions()
  );
}

function getOrCreateCache(cacheDir) {
  return cachesByDir[cacheDir] || (
    cachesByDir[cacheDir] = new Cache(compile, cacheDir)
  );
}
exports.setCacheDir = getOrCreateCache;

exports.runtime = // Legacy name; prefer installRuntime.
exports.installRuntime = function installRuntime() {
  return require("./runtime.js");
};

exports.defineHelpers = function defineHelpers() {
  return require("meteor-babel-helpers");
};
<commit_msg>Add support for decorators and metadata reflection in TS<commit_after>"use strict";

const assert = require("assert");
const Cache = require("./cache.js");
const util = require("./util.js");
const cachesByDir = Object.create(null);
const BABEL_CACHE_DIR = process.env.BABEL_CACHE_DIR;
let options; // Lazily initialized.

// Make sure that module.importSync and module.export are defined in the
// current Node process.
const Module = module.constructor;
require("reify/lib/runtime").enable(Module.prototype);

// Options passed to compile will completely replace the default options,
// so if you only want to modify the default options, call this function
// first, modify the result, and then pass those options to compile.
function getDefaultOptions(features) {
  options = options || require("./options.js");
  return options.getDefaults(features);
}
exports.getDefaultOptions = getDefaultOptions;

function getMinifierOptions(features) {
  options = options || require("./options.js");
  return options.getMinifierDefaults(features);
}
exports.getMinifierOptions = getMinifierOptions;

// If you have already imported meteor-babel as a package, and this file
// (index.js) has been evaluated, then there is very little additional
// cost to calling meteorBabel.getMinimumModernBrowserVersions. However,
// if you want to avoid importing meteor-babel, but need to know the
// minimum browser versions, you should import the modern-versions.js
// module directly: require("meteor-babel/modern-versions.js").get().
exports.getMinimumModernBrowserVersions = function () {
  return require("./modern-versions.js").get();
};

const parse = exports.parse = require("./parser").parse;

let didWarnAboutNoCache = false;

exports.compile = function (source, babelOptions, cacheOptions) {
  babelOptions = babelOptions || getDefaultOptions();

  if (cacheOptions !== false) {
    if (cacheOptions &&
        typeof cacheOptions.cacheDirectory === "string") {
      return getOrCreateCache(
        cacheOptions.cacheDirectory
      ).get(source, babelOptions, cacheOptions.cacheDeps);
    }

    // If cacheOptions.cacheDirectory was not provided, and cacheOptions
    // does not have a cacheDeps property, use the whole cacheOptions object
    // as cacheDeps when computing the cache key.
    const cacheDeps = cacheOptions && cacheOptions.cacheDeps || cacheOptions;

    // If no babelOptions.cacheDir was provided, but the BABEL_CACHE_DIR
    // environment variable is set, then respect that.
    if (BABEL_CACHE_DIR) {
      return getOrCreateCache(BABEL_CACHE_DIR)
        .get(source, babelOptions, cacheDeps);
    }

    // If neither babelOptions.cacheDir nor BABEL_CACHE_DIR were provided,
    // use the first cache directory registered so far.
    for (var cacheDirectory in cachesByDir) {
      return getOrCreateCache(cacheDirectory)
        .get(source, babelOptions, cacheDeps);
    }

    // Otherwise fall back to compiling without a cache.
    if (! didWarnAboutNoCache) {
      console.warn("Compiling " + babelOptions.filename +
                  " with meteor-babel without a cache");
      console.trace();
      didWarnAboutNoCache = true;
    }
  }

  return compile(source, babelOptions);
};

function compile(source, options) {
  const babelCore = require("@babel/core");
  let result = { code: source };

  const optionsCopy = util.deepClone(options);
  const { ast, plugins, presets } = optionsCopy;
  delete optionsCopy.plugins;
  delete optionsCopy.typescript;
  optionsCopy.ast = true;

  if (options.typescript) {
    precompileTypeScript(result, options);
  }

  function transform(presets) {
    optionsCopy.plugins = [{
      parserOverride: parse
    }];

    optionsCopy.presets = presets;
    optionsCopy.sourceMaps = true;
    if (result.map) {
      optionsCopy.inputSourceMap = result.map;
    }

    if (result.ast) {
      result = babelCore.transformFromAstSync(
        result.ast,
        result.code,
        optionsCopy
      );
    } else {
      result = babelCore.transformSync(result.code, optionsCopy);
    }

    if (ast === false) {
      delete result.ast;
    }
  }

  if (plugins && plugins.length > 0) {
    const presetOfPlugins = { plugins };
    transform([presetOfPlugins]);
  }

  if (presets) {
    transform(presets);
  }

  return result;
}

function precompileTypeScript(result, options) {
  const fileName = options.filename || options.sourceFileName;
  if (fileName && ! fileName.endsWith(".ts") && ! fileName.endsWith(".tsx")) {
    return;
  }

  const ts = require("typescript");
  let tsResult;
  try {
    tsResult = ts.transpileModule(result.code, {
      fileName,
      compilerOptions: {
        target: ts.ScriptTarget.ESNext,
        // Leave module syntax intact so that Babel/Reify can handle it.
        module: ts.ModuleKind.ESNext,
        // This used to be false by default, but appears to have become
        // true by default around the release of typescript@3.7. It's
        // important to disable this option because enabling it allows
        // TypeScript to use helpers like __importDefault, which are much
        // better handled by Babel/Reify later in the pipeline.
        esModuleInterop: false,
        sourceMap: true,
        inlineSources: true,
        experimentalDecorators: true,
        emitDecoratorMetadata: true,
      }
    });
  } catch (e) {
    e.message = "While compiling " + fileName + ": " + e.message;
    throw e;
  }

  result.code = tsResult.outputText.replace(
    /\/\/# sourceMappingURL=.*?(\n|$)/g,
    "$1" // preserve trailing \n characters
  );

  result.map = JSON.parse(tsResult.sourceMapText);
  if (fileName) {
    result.map.file = fileName;
    result.map.sources = [fileName];
  }
}

exports.minify = function minify(source, options) {
  // We are not compiling the code in this step, only minifying, so reify
  // is not used.
  return require("@babel/core").transformFromAst(
    parse(source),
    source,
    options || getMinifierOptions()
  );
}

function getOrCreateCache(cacheDir) {
  return cachesByDir[cacheDir] || (
    cachesByDir[cacheDir] = new Cache(compile, cacheDir)
  );
}
exports.setCacheDir = getOrCreateCache;

exports.runtime = // Legacy name; prefer installRuntime.
exports.installRuntime = function installRuntime() {
  return require("./runtime.js");
};

exports.defineHelpers = function defineHelpers() {
  return require("meteor-babel-helpers");
};
<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const resolve = require('resolve');
const version = require('./package.json').version;
const autoprefixer = require('broccoli-autoprefixer');
const BroccoliMergeTrees = require('broccoli-merge-trees');
const writeFile = require('broccoli-file-creator');
const Funnel = require('broccoli-funnel');
const AngularScssFilter = require('./lib/angular-scss-filter');
const fastbootTransform = require('fastboot-transform');
const sass = require('node-sass');

module.exports = {
  name: 'ember-paper',

  included() {
    this._super.included.apply(this, arguments);
    let app;

    // If the addon has the _findHost() method (in ember-cli >= 2.7.0), we'll just
    // use that.
    if (typeof this._findHost === 'function') {
      app = this._findHost();
    } else {
      // Otherwise, we'll use this implementation borrowed from the _findHost()
      // method in ember-cli.
      let current = this;
      do {
        app = current.app || app;
      } while (current.parent.parent && (current = current.parent));
    }

    app.import('vendor/ember-paper/register-version.js');
    app.import('vendor/hammerjs/hammer.js');
    app.import('vendor/matchmedia-polyfill/matchMedia.js');
    app.import('vendor/propagating-hammerjs/propagating.js');
  },

  config() {
    return {
      'ember-paper': {
        insertFontLinks: true
      },
      sassOptions: {
        implementation: sass
      }
    };
  },

  contentFor(type, config) {
    if (type === 'head') {
      if (config['ember-paper'].insertFontLinks) {
        return '<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">'
          + '<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">';
      }
    } else if (type === 'body-footer') {
      let response = null;
      let emberPowerSelect = this.addons.filter(function(addon) {
        return addon.name === 'ember-power-select';
      })[0];
      response = emberPowerSelect.contentFor(type, config);
      if (config.environment !== 'test' &&  !config._emberPaperContentForInvoked) {
        config._emberPaperContentForInvoked = true;
        response = `
          ${response || ''}

        `;
      }
      return response;
    }
  },

  treeForVendor(tree) {
    let trees = [];

    let versionTree = writeFile(
      'ember-paper/register-version.js',
      `Ember.libraries.register('Ember Paper', '${version}');`
    );

    let hammerJs = fastbootTransform(new Funnel(this.pathBase('hammerjs'), {
      files: ['hammer.js'],
      destDir: 'hammerjs'
    }));

    let matchMediaPolyfill = fastbootTransform(new Funnel(this.pathBase('matchmedia-polyfill'), {
      files: ['matchMedia.js'],
      destDir: 'matchmedia-polyfill'
    }));

    let propagatingHammerJs = fastbootTransform(new Funnel(this.pathBase('propagating-hammerjs'), {
      files: ['propagating.js'],
      destDir: 'propagating-hammerjs'
    }));

    trees = trees.concat([hammerJs, matchMediaPolyfill, propagatingHammerJs, versionTree]);

    if (tree) {
      trees.push(tree);
    }

    return new BroccoliMergeTrees(trees);
  },

  treeForStyles(tree) {
    let scssFiles = [
      // core styles
      'core/style/typography.scss',
      'core/style/mixins.scss',
      'core/style/variables.scss',
      'core/style/structure.scss',
      'core/style/layout.scss',
      'core/services/layout/layout.scss',

      // component styles
      'components/content/content.scss',
      'components/content/content-theme.scss',

      'components/card/card.scss',
      'components/card/card-theme.scss',

      'components/button/button.scss',
      'components/button/button-theme.scss',

      'components/checkbox/checkbox.scss',
      'components/checkbox/checkbox-theme.scss',

      'components/radioButton/radio-button.scss',
      'components/radioButton/radio-button-theme.scss',

      'components/switch/switch.scss',
      'components/switch/switch-theme.scss',

      'components/input/input.scss',
      'components/input/input-theme.scss',

      'components/list/list.scss',
      'components/list/list-theme.scss',

      'components/divider/divider.scss',
      'components/divider/divider-theme.scss',

      'components/whiteframe/whiteframe.scss',

      'components/toolbar/toolbar.scss',
      'components/toolbar/toolbar-theme.scss',

      'components/icon/icon.scss',
      'components/icon/icon-theme.scss',

      'components/slider/slider.scss',
      'components/slider/slider-theme.scss',

      'components/subheader/subheader.scss',
      'components/subheader/subheader-theme.scss',

      'components/autocomplete/autocomplete.scss',
      'components/autocomplete/autocomplete-theme.scss',

      'components/progressLinear/progress-linear.scss',
      'components/progressLinear/progress-linear-theme.scss',

      'components/progressCircular/progress-circular.scss',
      'components/progressCircular/progress-circular-theme.scss',

      'components/menu/menu.scss',
      'components/menu/menu-theme.scss',

      'components/select/select.scss',
      'components/select/select-theme.scss',

      'components/gridList/grid-list.scss',

      'components/sidenav/sidenav.scss',
      'components/sidenav/sidenav-theme.scss',

      'components/backdrop/backdrop.scss',
      'components/backdrop/backdrop-theme.scss',

      'components/dialog/dialog.scss',
      'components/dialog/dialog-theme.scss',

      'components/virtualRepeat/virtual-repeater.scss',

      'components/chips/chips.scss',
      'components/chips/chips-theme.scss',

      'components/panel/panel.scss',
      'components/panel/panel-theme.scss',

      'components/tooltip/tooltip.scss',
      'components/tooltip/tooltip-theme.scss',

      'components/toast/toast.scss',
      'components/toast/toast-theme.scss',

      'components/tabs/tabs.scss',
      'components/tabs/tabs-theme.scss',

      'components/fabSpeedDial/fabSpeedDial.scss'
    ];

    let angularScssFiles = new Funnel(this.pathBase('angular-material-source'), {
      files: scssFiles,
      srcDir: '/src',
      destDir: 'angular-material',
      annotation: 'AngularScssFunnel'
    });

    angularScssFiles = new AngularScssFilter(angularScssFiles);

    let mergedTrees = new BroccoliMergeTrees([angularScssFiles, tree], { overwrite: true });
    return this._super.treeForStyles(mergedTrees);
  },

  /*
    Rely on the `resolve` package to mimic node's resolve algorithm.
    It finds the angular-material-source module in a manner that works for npm 2.x,
    3.x, and yarn in both the addon itself and projects that depend on this addon.

    This is an edge case b/c angular-material-source does not have a main
    module we can require.resolve through node itself and similarily ember-cli
    does not have such a hack for the same reason.

    tl;dr - We want the non built scss files, and b/c this dep is only provided via
    git, we use this hack. Please change it if you read this and know a better way.
  */
  pathBase(packageName) {
    return path.dirname(resolve.sync(`${packageName}/package.json`, { basedir: __dirname }));
  },

  postprocessTree(type, tree) {
    if (type === 'all' || type === 'styles') {
      tree = autoprefixer(tree, this.app.options.autoprefixer || { browsers: ['last 2 versions'] });
    }
    return tree;
  }
};
<commit_msg>remove sass config<commit_after>'use strict';

const path = require('path');
const resolve = require('resolve');
const version = require('./package.json').version;
const autoprefixer = require('broccoli-autoprefixer');
const BroccoliMergeTrees = require('broccoli-merge-trees');
const writeFile = require('broccoli-file-creator');
const Funnel = require('broccoli-funnel');
const AngularScssFilter = require('./lib/angular-scss-filter');
const fastbootTransform = require('fastboot-transform');

module.exports = {
  name: 'ember-paper',

  included() {
    this._super.included.apply(this, arguments);
    let app;

    // If the addon has the _findHost() method (in ember-cli >= 2.7.0), we'll just
    // use that.
    if (typeof this._findHost === 'function') {
      app = this._findHost();
    } else {
      // Otherwise, we'll use this implementation borrowed from the _findHost()
      // method in ember-cli.
      let current = this;
      do {
        app = current.app || app;
      } while (current.parent.parent && (current = current.parent));
    }

    app.import('vendor/ember-paper/register-version.js');
    app.import('vendor/hammerjs/hammer.js');
    app.import('vendor/matchmedia-polyfill/matchMedia.js');
    app.import('vendor/propagating-hammerjs/propagating.js');
  },

  config() {
    return {
      'ember-paper': {
        insertFontLinks: true
      }
    };
  },

  contentFor(type, config) {
    if (type === 'head') {
      if (config['ember-paper'].insertFontLinks) {
        return '<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic">'
          + '<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">';
      }
    } else if (type === 'body-footer') {
      let response = null;
      let emberPowerSelect = this.addons.filter(function(addon) {
        return addon.name === 'ember-power-select';
      })[0];
      response = emberPowerSelect.contentFor(type, config);
      if (config.environment !== 'test' &&  !config._emberPaperContentForInvoked) {
        config._emberPaperContentForInvoked = true;
        response = `
          ${response || ''}

        `;
      }
      return response;
    }
  },

  treeForVendor(tree) {
    let trees = [];

    let versionTree = writeFile(
      'ember-paper/register-version.js',
      `Ember.libraries.register('Ember Paper', '${version}');`
    );

    let hammerJs = fastbootTransform(new Funnel(this.pathBase('hammerjs'), {
      files: ['hammer.js'],
      destDir: 'hammerjs'
    }));

    let matchMediaPolyfill = fastbootTransform(new Funnel(this.pathBase('matchmedia-polyfill'), {
      files: ['matchMedia.js'],
      destDir: 'matchmedia-polyfill'
    }));

    let propagatingHammerJs = fastbootTransform(new Funnel(this.pathBase('propagating-hammerjs'), {
      files: ['propagating.js'],
      destDir: 'propagating-hammerjs'
    }));

    trees = trees.concat([hammerJs, matchMediaPolyfill, propagatingHammerJs, versionTree]);

    if (tree) {
      trees.push(tree);
    }

    return new BroccoliMergeTrees(trees);
  },

  treeForStyles(tree) {
    let scssFiles = [
      // core styles
      'core/style/typography.scss',
      'core/style/mixins.scss',
      'core/style/variables.scss',
      'core/style/structure.scss',
      'core/style/layout.scss',
      'core/services/layout/layout.scss',

      // component styles
      'components/content/content.scss',
      'components/content/content-theme.scss',

      'components/card/card.scss',
      'components/card/card-theme.scss',

      'components/button/button.scss',
      'components/button/button-theme.scss',

      'components/checkbox/checkbox.scss',
      'components/checkbox/checkbox-theme.scss',

      'components/radioButton/radio-button.scss',
      'components/radioButton/radio-button-theme.scss',

      'components/switch/switch.scss',
      'components/switch/switch-theme.scss',

      'components/input/input.scss',
      'components/input/input-theme.scss',

      'components/list/list.scss',
      'components/list/list-theme.scss',

      'components/divider/divider.scss',
      'components/divider/divider-theme.scss',

      'components/whiteframe/whiteframe.scss',

      'components/toolbar/toolbar.scss',
      'components/toolbar/toolbar-theme.scss',

      'components/icon/icon.scss',
      'components/icon/icon-theme.scss',

      'components/slider/slider.scss',
      'components/slider/slider-theme.scss',

      'components/subheader/subheader.scss',
      'components/subheader/subheader-theme.scss',

      'components/autocomplete/autocomplete.scss',
      'components/autocomplete/autocomplete-theme.scss',

      'components/progressLinear/progress-linear.scss',
      'components/progressLinear/progress-linear-theme.scss',

      'components/progressCircular/progress-circular.scss',
      'components/progressCircular/progress-circular-theme.scss',

      'components/menu/menu.scss',
      'components/menu/menu-theme.scss',

      'components/select/select.scss',
      'components/select/select-theme.scss',

      'components/gridList/grid-list.scss',

      'components/sidenav/sidenav.scss',
      'components/sidenav/sidenav-theme.scss',

      'components/backdrop/backdrop.scss',
      'components/backdrop/backdrop-theme.scss',

      'components/dialog/dialog.scss',
      'components/dialog/dialog-theme.scss',

      'components/virtualRepeat/virtual-repeater.scss',

      'components/chips/chips.scss',
      'components/chips/chips-theme.scss',

      'components/panel/panel.scss',
      'components/panel/panel-theme.scss',

      'components/tooltip/tooltip.scss',
      'components/tooltip/tooltip-theme.scss',

      'components/toast/toast.scss',
      'components/toast/toast-theme.scss',

      'components/tabs/tabs.scss',
      'components/tabs/tabs-theme.scss',

      'components/fabSpeedDial/fabSpeedDial.scss'
    ];

    let angularScssFiles = new Funnel(this.pathBase('angular-material-source'), {
      files: scssFiles,
      srcDir: '/src',
      destDir: 'angular-material',
      annotation: 'AngularScssFunnel'
    });

    angularScssFiles = new AngularScssFilter(angularScssFiles);

    let mergedTrees = new BroccoliMergeTrees([angularScssFiles, tree], { overwrite: true });
    return this._super.treeForStyles(mergedTrees);
  },

  /*
    Rely on the `resolve` package to mimic node's resolve algorithm.
    It finds the angular-material-source module in a manner that works for npm 2.x,
    3.x, and yarn in both the addon itself and projects that depend on this addon.

    This is an edge case b/c angular-material-source does not have a main
    module we can require.resolve through node itself and similarily ember-cli
    does not have such a hack for the same reason.

    tl;dr - We want the non built scss files, and b/c this dep is only provided via
    git, we use this hack. Please change it if you read this and know a better way.
  */
  pathBase(packageName) {
    return path.dirname(resolve.sync(`${packageName}/package.json`, { basedir: __dirname }));
  },

  postprocessTree(type, tree) {
    if (type === 'all' || type === 'styles') {
      tree = autoprefixer(tree, this.app.options.autoprefixer || { browsers: ['last 2 versions'] });
    }
    return tree;
  }
};
<|endoftext|>


<commit_before>var httpProxy = require('http-proxy');
var http = require('http');

var CORS_HEADERS = {
  'access-control-allow-origin': '*',
  'access-control-allow-methods': 'HEAD, POST, GET, PUT, PATCH, DELETE',
  'access-control-max-age': '86400',
  'access-control-allow-headers': "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Authorization"
};

// Create a proxy server pointing at spreadsheets.google.com.
//var proxy = httpProxy.createProxyServer({target: 'https://spreadsheets.google.com'});
var proxy = httpProxy.createProxyServer();

https.createServer(function(req, res) {
  if (req.method === 'OPTIONS') {
    // Respond to OPTIONS requests advertising we support full CORS for *
    res.writeHead(200, CORS_HEADERS);
    res.end();
    return
  }
  // Remove our original host so it doesn't mess up Google's header parsing.
  delete req.headers.host;
  proxy.web(req, res, {
    target: 'https://spreadsheets.google.com:443',
    xfwd: false
  });
  // Add CORS headers to every other request also.
  proxy.on('proxyRes', function(proxyRes, req, res) {
    for (var key in CORS_HEADERS) {
      proxyRes.headers[key] = CORS_HEADERS[key];
    }
  });
}).listen(process.env.PORT || 5000);
<commit_msg>https -> http<commit_after>var httpProxy = require('http-proxy');
var http = require('http');

var CORS_HEADERS = {
  'access-control-allow-origin': '*',
  'access-control-allow-methods': 'HEAD, POST, GET, PUT, PATCH, DELETE',
  'access-control-max-age': '86400',
  'access-control-allow-headers': "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Authorization"
};

// Create a proxy server pointing at spreadsheets.google.com.
//var proxy = httpProxy.createProxyServer({target: 'https://spreadsheets.google.com'});
var proxy = httpProxy.createProxyServer();

http.createServer(function(req, res) {
  if (req.method === 'OPTIONS') {
    // Respond to OPTIONS requests advertising we support full CORS for *
    res.writeHead(200, CORS_HEADERS);
    res.end();
    return
  }
  // Remove our original host so it doesn't mess up Google's header parsing.
  delete req.headers.host;
  proxy.web(req, res, {
    target: 'https://spreadsheets.google.com:443',
    xfwd: false
  });
  // Add CORS headers to every other request also.
  proxy.on('proxyRes', function(proxyRes, req, res) {
    for (var key in CORS_HEADERS) {
      proxyRes.headers[key] = CORS_HEADERS[key];
    }
  });
}).listen(process.env.PORT || 5000);
<|endoftext|>


<commit_before>'use strict';
const path = require('path');
const through2 = require('through2');
const gutil = require('gulp-util');
const groupBy = require('lodash.groupby');
const PQueue = require('p-queue');
const commandRunner = require('./lib/command-runner');

const commands = {
  tsd: ['reinstall', '--save'],
  bower: ['install', '--config.interactive=false'],
  npm: ['install'],
  pip: ['install', '-r', 'requirements.txt'],
  composer: ['install'],
};

const fileToCommand = {
  'tsd.json': 'tsd',
  'bower.json': 'bower',
  'package.json': 'npm',
  'requirements.txt': 'pip',
  'composer.json': 'composer',
};

module.exports = function (opts = {}) {
  const toRun = [];

  return through2(
    {objectMode: true},
    function (file, enc, cb) {
      if (!file.path) {
        return cb();
      }
      if (fileToCommand[path.basename(file.path)]) {
        const cmd = {
          cmd: fileToCommand[path.basename(file.path)],
          args: (commands[fileToCommand[path.basename(file.path)]] || []).slice()
        };

        if (['bower', 'npm'].includes(cmd.cmd) && opts.production) {
          cmd.args.push('--production');
        }
        if (cmd.cmd === 'npm' && opts.ignoreScripts) {
          cmd.args.push('--ignore-scripts');
        }
        if (opts.args) {
          cmd.args = cmd.args.concat(opts.args).map(arg => arg.toString());
        }
        if (cmd.cmd === 'bower' && opts.allowRoot) {
          cmd.args.push('--allow-root');
        }
        if (cmd.cmd === 'npm' && opts.noOptional) {
          cmd.args.push('--no-optional');
        }

        cmd.cwd = path.dirname(file.path);
        toRun.push(cmd);
      }
      this.push(file);
      cb();
    },
    cb => {
      if (toRun.length === 0) {
        return cb();
      }
      if (skipInstall()) {
        log('Skipping install.', 'Run `' + gutil.colors.yellow(formatCommands(toRun)) + '` manually');
        return cb();
      }
      const groupedCommands = groupBy(toRun, 'cmd');
      Promise.all(Object.keys(groupedCommands).map(cmd => {
        const commands = groupedCommands[cmd];
        const queue = new PQueue({concurrency: 1});
        return Promise.all(commands.map(command => queue.add(() => logFailure(command)(commandRunner.run(command)))));
      }))
      .then(() => cb(), cb); // eslint-disable-line promise/no-callback-in-promise
    }
  );
};

function logFailure(command) {
  return promise => {
    return promise.catch(err => {
      log(err.message, ', run `' + gutil.colors.yellow(formatCommand(command)) + '` manually');
      throw err;
    });
  };
}

function log(...args) {
  if (isTest()) {
    return;
  }
  gutil.log(...args);
}

function formatCommands(cmds) {
  return cmds.map(formatCommand).join(' && ');
}

function formatCommand(command) {
  return command.cmd + ' ' + command.args.join(' ');
}

function skipInstall() {
  return process.argv.slice(2).includes('--skip-install');
}

function isTest() {
  return process.env.NODE_ENV === 'test';
}
<commit_msg>fix: add support for Typings (fixes #37)<commit_after>'use strict';
const path = require('path');
const through2 = require('through2');
const gutil = require('gulp-util');
const groupBy = require('lodash.groupby');
const PQueue = require('p-queue');
const commandRunner = require('./lib/command-runner');

const commands = {
  tsd: ['reinstall', '--save'],
  bower: ['install', '--config.interactive=false'],
  npm: ['install'],
  pip: ['install', '-r', 'requirements.txt'],
  composer: ['install'],
  typings: ['install']
};

const fileToCommand = {
  'tsd.json': 'tsd',
  'bower.json': 'bower',
  'package.json': 'npm',
  'requirements.txt': 'pip',
  'composer.json': 'composer',
  'typings.json': 'typings'
};

module.exports = function (opts = {}) {
  const toRun = [];

  return through2(
    {objectMode: true},
    function (file, enc, cb) {
      if (!file.path) {
        return cb();
      }
      if (fileToCommand[path.basename(file.path)]) {
        const cmd = {
          cmd: fileToCommand[path.basename(file.path)],
          args: (commands[fileToCommand[path.basename(file.path)]] || []).slice()
        };

        if (['bower', 'npm'].includes(cmd.cmd) && opts.production) {
          cmd.args.push('--production');
        }
        if (cmd.cmd === 'npm' && opts.ignoreScripts) {
          cmd.args.push('--ignore-scripts');
        }
        if (opts.args) {
          cmd.args = cmd.args.concat(opts.args).map(arg => arg.toString());
        }
        if (cmd.cmd === 'bower' && opts.allowRoot) {
          cmd.args.push('--allow-root');
        }
        if (cmd.cmd === 'npm' && opts.noOptional) {
          cmd.args.push('--no-optional');
        }

        cmd.cwd = path.dirname(file.path);
        toRun.push(cmd);
      }
      this.push(file);
      cb();
    },
    cb => {
      if (toRun.length === 0) {
        return cb();
      }
      if (skipInstall()) {
        log('Skipping install.', 'Run `' + gutil.colors.yellow(formatCommands(toRun)) + '` manually');
        return cb();
      }
      const groupedCommands = groupBy(toRun, 'cmd');
      Promise.all(Object.keys(groupedCommands).map(cmd => {
        const commands = groupedCommands[cmd];
        const queue = new PQueue({concurrency: 1});
        return Promise.all(commands.map(command => queue.add(() => logFailure(command)(commandRunner.run(command)))));
      }))
      .then(() => cb(), cb); // eslint-disable-line promise/no-callback-in-promise
    }
  );
};

function logFailure(command) {
  return promise => {
    return promise.catch(err => {
      log(err.message, ', run `' + gutil.colors.yellow(formatCommand(command)) + '` manually');
      throw err;
    });
  };
}

function log(...args) {
  if (isTest()) {
    return;
  }
  gutil.log(...args);
}

function formatCommands(cmds) {
  return cmds.map(formatCommand).join(' && ');
}

function formatCommand(command) {
  return command.cmd + ' ' + command.args.join(' ');
}

function skipInstall() {
  return process.argv.slice(2).includes('--skip-install');
}

function isTest() {
  return process.env.NODE_ENV === 'test';
}
<|endoftext|>