<commit_before>'use strict';
// ======================================================================================
// graceful-shutdown.js
// ======================================================================================
// gracefully shuts downs http server
// can be used with http, express, koa, ...
// ======================================================================================

const debug = require('debug')('http-graceful-shutdown');

let isShuttingDown = false;
let connections = {};
let connectionCounter = 0;
let failed = false;

/**
 * Gracefully shuts down `server` when the process receives
 * the passed signals
 *
 * @param {http.Server} server
 * @param {object} opts
 *                        signals: string (each signal separated by SPACE)
 *                        timeout: timeout value for forceful shutdown in ms
 *                        development: boolean value (if true, no graceful shutdown to speed up development
 *                        onShutdown: optional function
 *                        finally: optional function
 */

function GracefulShutdown(server, opts) {

  opts = opts || {};

  // merge opts with default options
  let options = Object.assign({
    signals: 'SIGINT SIGTERM',
    timeout: 30000,
    development: false
  }, opts);

  options.signals.split(' ').forEach(function (signal) {
    if (signal && signal !== '') {
      process.on(signal, function () {
        shutdown(signal);
      });
    }
  });

  function destroy(socket) {
    if (socket._isIdle && isShuttingDown) {
      socket.destroy();
      delete connections[socket._connectionId];
    }
  }

  function isFunction(functionToCheck) {
    let getType = Object.prototype.toString.call(functionToCheck);
    return /^\[object\s([a-zA-Z]+)?Function\]$/.test(getType);
  }

  server.on('request', function (req, res) {
    req.socket._isIdle = false;

    res.on('finish', function () {
      req.socket._isIdle = true;
      destroy(req.socket);
    });
  });

  server.on('connection', function (socket) {
    let id = connectionCounter++;
    socket._isIdle = true;
    socket._connectionId = id;
    connections[id] = socket;

    socket.on('close', function () {
      delete connections[id];
    });
  });

  process.on('exit', function () {
    if (options.finally && isFunction(options.finally)) {
      options.finally();
    }
    debug('closed');
  });

  function shutdown(sig) {

    return new Promise((resolve, reject) => {

      let counter = 0;

      function cleanupHttp() {

        return new Promise((resolve, reject) => {
          Object.keys(connections).forEach(function (key) {
            counter++;
            destroy(connections[key]);
          });

          debug('Connections destroyed : ' + counter);
          debug('Connection Counter    : ' + connectionCounter);

          // normal shutdown
          server.close(function (err) {
            if (err) return reject(err);
            resolve();
          });
        });

      }

      debug('shutdown signal - ' + sig);

      // Don't bother with graceful shutdown on development to speed up round trip
      if (options.development) {
        debug('DEV-Mode - imediate forceful shutdown');
        return process.exit(0);
      }

      const finalHandler = () => {
        resolve();
        process.nextTick(() => {
          process.exit(failed ? 1 : 0);
        });
      };

      const exitHandler = promise => promise
        .catch((err) => {
          const errString = (typeof err === 'string') ? err : JSON.stringify(err);
          debug(errString);
          failed = true;
          reject(errString);
        });

      if (!isShuttingDown) {
        isShuttingDown = true;
        debug('shutting down');

        // forcefull shutdown after timeout
        if (options.timeout) {
          setTimeout(function () {
            debug('Could not close connections in time (' + options.timeout + 'ms), forcefully shutting down');
            resolve();
            process.nextTick(() => {
              process.exit(1);
            });

          }, options.timeout).unref();
        }

        exitHandler(cleanupHttp()).then(() => {
          if (options.onShutdown && isFunction(options.onShutdown)) {
            return exitHandler(options.onShutdown(sig));
          }
          return;
        }).then(finalHandler);
      }
    });
  }

  function shutdownManual() {
    return shutdown('manual');
  }

  return shutdownManual;
}

module.exports = GracefulShutdown;
<commit_msg>moved finally before promise resolve<commit_after>'use strict';
// ======================================================================================
// graceful-shutdown.js
// ======================================================================================
// gracefully shuts downs http server
// can be used with http, express, koa, ...
// ======================================================================================

const debug = require('debug')('http-graceful-shutdown');

let isShuttingDown = false;
let connections = {};
let connectionCounter = 0;
let failed = false;

/**
 * Gracefully shuts down `server` when the process receives
 * the passed signals
 *
 * @param {http.Server} server
 * @param {object} opts
 *                        signals: string (each signal separated by SPACE)
 *                        timeout: timeout value for forceful shutdown in ms
 *                        development: boolean value (if true, no graceful shutdown to speed up development
 *                        onShutdown: optional function
 *                        finally: optional function
 */

function GracefulShutdown(server, opts) {

  opts = opts || {};

  // merge opts with default options
  let options = Object.assign({
    signals: 'SIGINT SIGTERM',
    timeout: 30000,
    development: false
  }, opts);

  options.signals.split(' ').forEach(function (signal) {
    if (signal && signal !== '') {
      process.on(signal, function () {
        shutdown(signal);
      });
    }
  });

  function destroy(socket) {
    if (socket._isIdle && isShuttingDown) {
      socket.destroy();
      delete connections[socket._connectionId];
    }
  }

  function isFunction(functionToCheck) {
    let getType = Object.prototype.toString.call(functionToCheck);
    return /^\[object\s([a-zA-Z]+)?Function\]$/.test(getType);
  }

  server.on('request', function (req, res) {
    req.socket._isIdle = false;

    res.on('finish', function () {
      req.socket._isIdle = true;
      destroy(req.socket);
    });
  });

  server.on('connection', function (socket) {
    let id = connectionCounter++;
    socket._isIdle = true;
    socket._connectionId = id;
    connections[id] = socket;

    socket.on('close', function () {
      delete connections[id];
    });
  });

  process.on('exit', function () {
    debug('closed');
  });

  function shutdown(sig) {

    return new Promise((resolve, reject) => {

      let counter = 0;

      function cleanupHttp() {

        return new Promise((resolve, reject) => {
          Object.keys(connections).forEach(function (key) {
            counter++;
            destroy(connections[key]);
          });

          debug('Connections destroyed : ' + counter);
          debug('Connection Counter    : ' + connectionCounter);

          // normal shutdown
          server.close(function (err) {
            if (err) return reject(err);
            resolve();
          });
        });

      }

      debug('shutdown signal - ' + sig);

      // Don't bother with graceful shutdown on development to speed up round trip
      if (options.development) {
        debug('DEV-Mode - imediate forceful shutdown');
        return process.exit(0);
      }

      const finalHandler = () => {
        if (options.finally && isFunction(options.finally)) {
          options.finally();
        }
        resolve();
        process.nextTick(() => {
          process.exit(failed ? 1 : 0);
        });
      };

      const exitHandler = promise => promise
        .catch((err) => {
          const errString = (typeof err === 'string') ? err : JSON.stringify(err);
          debug(errString);
          failed = true;
          reject(errString);
        });

      if (!isShuttingDown) {
        isShuttingDown = true;
        debug('shutting down');

        // forcefull shutdown after timeout
        if (options.timeout) {
          setTimeout(function () {
            debug('Could not close connections in time (' + options.timeout + 'ms), forcefully shutting down');
            if (options.finally && isFunction(options.finally)) {
              options.finally();
            }
            resolve();
            process.nextTick(() => {
              process.exit(1);
            });

          }, options.timeout).unref();
        }

        exitHandler(cleanupHttp()).then(() => {
          if (options.onShutdown && isFunction(options.onShutdown)) {
            return exitHandler(options.onShutdown(sig));
          }
          return;
        }).then(finalHandler);
      }
    });
  }

  function shutdownManual() {
    return shutdown('manual');
  }

  return shutdownManual;
}

module.exports = GracefulShutdown;
<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');
var mockery = require('mockery');
var path = require('path');
var assert = require('yeoman-assert');
var helpers = require('yeoman-generator').test;
var fs = require('fs');

function assertObjectContains(obj, content) {
  Object.keys(content).forEach(function (key) {
    if (typeof content[key] === 'object') {
      assertObjectContains(content[key], obj[key]);
      return;
    }

    assert.equal(content[key], obj[key]);
  });
}

function assertJSONFileContains(filename, content) {
  var obj = JSON.parse(fs.readFileSync(filename, 'utf8'));
  assertObjectContains(obj, content);
}

describe('node:app', function () {
  before(function () {
    mockery.enable({warnOnUnregistered: false});

    mockery.registerMock('npm-name', function (name, cb) {
      cb(null, true);
    });

    mockery.registerMock(
      require.resolve('generator-license/app'),
      helpers.createDummyGenerator()
    );
  });

  after(function () {
    mockery.disable();
  });

  describe('running on new project', function () {
    before(function (done) {
      this.answers = {
        name: 'generator-node',
        description: 'A node generator',
        homepage: 'http://yeoman.io',
        githubAccount: 'yeoman',
        authorName: 'The Yeoman Team',
        authorEmail: 'hi@yeoman.io',
        authorUrl: 'http://yeoman.io',
        keywords: ['foo', 'bar']
      };
      helpers.run(path.join(__dirname, '../generators/app'))
        .withPrompts(this.answers)
        .on('end', done);
    });

    it('creates files', function () {
      assert.file([
        '.travis.yml',
        '.editorconfig',
        '.eslintrc',
        '.gitignore',
        '.gitattributes',
        'README.md',
        'lib/index.js',
        'test/index.js'
      ]);
    });

    it('creates package.json', function () {
      assert.file('package.json');
      assertJSONFileContains('package.json', {
        name: 'generator-node',
        version: '0.0.0',
        description: this.answers.description,
        homepage: this.answers.homepage,
        repository: 'yeoman/generator-node',
        author: {
          name: this.answers.authorName,
          email: this.answers.authorEmail,
          url: this.answers.authorUrl
        },
        files: ['dist'],
        keywords: this.answers.keywords,
        main: 'dist/index.js'
      });
    });

    it('creates and fill contents in README.md', function () {
      assert.file('README.md');
      assert.fileContent('README.md', 'var generatorNode = require(\'generator-node\');');
      assert.fileContent('README.md', '> A node generator');
      assert.fileContent('README.md', '$ npm install --save generator-node');
      assert.fileContent('README.md', '© [The Yeoman Team](http://yeoman.io)');
      assert.fileContent('README.md', '[travis-image]: https://travis-ci.org/yeoman/generator-node.svg?branch=master');
      assert.fileContent('README.md', 'coveralls');
    });
  });

  describe('running on existing project', function () {
    before(function (done) {
      this.pkg = {
        version: '1.0.34',
        description: 'lots of fun',
        homepage: 'http://yeoman.io',
        repository: 'yeoman/generator-node',
        author: 'The Yeoman Team',
        files: ['lib'],
        keywords: ['bar']
      };
      helpers.run(path.join(__dirname, '../generators/app'))
        .withPrompts({
          name: 'generator-node'
        })
        .on('ready', function (gen) {
          gen.fs.writeJSON(gen.destinationPath('package.json'), this.pkg);
          gen.fs.write(gen.destinationPath('README.md'), 'foo');
        }.bind(this))
        .on('end', done);
    });

    it('extends package.json keys with missing ones', function () {
      var pkg = _.extend({name: 'generator-node'}, this.pkg);
      assertJSONFileContains('package.json', pkg);
    });

    it('does not overwrite previous README.md', function () {
      assert.fileContent('README.md', 'foo');
    });
  });

  describe('--no-travis', function () {
    before(function (done) {
      helpers.run(path.join(__dirname, '../generators/app'))
        .withOptions({travis: false})
        .on('end', done);
    });

    it('skip .travis.yml', function () {
      assert.noFile('.travis.yml');
    });
  });

  describe('--no-babel', function () {
    before(function (done) {
      helpers.run(path.join(__dirname, '../generators/app'))
        .withOptions({babel: false})
        .on('end', done);
    });

    it('skip .bablerc', function () {
      assert.noFile('.babelrc');
    });

    it('include the raw files', function () {
      assertJSONFileContains('package.json', {
        files: ['lib'],
        main: 'lib/index.js'
      });
    });
  });
});
<commit_msg>Update to the new yeoman-assert methods<commit_after>'use strict';
var _ = require('lodash');
var mockery = require('mockery');
var path = require('path');
var assert = require('yeoman-assert');
var helpers = require('yeoman-generator').test;
var fs = require('fs');

describe('node:app', function () {
  before(function () {
    mockery.enable({warnOnUnregistered: false});

    mockery.registerMock('npm-name', function (name, cb) {
      cb(null, true);
    });

    mockery.registerMock(
      require.resolve('generator-license/app'),
      helpers.createDummyGenerator()
    );
  });

  after(function () {
    mockery.disable();
  });

  describe('running on new project', function () {
    before(function (done) {
      this.answers = {
        name: 'generator-node',
        description: 'A node generator',
        homepage: 'http://yeoman.io',
        githubAccount: 'yeoman',
        authorName: 'The Yeoman Team',
        authorEmail: 'hi@yeoman.io',
        authorUrl: 'http://yeoman.io',
        keywords: ['foo', 'bar']
      };
      helpers.run(path.join(__dirname, '../generators/app'))
        .withPrompts(this.answers)
        .on('end', done);
    });

    it('creates files', function () {
      assert.file([
        '.travis.yml',
        '.editorconfig',
        '.eslintrc',
        '.gitignore',
        '.gitattributes',
        'README.md',
        'lib/index.js',
        'test/index.js'
      ]);
    });

    it('creates package.json', function () {
      assert.file('package.json');
      assert.JSONFileContent('package.json', {
        name: 'generator-node',
        version: '0.0.0',
        description: this.answers.description,
        homepage: this.answers.homepage,
        repository: 'yeoman/generator-node',
        author: {
          name: this.answers.authorName,
          email: this.answers.authorEmail,
          url: this.answers.authorUrl
        },
        files: ['dist'],
        keywords: this.answers.keywords,
        main: 'dist/index.js'
      });
    });

    it('creates and fill contents in README.md', function () {
      assert.file('README.md');
      assert.fileContent('README.md', 'var generatorNode = require(\'generator-node\');');
      assert.fileContent('README.md', '> A node generator');
      assert.fileContent('README.md', '$ npm install --save generator-node');
      assert.fileContent('README.md', '© [The Yeoman Team](http://yeoman.io)');
      assert.fileContent('README.md', '[travis-image]: https://travis-ci.org/yeoman/generator-node.svg?branch=master');
      assert.fileContent('README.md', 'coveralls');
    });
  });

  describe('running on existing project', function () {
    before(function (done) {
      this.pkg = {
        version: '1.0.34',
        description: 'lots of fun',
        homepage: 'http://yeoman.io',
        repository: 'yeoman/generator-node',
        author: 'The Yeoman Team',
        files: ['lib'],
        keywords: ['bar']
      };
      helpers.run(path.join(__dirname, '../generators/app'))
        .withPrompts({
          name: 'generator-node'
        })
        .on('ready', function (gen) {
          gen.fs.writeJSON(gen.destinationPath('package.json'), this.pkg);
          gen.fs.write(gen.destinationPath('README.md'), 'foo');
        }.bind(this))
        .on('end', done);
    });

    it('extends package.json keys with missing ones', function () {
      var pkg = _.extend({name: 'generator-node'}, this.pkg);
      assert.JSONFileContent('package.json', pkg);
    });

    it('does not overwrite previous README.md', function () {
      assert.fileContent('README.md', 'foo');
    });
  });

  describe('--no-travis', function () {
    before(function (done) {
      helpers.run(path.join(__dirname, '../generators/app'))
        .withOptions({travis: false})
        .on('end', done);
    });

    it('skip .travis.yml', function () {
      assert.noFile('.travis.yml');
    });
  });

  describe('--no-babel', function () {
    before(function (done) {
      helpers.run(path.join(__dirname, '../generators/app'))
        .withOptions({babel: false})
        .on('end', done);
    });

    it('skip .bablerc', function () {
      assert.noFile('.babelrc');
    });

    it('include the raw files', function () {
      assert.JSONFileContent('package.json', {
        files: ['lib'],
        main: 'lib/index.js'
      });
    });
  });
});
<|endoftext|>


<commit_before>const async = require('async');
const AccountParser = require('../../utils/accountParser');
const fundAccount = require('./fundAccount');
const constants = require('../../constants');
const Transaction = require('ethereumjs-tx');
const ethUtil = require('ethereumjs-util');

class Provider {
  constructor(options) {
    this.web3 = options.web3;
    this.accountsConfig = options.accountsConfig;
    this.blockchainConfig = options.blockchainConfig;
    this.type = options.type;
    this.web3Endpoint = options.web3Endpoint;
    this.logger = options.logger;
    this.isDev = options.isDev;
    this.nonceCache = {};
  }

  getNonce(address, callback) {
    this.web3.eth.getTransactionCount(address, (_error, transactionCount) => {
      if(!this.nonceCache[address]) {
        this.nonceCache[address] = -1;
      }

      if (transactionCount > this.nonceCache[address]) {
        this.nonceCache[address] = transactionCount;
        return callback(this.nonceCache[address]);
      }

      this.nonceCache[address]++;
      callback(this.nonceCache[address]);
    });
  }

  startWeb3Provider(callback) {
    const self = this;

    if (this.type === 'rpc') {
      self.provider = new this.web3.providers.HttpProvider(self.web3Endpoint);
    } else if (this.type === 'ws') {
    // Note: don't pass to the provider things like {headers: {Origin: "embark"}}. Origin header is for browser to fill
    // to protect user, it has no meaning if it is used server-side. See here for more details: https://github.com/ethereum/go-ethereum/issues/16608
    // Moreover, Parity reject origins that are not urls so if you try to connect with Origin: "embark" it gives the following error:
    // << Blocked connection to WebSockets server from untrusted origin: Some("embark") >>
    // The best choice is to use void origin, BUT Geth rejects void origin, so to keep both clients happy we can use http://embark
      self.provider = new this.web3.providers.WebsocketProvider(self.web3Endpoint, {headers: {Origin: constants.embarkResourceOrigin}});

      self.provider.on('error', () => self.logger.error('Websocket Error'));
      self.provider.on('end', () => self.logger.error('Websocket connection ended'));
    } else {
      return callback(__("contracts config error: unknown deployment type %s", this.type));
    }
    self.web3.setProvider(self.provider);

    self.web3.eth.getAccounts((err, accounts = []) => {
      if (err) {
        self.logger.warn('Error while getting the node\'s accounts.', err.message || err);
      }

      self.blockchainAccounts = AccountParser.parseAccountsConfig(self.blockchainConfig.accounts, self.web3, self.logger, accounts);

      accounts = accounts.concat(self.blockchainAccounts);

      self.accounts = AccountParser.parseAccountsConfig(self.accountsConfig, self.web3, self.logger, accounts);

      if (!self.accounts.length) {
        self.accounts = accounts;
      }
      self.addresses = [];

      self.accounts.forEach(account => {
        self.addresses.push(account.address || account);
        if (account.privateKey) {
          self.web3.eth.accounts.wallet.add(account);
        }
      });
      self.addresses = [...new Set(self.addresses)]; // Remove duplicates

      if (self.accounts.length) {
        self.web3.eth.defaultAccount = self.addresses[0];
      }

      const realSend = self.provider.send.bind(self.provider);

      // Allow to run transaction in parallel by resolving
      // the nonce manually.
      // For each transaction, resolve the nonce by taking the
      // max of current transaction count and the cache we keep
      // locally.
      // Deconstruct the transaction and update the nonce.
      // Before updating the transaction, it must be signed.
      self.runTransaction = async.queue(({payload}, callback) => {
        const rawTx = payload.params[0];
        const rawData = Buffer.from(ethUtil.stripHexPrefix(rawTx), 'hex');
        const tx = new Transaction(rawData, 'hex');
        const address = '0x' + tx.getSenderAddress().toString('hex').toLowerCase();

        self.getNonce(address, (newNonce) => {
          tx.nonce = newNonce;
          const key = ethUtil.stripHexPrefix(self.web3.eth.accounts.wallet[address].privateKey);
          const privKey = Buffer.from(key, 'hex');
          tx.sign(privKey);
          payload.params[0] = '0x' + tx.serialize().toString('hex');
          return realSend(payload, (error, result) => {
            self.web3.eth.getTransaction(result.result, () => {
              callback(error, result);
            });
          });
        });
      }, 1);

      self.provider.send = function(payload, cb) {
        if (payload.method === 'eth_accounts') {
          return realSend(payload, function(err, result) {
            if (err) {
              return cb(err);
            }
            if (self.accounts.length) {
              result.result = self.addresses; // Send our addresses
            }
            cb(null, result);
          });
        } else if (payload.method === constants.blockchain.transactionMethods.eth_sendRawTransaction) {
          return self.runTransaction.push({payload}, cb);
        }

        realSend(payload, cb);
      };
      callback();
    });
  }

  connected() {
    if (this.type === 'rpc') {
      return !!this.provider;
    } else if (this.type === 'ws') {
      return this.provider && this.provider.connection._connection && this.provider.connection._connection.connected;
    }

    return false;
  }

  stop() {
    if (this.provider && this.provider.removeAllListeners) {
      this.provider.removeAllListeners('connect');
      this.provider.removeAllListeners('error');
      this.provider.removeAllListeners('end');
      this.provider.removeAllListeners('data');
      this.provider.responseCallbacks = {};
    }
    this.provider = null;
    this.web3.setProvider(null);
  }

  fundAccounts(callback) {
    const self = this;
    if (!self.accounts.length) {
      return callback();
    }
    if (!self.isDev) {
      return callback();
    }
    async.eachLimit(self.accounts, 1, (account, eachCb) => {
      if (!account.address) {
        return eachCb();
      }
      fundAccount(self.web3, account.address, account.hexBalance, eachCb);
    }, callback);
  }
}

module.exports = Provider;
<commit_msg>fix(ws): up fragmentation threshold to patch Geth bug with WS<commit_after>const async = require('async');
const AccountParser = require('../../utils/accountParser');
const fundAccount = require('./fundAccount');
const constants = require('../../constants');
const Transaction = require('ethereumjs-tx');
const ethUtil = require('ethereumjs-util');

class Provider {
  constructor(options) {
    this.web3 = options.web3;
    this.accountsConfig = options.accountsConfig;
    this.blockchainConfig = options.blockchainConfig;
    this.type = options.type;
    this.web3Endpoint = options.web3Endpoint;
    this.logger = options.logger;
    this.isDev = options.isDev;
    this.nonceCache = {};
  }

  getNonce(address, callback) {
    this.web3.eth.getTransactionCount(address, (_error, transactionCount) => {
      if(!this.nonceCache[address]) {
        this.nonceCache[address] = -1;
      }

      if (transactionCount > this.nonceCache[address]) {
        this.nonceCache[address] = transactionCount;
        return callback(this.nonceCache[address]);
      }

      this.nonceCache[address]++;
      callback(this.nonceCache[address]);
    });
  }

  startWeb3Provider(callback) {
    const self = this;

    if (this.type === 'rpc') {
      self.provider = new this.web3.providers.HttpProvider(self.web3Endpoint);
    } else if (this.type === 'ws') {
    // Note: don't pass to the provider things like {headers: {Origin: "embark"}}. Origin header is for browser to fill
    // to protect user, it has no meaning if it is used server-side. See here for more details: https://github.com/ethereum/go-ethereum/issues/16608
    // Moreover, Parity reject origins that are not urls so if you try to connect with Origin: "embark" it gives the following error:
    // << Blocked connection to WebSockets server from untrusted origin: Some("embark") >>
      // The best choice is to use void origin, BUT Geth rejects void origin, so to keep both clients happy we can use http://embark
      self.provider = new this.web3.providers.WebsocketProvider(self.web3Endpoint, {
        headers: {Origin: constants.embarkResourceOrigin},
        // TODO remove this when Geth fixes this: https://github.com/ethereum/go-ethereum/issues/16846
        clientConfig: {
          fragmentationThreshold: 81920
        }
      });

      self.provider.on('error', () => self.logger.error('Websocket Error'));
      self.provider.on('end', () => self.logger.error('Websocket connection ended'));
    } else {
      return callback(__("contracts config error: unknown deployment type %s", this.type));
    }
    self.web3.setProvider(self.provider);

    self.web3.eth.getAccounts((err, accounts = []) => {
      if (err) {
        self.logger.warn('Error while getting the node\'s accounts.', err.message || err);
      }

      self.blockchainAccounts = AccountParser.parseAccountsConfig(self.blockchainConfig.accounts, self.web3, self.logger, accounts);

      accounts = accounts.concat(self.blockchainAccounts);

      self.accounts = AccountParser.parseAccountsConfig(self.accountsConfig, self.web3, self.logger, accounts);

      if (!self.accounts.length) {
        self.accounts = accounts;
      }
      self.addresses = [];

      self.accounts.forEach(account => {
        self.addresses.push(account.address || account);
        if (account.privateKey) {
          self.web3.eth.accounts.wallet.add(account);
        }
      });
      self.addresses = [...new Set(self.addresses)]; // Remove duplicates

      if (self.accounts.length) {
        self.web3.eth.defaultAccount = self.addresses[0];
      }

      const realSend = self.provider.send.bind(self.provider);

      // Allow to run transaction in parallel by resolving
      // the nonce manually.
      // For each transaction, resolve the nonce by taking the
      // max of current transaction count and the cache we keep
      // locally.
      // Deconstruct the transaction and update the nonce.
      // Before updating the transaction, it must be signed.
      self.runTransaction = async.queue(({payload}, callback) => {
        const rawTx = payload.params[0];
        const rawData = Buffer.from(ethUtil.stripHexPrefix(rawTx), 'hex');
        const tx = new Transaction(rawData, 'hex');
        const address = '0x' + tx.getSenderAddress().toString('hex').toLowerCase();

        self.getNonce(address, (newNonce) => {
          tx.nonce = newNonce;
          const key = ethUtil.stripHexPrefix(self.web3.eth.accounts.wallet[address].privateKey);
          const privKey = Buffer.from(key, 'hex');
          tx.sign(privKey);
          payload.params[0] = '0x' + tx.serialize().toString('hex');
          return realSend(payload, (error, result) => {
            self.web3.eth.getTransaction(result.result, () => {
              callback(error, result);
            });
          });
        });
      }, 1);

      self.provider.send = function(payload, cb) {
        if (payload.method === 'eth_accounts') {
          return realSend(payload, function(err, result) {
            if (err) {
              return cb(err);
            }
            if (self.accounts.length) {
              result.result = self.addresses; // Send our addresses
            }
            cb(null, result);
          });
        } else if (payload.method === constants.blockchain.transactionMethods.eth_sendRawTransaction) {
          return self.runTransaction.push({payload}, cb);
        }

        realSend(payload, cb);
      };
      callback();
    });
  }

  connected() {
    if (this.type === 'rpc') {
      return !!this.provider;
    } else if (this.type === 'ws') {
      return this.provider && this.provider.connection._connection && this.provider.connection._connection.connected;
    }

    return false;
  }

  stop() {
    if (this.provider && this.provider.removeAllListeners) {
      this.provider.removeAllListeners('connect');
      this.provider.removeAllListeners('error');
      this.provider.removeAllListeners('end');
      this.provider.removeAllListeners('data');
      this.provider.responseCallbacks = {};
    }
    this.provider = null;
    this.web3.setProvider(null);
  }

  fundAccounts(callback) {
    const self = this;
    if (!self.accounts.length) {
      return callback();
    }
    if (!self.isDev) {
      return callback();
    }
    async.eachLimit(self.accounts, 1, (account, eachCb) => {
      if (!account.address) {
        return eachCb();
      }
      fundAccount(self.web3, account.address, account.hexBalance, eachCb);
    }, callback);
  }
}

module.exports = Provider;
<|endoftext|>


<commit_before>/**
 * Complete dimensions by data (guess dimension).
 */
define(function (require) {

    var zrUtil = require('zrender/core/util');
    var modelUtil = require('../../util/model');
    var each = zrUtil.each;
    var isString = zrUtil.isString;
    var defaults = zrUtil.defaults;
    var normalizeToArray = modelUtil.normalizeToArray;

    var OTHER_DIMS = {tooltip: 1, label: 1, itemName: 1};

    /**
     * Complete the dimensions array, by user defined `dimension` and `encode`,
     * and guessing from the data structure.
     * If no 'value' dimension specified, the first no-named dimension will be
     * named as 'value'.
     *
     * @param {Array.<string>} sysDims Necessary dimensions, like ['x', 'y'], which
     *      provides not only dim template, but also default order.
     *      `name` of each item provides default coord name.
     *      [{dimsDef: []}, ...] can be specified to give names.
     * @param {Array} data Data list. [[1, 2, 3], [2, 3, 4]].
     * @param {Object} [opt]
     * @param {Array.<Object|string>} [opt.dimsDef] option.series.dimensions User defined dimensions
     *      For example: ['asdf', {name, type}, ...].
     * @param {Object} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3}
     * @param {string} [opt.extraPrefix] Prefix of name when filling the left dimensions.
     * @param {string} [opt.extraFromZero] If specified, extra dim names will be:
     *                      extraPrefix + 0, extraPrefix + extraBaseIndex + 1 ...
     *                      If not specified, extra dim names will be:
     *                      extraPrefix, extraPrefix + 0, extraPrefix + 1 ...
     * @param {number} [opt.dimCount] If not specified, guess by the first data item.
     * @return {Array.<Object>} [{
     *      name: string mandatory,
     *      coordDim: string mandatory,
     *      coordDimIndex: number mandatory,
     *      type: string optional,
     *      tooltipName: string optional,
     *      otherDims: {
     *          tooltip: number optional,
     *          label: number optional
     *      },
     *      isExtraCoord: boolean true or undefined.
     *      other props ...
     * }]
     */
    function completeDimensions(sysDims, data, opt) {
        data = data || [];
        opt = opt || {};
        sysDims = (sysDims || []).slice();
        var dimsDef = (opt.dimsDef || []).slice();
        var encodeDef = zrUtil.createHashMap(opt.encodeDef);
        var dataDimNameMap = zrUtil.createHashMap();
        var coordDimNameMap = zrUtil.createHashMap();
        // var valueCandidate;
        var result = [];

        var dimCount = opt.dimCount;
        if (dimCount == null) {
            var value0 = retrieveValue(data[0]);
            dimCount = Math.max(
                zrUtil.isArray(value0) && value0.length || 1,
                sysDims.length,
                dimsDef.length
            );
            each(sysDims, function (sysDimItem) {
                var sysDimItemDimsDef = sysDimItem.dimsDef;
                sysDimItemDimsDef && (dimCount = Math.max(dimCount, sysDimItemDimsDef.length));
            });
        }

        // Apply user defined dims (`name` and `type`) and init result.
        for (var i = 0; i < dimCount; i++) {
            var dimDefItem = isString(dimsDef[i]) ? {name: dimsDef[i]} : (dimsDef[i] || {});
            var userDimName = dimDefItem.name;
            var resultItem = result[i] = {otherDims: {}};
            // Name will be applied later for avoiding duplication.
            if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
                // Only if `series.dimensions` is defined in option, tooltipName
                // will be set, and dimension will be diplayed vertically in
                // tooltip by default.
                resultItem.name = resultItem.tooltipName = userDimName;
                dataDimNameMap.set(userDimName, i);
            }
            dimDefItem.type != null && (resultItem.type = dimDefItem.type);
        }

        // Set `coordDim` and `coordDimIndex` by `encodeDef` and normalize `encodeDef`.
        encodeDef.each(function (dataDims, coordDim) {
            dataDims = encodeDef.set(coordDim, normalizeToArray(dataDims).slice());
            each(dataDims, function (resultDimIdx, coordDimIndex) {
                // The input resultDimIdx can be dim name or index.
                isString(resultDimIdx) && (resultDimIdx = dataDimNameMap.get(resultDimIdx));
                if (resultDimIdx != null && resultDimIdx < dimCount) {
                    dataDims[coordDimIndex] = resultDimIdx;
                    applyDim(result[resultDimIdx], coordDim, coordDimIndex);
                }
            });
        });

        // Apply templetes and default order from `sysDims`.
        var availDimIdx = 0;
        each(sysDims, function (sysDimItem, sysDimIndex) {
            var coordDim;
            var sysDimItem;
            var sysDimItemDimsDef;
            var sysDimItemOtherDims;
            if (isString(sysDimItem)) {
                coordDim = sysDimItem;
                sysDimItem = {};
            }
            else {
                coordDim = sysDimItem.name;
                sysDimItem = zrUtil.clone(sysDimItem);
                // `coordDimIndex` should not be set directly.
                sysDimItemDimsDef = sysDimItem.dimsDef;
                sysDimItemOtherDims = sysDimItem.otherDims;
                sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex
                    = sysDimItem.dimsDef = sysDimItem.otherDims = null;
            }

            var dataDims = normalizeToArray(encodeDef.get(coordDim));
            // dimensions provides default dim sequences.
            if (!dataDims.length) {
                for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) {
                    while (availDimIdx < result.length && result[availDimIdx].coordDim != null) {
                        availDimIdx++;
                    }
                    availDimIdx < result.length && dataDims.push(availDimIdx++);
                }
            }
            // Apply templates.
            each(dataDims, function (resultDimIdx, coordDimIndex) {
                var resultItem = result[resultDimIdx];
                applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex);
                if (resultItem.name == null && sysDimItemDimsDef) {
                    resultItem.name = resultItem.tooltipName = sysDimItemDimsDef[coordDimIndex];
                }
                sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims);
            });
        });

        // Make sure the first extra dim is 'value'.
        var extra = opt.extraPrefix || 'value';

        // Set dim `name` and other `coordDim` and other props.
        for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
            var resultItem = result[resultDimIdx] = result[resultDimIdx] || {};
            var coordDim = resultItem.coordDim;

            coordDim == null && (
                resultItem.coordDim = genName(extra, coordDimNameMap, opt.extraFromZero),
                resultItem.coordDimIndex = 0,
                resultItem.isExtraCoord = true
            );

            resultItem.name == null && (resultItem.name = genName(
                resultItem.coordDim,
                dataDimNameMap
            ));

            resultItem.type == null && guessOrdinal(data, resultDimIdx)
                && (resultItem.type = 'ordinal');
        }

        return result;

        function applyDim(resultItem, coordDim, coordDimIndex) {
            if (OTHER_DIMS[coordDim]) {
                resultItem.otherDims[coordDim] = coordDimIndex;
            }
            else {
                resultItem.coordDim = coordDim;
                resultItem.coordDimIndex = coordDimIndex;
                coordDimNameMap.set(coordDim, true);
            }
        }

        function genName(name, map, fromZero) {
            if (fromZero || map.get(name) != null) {
                var i = 0;
                while (map.get(name + i) != null) {
                    i++;
                }
                name += i;
            }
            map.set(name, true);
            return name;
        }
    }

    // The rule should not be complex, otherwise user might not
    // be able to known where the data is wrong.
    var guessOrdinal = completeDimensions.guessOrdinal = function (data, dimIndex) {
        for (var i = 0, len = data.length; i < len; i++) {
            var value = retrieveValue(data[i]);

            if (!zrUtil.isArray(value)) {
                return false;
            }

            var value = value[dimIndex];
            // Consider usage convenience, '1', '2' will be treated as "number".
            if (value != null && isFinite(value)) {
                return false;
            }
            else if (isString(value) && value !== '-') {
                return true;
            }
        }
        return false;
    };

    function retrieveValue(o) {
        return zrUtil.isArray(o) ? o : zrUtil.isObject(o) ? o.value: o;
    }

    return completeDimensions;

});<commit_msg>tweak<commit_after>/**
 * Complete dimensions by data (guess dimension).
 */
define(function (require) {

    var zrUtil = require('zrender/core/util');
    var modelUtil = require('../../util/model');
    var each = zrUtil.each;
    var isString = zrUtil.isString;
    var defaults = zrUtil.defaults;
    var normalizeToArray = modelUtil.normalizeToArray;

    var OTHER_DIMS = {tooltip: 1, label: 1, itemName: 1};

    /**
     * Complete the dimensions array, by user defined `dimension` and `encode`,
     * and guessing from the data structure.
     * If no 'value' dimension specified, the first no-named dimension will be
     * named as 'value'.
     *
     * @param {Array.<string>} sysDims Necessary dimensions, like ['x', 'y'], which
     *      provides not only dim template, but also default order.
     *      `name` of each item provides default coord name.
     *      [{dimsDef: []}, ...] can be specified to give names.
     * @param {Array} data Data list. [[1, 2, 3], [2, 3, 4]].
     * @param {Object} [opt]
     * @param {Array.<Object|string>} [opt.dimsDef] option.series.dimensions User defined dimensions
     *      For example: ['asdf', {name, type}, ...].
     * @param {Object} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3}
     * @param {string} [opt.extraPrefix] Prefix of name when filling the left dimensions.
     * @param {string} [opt.extraFromZero] If specified, extra dim names will be:
     *                      extraPrefix + 0, extraPrefix + extraBaseIndex + 1 ...
     *                      If not specified, extra dim names will be:
     *                      extraPrefix, extraPrefix + 0, extraPrefix + 1 ...
     * @param {number} [opt.dimCount] If not specified, guess by the first data item.
     * @return {Array.<Object>} [{
     *      name: string mandatory,
     *      coordDim: string mandatory,
     *      coordDimIndex: number mandatory,
     *      type: string optional,
     *      tooltipName: string optional,
     *      otherDims: {
     *          tooltip: number optional,
     *          label: number optional
     *      },
     *      isExtraCoord: boolean true or undefined.
     *      other props ...
     * }]
     */
    function completeDimensions(sysDims, data, opt) {
        data = data || [];
        opt = opt || {};
        sysDims = (sysDims || []).slice();
        var dimsDef = (opt.dimsDef || []).slice();
        var encodeDef = zrUtil.createHashMap(opt.encodeDef);
        var dataDimNameMap = zrUtil.createHashMap();
        var coordDimNameMap = zrUtil.createHashMap();
        // var valueCandidate;
        var result = [];

        var dimCount = opt.dimCount;
        if (dimCount == null) {
            var value0 = retrieveValue(data[0]);
            dimCount = Math.max(
                zrUtil.isArray(value0) && value0.length || 1,
                sysDims.length,
                dimsDef.length
            );
            each(sysDims, function (sysDimItem) {
                var sysDimItemDimsDef = sysDimItem.dimsDef;
                sysDimItemDimsDef && (dimCount = Math.max(dimCount, sysDimItemDimsDef.length));
            });
        }

        // Apply user defined dims (`name` and `type`) and init result.
        for (var i = 0; i < dimCount; i++) {
            var dimDefItem = isString(dimsDef[i]) ? {name: dimsDef[i]} : (dimsDef[i] || {});
            var userDimName = dimDefItem.name;
            var resultItem = result[i] = {otherDims: {}};
            // Name will be applied later for avoiding duplication.
            if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
                // Only if `series.dimensions` is defined in option, tooltipName
                // will be set, and dimension will be diplayed vertically in
                // tooltip by default.
                resultItem.name = resultItem.tooltipName = userDimName;
                dataDimNameMap.set(userDimName, i);
            }
            dimDefItem.type != null && (resultItem.type = dimDefItem.type);
        }

        // Set `coordDim` and `coordDimIndex` by `encodeDef` and normalize `encodeDef`.
        encodeDef.each(function (dataDims, coordDim) {
            dataDims = encodeDef.set(coordDim, normalizeToArray(dataDims).slice());
            each(dataDims, function (resultDimIdx, coordDimIndex) {
                // The input resultDimIdx can be dim name or index.
                isString(resultDimIdx) && (resultDimIdx = dataDimNameMap.get(resultDimIdx));
                if (resultDimIdx != null && resultDimIdx < dimCount) {
                    dataDims[coordDimIndex] = resultDimIdx;
                    applyDim(result[resultDimIdx], coordDim, coordDimIndex);
                }
            });
        });

        // Apply templetes and default order from `sysDims`.
        var availDimIdx = 0;
        each(sysDims, function (sysDimItem, sysDimIndex) {
            var coordDim;
            var sysDimItem;
            var sysDimItemDimsDef;
            var sysDimItemOtherDims;
            if (isString(sysDimItem)) {
                coordDim = sysDimItem;
                sysDimItem = {};
            }
            else {
                coordDim = sysDimItem.name;
                sysDimItem = zrUtil.clone(sysDimItem);
                // `coordDimIndex` should not be set directly.
                sysDimItemDimsDef = sysDimItem.dimsDef;
                sysDimItemOtherDims = sysDimItem.otherDims;
                sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex
                    = sysDimItem.dimsDef = sysDimItem.otherDims = null;
            }

            var dataDims = normalizeToArray(encodeDef.get(coordDim));
            // dimensions provides default dim sequences.
            if (!dataDims.length) {
                for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) {
                    while (availDimIdx < result.length && result[availDimIdx].coordDim != null) {
                        availDimIdx++;
                    }
                    availDimIdx < result.length && dataDims.push(availDimIdx++);
                }
            }
            // Apply templates.
            each(dataDims, function (resultDimIdx, coordDimIndex) {
                var resultItem = result[resultDimIdx];
                applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex);
                if (resultItem.name == null && sysDimItemDimsDef) {
                    resultItem.name = resultItem.tooltipName = sysDimItemDimsDef[coordDimIndex];
                }
                sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims);
            });
        });

        // Make sure the first extra dim is 'value'.
        var extra = opt.extraPrefix || 'value';

        // Set dim `name` and other `coordDim` and other props.
        for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
            var resultItem = result[resultDimIdx] = result[resultDimIdx] || {};
            var coordDim = resultItem.coordDim;

            coordDim == null && (
                resultItem.coordDim = genName(extra, coordDimNameMap, opt.extraFromZero),
                resultItem.coordDimIndex = 0,
                resultItem.isExtraCoord = true
            );

            resultItem.name == null && (resultItem.name = genName(
                resultItem.coordDim,
                dataDimNameMap
            ));

            resultItem.type == null && guessOrdinal(data, resultDimIdx)
                && (resultItem.type = 'ordinal');
        }

        return result;

        function applyDim(resultItem, coordDim, coordDimIndex) {
            if (OTHER_DIMS[coordDim]) {
                resultItem.otherDims[coordDim] = coordDimIndex;
            }
            else {
                resultItem.coordDim = coordDim;
                resultItem.coordDimIndex = coordDimIndex;
                coordDimNameMap.set(coordDim, true);
            }
        }

        function genName(name, map, fromZero) {
            if (fromZero || map.get(name) != null) {
                var i = 0;
                while (map.get(name + i) != null) {
                    i++;
                }
                name += i;
            }
            map.set(name, true);
            return name;
        }
    }

    // The rule should not be complex, otherwise user might not
    // be able to known where the data is wrong.
    var guessOrdinal = completeDimensions.guessOrdinal = function (data, dimIndex) {
        for (var i = 0, len = data.length; i < len; i++) {
            var value = retrieveValue(data[i]);

            if (!zrUtil.isArray(value)) {
                return false;
            }

            var value = value[dimIndex];
            // Consider usage convenience, '1', '2' will be treated as "number".
            // `isFinit('')` get `true`.
            if (value != null && isFinite(value) && value !== '') {
                return false;
            }
            else if (isString(value) && value !== '-') {
                return true;
            }
        }
        return false;
    };

    function retrieveValue(o) {
        return zrUtil.isArray(o) ? o : zrUtil.isObject(o) ? o.value: o;
    }

    return completeDimensions;

});<|endoftext|>


<commit_before><commit_msg>fix bug in ami:dongle:sms command<commit_after><|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

// Import the individual autotrack plugins you want to use.
// import 'autotrack/lib/plugins/clean-url-tracker';
// import 'autotrack/lib/plugins/max-scroll-tracker';
// import 'autotrack/lib/plugins/outbound-link-tracker';
// import 'autotrack/lib/plugins/page-visibility-tracker';
// import 'autotrack/lib/plugins/url-change-tracker';

/* eslint-disable */
/* global ga, fbq */

/**
 * The tracking ID for your Google Analytics property.
 * https://support.google.com/analytics/answer/1032385
 */
var TRACKING_ID = process.env.REACT_APP_GA || process.env.GA;

/**
 * Bump this when making backwards incompatible changes to the tracking
 * implementation. This allows you to create a segment or view filter
 * that isolates only data captured with the most recent tracking changes.
 */
var TRACKING_VERSION = process.env.REACT_APP_TV || process.env.TV || '1';

/**
 * A default value for dimensions so unset values always are reported as
 * something. This is needed since Google Analytics will drop empty dimension
 * values in reports.
 */
var NULL_VALUE = '(not set)';

/**
 * A mapping between custom dimension names and their indexes.
 */
var dimensions = {
  TRACKING_VERSION: 'dimension1',
  CLIENT_ID: 'dimension2',
  WINDOW_ID: 'dimension3',
  HIT_ID: 'dimension4',
  HIT_TIME: 'dimension5',
  HIT_TYPE: 'dimension6',
  HIT_SOURCE: 'dimension7',
  VISIBILITY_STATE: 'dimension8',
  URL_QUERY_PARAMS: 'dimension9'
};

/**
 * A mapping between custom metric names and their indexes.
 */
var metrics = {
  RESPONSE_END_TIME: 'metric1',
  DOM_LOAD_TIME: 'metric2',
  WINDOW_LOAD_TIME: 'metric3',
  PAGE_VISIBLE: 'metric4',
  MAX_SCROLL_PERCENTAGE: 'metric5'
};

/**
 * Initializes all the analytics setup. Creates trackers and sets initial
 * values on the trackers.
 */
var init = exports.init = function init() {
  // Initialize the command queue in case analytics.js hasn't loaded yet.
  window.ga = window.ga || function () {
    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return (ga.q = ga.q || []).push(args);
  };

  createTracker();
  trackErrors();
  trackCustomDimensions();
  requireAutotrackPlugins();
  sendInitialPageview();
  sendNavigationTimingMetrics();
};

/**
 * Tracks a JavaScript error with optional fields object overrides.
 * This function is exported so it can be used in other parts of the codebase.
 * E.g.:
 *
 *    `fetch('/api.json').catch(trackError);`
 *
 * @param {Error|undefined} err
 * @param {Object=} fieldsObj
 */
var trackError = exports.trackError = function trackError(err) {
  var fieldsObj = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

  ga('send', 'event', Object.assign({
    eventCategory: 'Error',
    eventAction: err.name,
    eventLabel: err.message + '\n' + (err.stack || '(no stack trace)'),
    nonInteraction: true
  }, fieldsObj));
};

/**
 * Creates the trackers and sets the default transport and tracking
 * version fields. In non-production environments it also logs hits.
 */
var createTracker = function createTracker() {
  ga('create', TRACKING_ID, 'auto');

  // Ensures all hits are sent via `navigator.sendBeacon()`.
  ga('set', 'transport', 'beacon');

  fbq('init', process.env.REACT_APP_FBQ || process.env.FBQ);
};

/**
 * Tracks any errors that may have occured on the page prior to analytics being
 * initialized, then adds an event handler to track future errors.
 */
var trackErrors = function trackErrors() {
  // Errors that have occurred prior to this script running are stored on
  // `window.__e.q`, as specified in `index.html`.
  var loadErrorEvents = window.__e && window.__e.q || [];

  // Use a different eventCategory for uncaught errors.
  var fieldsObj = { eventCategory: 'Uncaught Error' };

  // Replay any stored load error events.
  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = loadErrorEvents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var event = _step.value;

      trackError(event.error, fieldsObj);
    }

    // Add a new listener to track event immediately.
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  window.addEventListener('error', function (event) {
    trackError(event.error, fieldsObj);
  });
};

/**
 * Sets a default dimension value for all custom dimensions on all trackers.
 */
var trackCustomDimensions = function trackCustomDimensions() {
  // Sets a default dimension value for all custom dimensions to ensure
  // that every dimension in every hit has *some* value. This is necessary
  // because Google Analytics will drop rows with empty dimension values
  // in your reports.
  Object.keys(dimensions).forEach(function (key) {
    ga('set', dimensions[key], NULL_VALUE);
  });

  // Adds tracking of dimensions known at page load time.
  ga(function (tracker) {
    var _tracker$set;

    tracker.set((_tracker$set = {}, _defineProperty(_tracker$set, dimensions.TRACKING_VERSION, TRACKING_VERSION), _defineProperty(_tracker$set, dimensions.CLIENT_ID, tracker.get('clientId')), _defineProperty(_tracker$set, dimensions.WINDOW_ID, uuid()), _tracker$set));
  });

  // Adds tracking to record each the type, time, uuid, and visibility state
  // of each hit immediately before it's sent.
  ga(function (tracker) {
    var originalBuildHitTask = tracker.get('buildHitTask');
    tracker.set('buildHitTask', function (model) {
      var qt = model.get('queueTime') || 0;
      model.set(dimensions.HIT_TIME, String(new Date() - qt), true);
      model.set(dimensions.HIT_ID, uuid(), true);
      model.set(dimensions.HIT_TYPE, model.get('hitType'), true);
      model.set(dimensions.VISIBILITY_STATE, document.visibilityState, true);

      originalBuildHitTask(model);
    });
  });
};

/**
 * Requires select autotrack plugins and initializes each one with its
 * respective configuration options.
 */
var requireAutotrackPlugins = function requireAutotrackPlugins() {
  ga('require', 'cleanUrlTracker', {
    stripQuery: true,
    queryDimensionIndex: getDefinitionIndex(dimensions.URL_QUERY_PARAMS),
    trailingSlash: 'remove'
  });
  ga('require', 'maxScrollTracker', {
    sessionTimeout: 30,
    timeZone: process.env.REACT_APP_TZ || process.env.TZ || 'Asia/Taipei',
    maxScrollMetricIndex: getDefinitionIndex(metrics.MAX_SCROLL_PERCENTAGE)
  });
  ga('require', 'outboundLinkTracker', {
    events: ['click', 'contextmenu']
  });
  ga('require', 'pageVisibilityTracker', {
    visibleMetricIndex: getDefinitionIndex(metrics.PAGE_VISIBLE),
    sessionTimeout: 30,
    timeZone: process.env.REACT_APP_TZ || process.env.TZ || 'Asia/Taipei',
    fieldsObj: _defineProperty({}, dimensions.HIT_SOURCE, 'pageVisibilityTracker')
  });
  ga('require', 'urlChangeTracker', {
    fieldsObj: _defineProperty({}, dimensions.HIT_SOURCE, 'urlChangeTracker')
  });
};

/**
 * Sends the initial pageview to Google Analytics.
 */
var sendInitialPageview = function sendInitialPageview() {
  ga('send', 'pageview', _defineProperty({}, dimensions.HIT_SOURCE, 'pageload'));

  fbq('track', 'PageView');
};

/**
 * Gets the DOM and window load times and sends them as custom metrics to
 * Google Analytics via an event hit.
 */
var sendNavigationTimingMetrics = function sendNavigationTimingMetrics() {
  // Only track performance in supporting browsers.
  if (!(window.performance && window.performance.timing)) return;

  // If the window hasn't loaded, run this function after the `load` event.
  if (document.readyState != 'complete') {
    window.addEventListener('load', sendNavigationTimingMetrics);
    return;
  }

  var nt = performance.timing;
  var navStart = nt.navigationStart;

  var responseEnd = Math.round(nt.responseEnd - navStart);
  var domLoaded = Math.round(nt.domContentLoadedEventStart - navStart);
  var windowLoaded = Math.round(nt.loadEventStart - navStart);

  // In some edge cases browsers return very obviously incorrect NT values,
  // e.g. 0, negative, or future times. This validates values before sending.
  var allValuesAreValid = function allValuesAreValid() {
    for (var _len2 = arguments.length, values = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
      values[_key2] = arguments[_key2];
    }

    return values.every(function (value) {
      return value > 0 && value < 6e6;
    });
  };

  if (allValuesAreValid(responseEnd, domLoaded, windowLoaded)) {
    var _ga2;

    ga('send', 'event', (_ga2 = {
      eventCategory: 'Navigation Timing',
      eventAction: 'track',
      nonInteraction: true
    }, _defineProperty(_ga2, metrics.RESPONSE_END_TIME, responseEnd), _defineProperty(_ga2, metrics.DOM_LOAD_TIME, domLoaded), _defineProperty(_ga2, metrics.WINDOW_LOAD_TIME, windowLoaded), _ga2));
  }
};

/**
 * Accepts a custom dimension or metric and returns it's numerical index.
 * @param {string} definition The definition string (e.g. 'dimension1').
 * @return {number} The definition index.
 */
var getDefinitionIndex = function getDefinitionIndex(definition) {
  return +/\d+$/.exec(definition)[0];
};

/**
 * Generates a UUID.
 * https://gist.github.com/jed/982883
 * @param {string|undefined=} a
 * @return {string}
 */
var uuid = function b(a) {
  return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, b);
};

var trackEvent = exports.trackEvent = function trackEvent(eventCategory, eventAction) {
  var eventLabel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : NULL_VALUE;

  ga('send', 'event', {
    eventCategory: eventCategory,
    eventAction: eventAction,
    eventLabel: eventLabel
  });

  fbq('trackCustom', eventCategory, {
    eventAction: eventAction,
    eventLabel: eventLabel
  });
};

var trackPageview = exports.trackPageview = function trackPageview(pathname) {
  ga('send', 'pageview', pathname);

  fbq('track', 'PageView');
};

exports.default = { init: init, trackError: trackError, trackEvent: trackEvent, trackPageview: trackPageview };
<commit_msg>changed default for TZ<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

// Import the individual autotrack plugins you want to use.
// import 'autotrack/lib/plugins/clean-url-tracker';
// import 'autotrack/lib/plugins/max-scroll-tracker';
// import 'autotrack/lib/plugins/outbound-link-tracker';
// import 'autotrack/lib/plugins/page-visibility-tracker';
// import 'autotrack/lib/plugins/url-change-tracker';

/* eslint-disable */
/* global ga, fbq */

/**
 * The tracking ID for your Google Analytics property.
 * https://support.google.com/analytics/answer/1032385
 */
var TRACKING_ID = process.env.REACT_APP_GA || process.env.GA;

/**
 * Bump this when making backwards incompatible changes to the tracking
 * implementation. This allows you to create a segment or view filter
 * that isolates only data captured with the most recent tracking changes.
 */
var TRACKING_VERSION = process.env.REACT_APP_TV || process.env.TV || '1';

/**
 * A default value for dimensions so unset values always are reported as
 * something. This is needed since Google Analytics will drop empty dimension
 * values in reports.
 */
var NULL_VALUE = '(not set)';

/**
 * A mapping between custom dimension names and their indexes.
 */
var dimensions = {
  TRACKING_VERSION: 'dimension1',
  CLIENT_ID: 'dimension2',
  WINDOW_ID: 'dimension3',
  HIT_ID: 'dimension4',
  HIT_TIME: 'dimension5',
  HIT_TYPE: 'dimension6',
  HIT_SOURCE: 'dimension7',
  VISIBILITY_STATE: 'dimension8',
  URL_QUERY_PARAMS: 'dimension9'
};

/**
 * A mapping between custom metric names and their indexes.
 */
var metrics = {
  RESPONSE_END_TIME: 'metric1',
  DOM_LOAD_TIME: 'metric2',
  WINDOW_LOAD_TIME: 'metric3',
  PAGE_VISIBLE: 'metric4',
  MAX_SCROLL_PERCENTAGE: 'metric5'
};

/**
 * Initializes all the analytics setup. Creates trackers and sets initial
 * values on the trackers.
 */
var init = exports.init = function init() {
  // Initialize the command queue in case analytics.js hasn't loaded yet.
  window.ga = window.ga || function () {
    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    return (ga.q = ga.q || []).push(args);
  };

  createTracker();
  trackErrors();
  trackCustomDimensions();
  requireAutotrackPlugins();
  sendInitialPageview();
  sendNavigationTimingMetrics();
};

/**
 * Tracks a JavaScript error with optional fields object overrides.
 * This function is exported so it can be used in other parts of the codebase.
 * E.g.:
 *
 *    `fetch('/api.json').catch(trackError);`
 *
 * @param {Error|undefined} err
 * @param {Object=} fieldsObj
 */
var trackError = exports.trackError = function trackError(err) {
  var fieldsObj = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

  ga('send', 'event', Object.assign({
    eventCategory: 'Error',
    eventAction: err.name,
    eventLabel: err.message + '\n' + (err.stack || '(no stack trace)'),
    nonInteraction: true
  }, fieldsObj));
};

/**
 * Creates the trackers and sets the default transport and tracking
 * version fields. In non-production environments it also logs hits.
 */
var createTracker = function createTracker() {
  ga('create', TRACKING_ID, 'auto');

  // Ensures all hits are sent via `navigator.sendBeacon()`.
  ga('set', 'transport', 'beacon');

  fbq('init', process.env.REACT_APP_FBQ || process.env.FBQ);
};

/**
 * Tracks any errors that may have occured on the page prior to analytics being
 * initialized, then adds an event handler to track future errors.
 */
var trackErrors = function trackErrors() {
  // Errors that have occurred prior to this script running are stored on
  // `window.__e.q`, as specified in `index.html`.
  var loadErrorEvents = window.__e && window.__e.q || [];

  // Use a different eventCategory for uncaught errors.
  var fieldsObj = { eventCategory: 'Uncaught Error' };

  // Replay any stored load error events.
  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = loadErrorEvents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var event = _step.value;

      trackError(event.error, fieldsObj);
    }

    // Add a new listener to track event immediately.
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  window.addEventListener('error', function (event) {
    trackError(event.error, fieldsObj);
  });
};

/**
 * Sets a default dimension value for all custom dimensions on all trackers.
 */
var trackCustomDimensions = function trackCustomDimensions() {
  // Sets a default dimension value for all custom dimensions to ensure
  // that every dimension in every hit has *some* value. This is necessary
  // because Google Analytics will drop rows with empty dimension values
  // in your reports.
  Object.keys(dimensions).forEach(function (key) {
    ga('set', dimensions[key], NULL_VALUE);
  });

  // Adds tracking of dimensions known at page load time.
  ga(function (tracker) {
    var _tracker$set;

    tracker.set((_tracker$set = {}, _defineProperty(_tracker$set, dimensions.TRACKING_VERSION, TRACKING_VERSION), _defineProperty(_tracker$set, dimensions.CLIENT_ID, tracker.get('clientId')), _defineProperty(_tracker$set, dimensions.WINDOW_ID, uuid()), _tracker$set));
  });

  // Adds tracking to record each the type, time, uuid, and visibility state
  // of each hit immediately before it's sent.
  ga(function (tracker) {
    var originalBuildHitTask = tracker.get('buildHitTask');
    tracker.set('buildHitTask', function (model) {
      var qt = model.get('queueTime') || 0;
      model.set(dimensions.HIT_TIME, String(new Date() - qt), true);
      model.set(dimensions.HIT_ID, uuid(), true);
      model.set(dimensions.HIT_TYPE, model.get('hitType'), true);
      model.set(dimensions.VISIBILITY_STATE, document.visibilityState, true);

      originalBuildHitTask(model);
    });
  });
};

/**
 * Requires select autotrack plugins and initializes each one with its
 * respective configuration options.
 */
var requireAutotrackPlugins = function requireAutotrackPlugins() {
  ga('require', 'cleanUrlTracker', {
    stripQuery: true,
    queryDimensionIndex: getDefinitionIndex(dimensions.URL_QUERY_PARAMS),
    trailingSlash: 'remove'
  });
  ga('require', 'maxScrollTracker', {
    sessionTimeout: 30,
    timeZone: process.env.REACT_APP_TZ || process.env.TZ || 'America/Los_Angeles',
    maxScrollMetricIndex: getDefinitionIndex(metrics.MAX_SCROLL_PERCENTAGE)
  });
  ga('require', 'outboundLinkTracker', {
    events: ['click', 'contextmenu']
  });
  ga('require', 'pageVisibilityTracker', {
    visibleMetricIndex: getDefinitionIndex(metrics.PAGE_VISIBLE),
    sessionTimeout: 30,
    timeZone: process.env.REACT_APP_TZ || process.env.TZ || 'America/Los_Angeles',
    fieldsObj: _defineProperty({}, dimensions.HIT_SOURCE, 'pageVisibilityTracker')
  });
  ga('require', 'urlChangeTracker', {
    fieldsObj: _defineProperty({}, dimensions.HIT_SOURCE, 'urlChangeTracker')
  });
};

/**
 * Sends the initial pageview to Google Analytics.
 */
var sendInitialPageview = function sendInitialPageview() {
  ga('send', 'pageview', _defineProperty({}, dimensions.HIT_SOURCE, 'pageload'));

  fbq('track', 'PageView');
};

/**
 * Gets the DOM and window load times and sends them as custom metrics to
 * Google Analytics via an event hit.
 */
var sendNavigationTimingMetrics = function sendNavigationTimingMetrics() {
  // Only track performance in supporting browsers.
  if (!(window.performance && window.performance.timing)) return;

  // If the window hasn't loaded, run this function after the `load` event.
  if (document.readyState != 'complete') {
    window.addEventListener('load', sendNavigationTimingMetrics);
    return;
  }

  var nt = performance.timing;
  var navStart = nt.navigationStart;

  var responseEnd = Math.round(nt.responseEnd - navStart);
  var domLoaded = Math.round(nt.domContentLoadedEventStart - navStart);
  var windowLoaded = Math.round(nt.loadEventStart - navStart);

  // In some edge cases browsers return very obviously incorrect NT values,
  // e.g. 0, negative, or future times. This validates values before sending.
  var allValuesAreValid = function allValuesAreValid() {
    for (var _len2 = arguments.length, values = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
      values[_key2] = arguments[_key2];
    }

    return values.every(function (value) {
      return value > 0 && value < 6e6;
    });
  };

  if (allValuesAreValid(responseEnd, domLoaded, windowLoaded)) {
    var _ga2;

    ga('send', 'event', (_ga2 = {
      eventCategory: 'Navigation Timing',
      eventAction: 'track',
      nonInteraction: true
    }, _defineProperty(_ga2, metrics.RESPONSE_END_TIME, responseEnd), _defineProperty(_ga2, metrics.DOM_LOAD_TIME, domLoaded), _defineProperty(_ga2, metrics.WINDOW_LOAD_TIME, windowLoaded), _ga2));
  }
};

/**
 * Accepts a custom dimension or metric and returns it's numerical index.
 * @param {string} definition The definition string (e.g. 'dimension1').
 * @return {number} The definition index.
 */
var getDefinitionIndex = function getDefinitionIndex(definition) {
  return +/\d+$/.exec(definition)[0];
};

/**
 * Generates a UUID.
 * https://gist.github.com/jed/982883
 * @param {string|undefined=} a
 * @return {string}
 */
var uuid = function b(a) {
  return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, b);
};

var trackEvent = exports.trackEvent = function trackEvent(eventCategory, eventAction) {
  var eventLabel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : NULL_VALUE;

  ga('send', 'event', {
    eventCategory: eventCategory,
    eventAction: eventAction,
    eventLabel: eventLabel
  });

  fbq('trackCustom', eventCategory, {
    eventAction: eventAction,
    eventLabel: eventLabel
  });
};

var trackPageview = exports.trackPageview = function trackPageview(pathname) {
  ga('send', 'pageview', pathname);

  fbq('track', 'PageView');
};

exports.default = { init: init, trackError: trackError, trackEvent: trackEvent, trackPageview: trackPageview };
<|endoftext|>


<commit_before><commit_msg>Tiny optimization to `rgbToHex`<commit_after><|endoftext|>


<commit_before>var loadMatchday = function (matchday)
{
    $("#content").empty()
    var row = $("

").appendTo("#content")
    var column = $("

").appendTo(row)
    var h1 = $("
" + (matchday + 1) + ". Spieltag
").appendTo(column)
    if (matchday !== 0)
    {
        var moveUpButton = $("<button class=\"btn btn-warning\">←</button>").appendTo(h1)
        moveUpButton.click
        (
            function ()
            {
                 var temp = matches[matchday]
                 matches[matchday] = matches[matchday - 1]
                 matches[matchday - 1] = temp
                 loadMatchday(matchday)
            }
        )
    }
    $(document.createTextNode(" ")).appendTo(h1)
    if (matchday !== matches.length - 1)
    {
        var moveDownButton = $("<button class=\"btn btn-warning\">→</button>").appendTo(h1)
        moveDownButton.click
        (
            function ()
            {
                 var temp = matches[matchday]
                 matches[matchday] = matches[matchday + 1]
                 matches[matchday + 1] = temp
                 loadMatchday(matchday)
            }
        )
    }
    var teamFrequencies = {}
    for (var i = 0; i < matches[matchday].length; i++)
    {
        var match = matches[matchday][i]
        var homeTeam = match.homeTeam
        var awayTeam = match.awayTeam
        if (teamFrequencies[homeTeam] === undefined)
        {
            teamFrequencies[homeTeam] = 0
        }
        if (teamFrequencies[awayTeam] === undefined)
        {
            teamFrequencies[awayTeam] = 0
        }
        teamFrequencies[homeTeam]++
        teamFrequencies[awayTeam]++
    }
    var table = $("

").appendTo(column)
    for (var i = 0; i < matches[matchday].length; i++)
    {
        var match = matches[matchday][i]
        var tr = $("

").appendTo(table)
        if (teamFrequencies[match.homeTeam] > 1)
        {
            $("" + match.homeTeam + "	").appendTo(tr)
        }
        else
        {
            $("" + match.homeTeam + "	").appendTo(tr)
        }
        $("-	").appendTo(tr)
        if (teamFrequencies[match.awayTeam] > 1)
        {
            $("" + match.awayTeam + "	").appendTo(tr)
        }
        else
        {
            $("" + match.awayTeam + "	").appendTo(tr)
        }
        var createButtons = function (matchday, i)
        {
            var match = matches[matchday][i]
            var td, formGroup
            td = $("	").appendTo(tr)
            formGroup = $("

").appendTo(td)
            var homeGoalsInput = $("<input class=\"form-control\" min=\"0\" type=\"number\" />").appendTo(formGroup)
            if (match.homeGoals !== undefined)
            {
                homeGoalsInput.val(match.homeGoals)
            }
            homeGoalsInput.change
            (
                function ()
                {
                    match.homeGoals = parseInt(homeGoalsInput.val())
                    calculateTable(matchday)
                }
            )
            $(":	").appendTo(tr)
            td = $("	").appendTo(tr)
            formGroup = $("

").appendTo(td)
            var awayGoalsInput = $("<input class=\"form-control\" min=\"0\" type=\"number\" />").appendTo(formGroup)
            if (match.awayGoals !== undefined)
            {
                awayGoalsInput.val(match.awayGoals)
            }
            awayGoalsInput.change
            (
                function ()
                {
                    match.awayGoals = parseInt(awayGoalsInput.val())
                    calculateTable(matchday)
                }
            )
            if (matchday !== 0)
            {
                td = $("	").appendTo(tr)
                var moveUpButton = $("<button class=\"btn btn-warning\">←</button>").appendTo(td)
                moveUpButton.click
                (
                    function ()
                    {
                        matches[matchday - 1].push(matches[matchday].splice(i, 1)[0])
                        loadMatchday(matchday)
                    }
                )
            }
            if (matchday !== matches.length - 1)
            {
                td = $("	").appendTo(tr)
                var moveDownButton = $("<button class=\"btn btn-warning\">→</button>").appendTo(td)
                moveDownButton.click
                (
                    function ()
                    {
                        matches[matchday + 1].push(matches[matchday].splice(i, 1)[0])
                        loadMatchday(matchday)
                    }
                )
            }
        }
        createButtons(matchday, i)
    }
    $("
Tabelle
").appendTo(column)
    $("

").appendTo(column)
    calculateTable(matchday)
}

var updateMatchdayControl = function ()
{
    $("#matchdays").empty()
    var buttonGroup = $("

").appendTo("#matchdays")
    var settings = $("<button class=\"btn btn-default matchday-button\">Einstellungen</button>").appendTo(buttonGroup)
    settings.click
    (
        function ()
        {
            $(".matchday-button").removeClass("active")
            settings.addClass("active")
            $("#content").empty()
            var row = $("

").appendTo("#content")
            var column = $("

").appendTo(row)
            $("
Einstellungen
").appendTo(column)
            loadSettings()
        }
    )
    var firstMatchdayButton
    for (var i = 0; i < matches.length; i++)
    {
        var initMatchdayButton = function (i)
        {
            var button = $("<button class=\"btn btn-default matchday-button\">" + (i + 1) + "</button>").appendTo(buttonGroup)
            if (i === 0)
            {
                firstMatchdayButton = button
            }
            button.click
            (
                function ()
                {
                    $(".matchday-button").removeClass("active")
                    button.addClass("active")
                    loadMatchday(i)
                }
            )
        }
        initMatchdayButton(i)
    }
    firstMatchdayButton.click()
}
<commit_msg>Highlighting doppelter Mannschaften überarbeitet<commit_after>var loadMatchday = function (matchday)
{
    $("#content").empty()
    var row = $("

").appendTo("#content")
    var column = $("

").appendTo(row)
    var h1 = $("
" + (matchday + 1) + ". Spieltag
").appendTo(column)
    if (matchday !== 0)
    {
        var moveUpButton = $("<button class=\"btn btn-warning\">←</button>").appendTo(h1)
        moveUpButton.click
        (
            function ()
            {
                 var temp = matches[matchday]
                 matches[matchday] = matches[matchday - 1]
                 matches[matchday - 1] = temp
                 loadMatchday(matchday)
            }
        )
    }
    $(document.createTextNode(" ")).appendTo(h1)
    if (matchday !== matches.length - 1)
    {
        var moveDownButton = $("<button class=\"btn btn-warning\">→</button>").appendTo(h1)
        moveDownButton.click
        (
            function ()
            {
                 var temp = matches[matchday]
                 matches[matchday] = matches[matchday + 1]
                 matches[matchday + 1] = temp
                 loadMatchday(matchday)
            }
        )
    }
    var teamCount = {}
    for (var i = 0; i < matches[matchday].length; i++)
    {
        var match = matches[matchday][i]
        var homeTeam = match.homeTeam
        var awayTeam = match.awayTeam
        if (teamCount[homeTeam] === undefined)
        {
            teamCount[homeTeam] = 0
        }
        if (teamCount[awayTeam] === undefined)
        {
            teamCount[awayTeam] = 0
        }
        teamCount[homeTeam]++
        teamCount[awayTeam]++
    }
    var table = $("

").appendTo(column)
    for (var i = 0; i < matches[matchday].length; i++)
    {
        var match = matches[matchday][i]
        var tr = $("

").appendTo(table)
        if (teamCount[match.homeTeam] > 1)
        {
            $("" + match.homeTeam + "	").appendTo(tr)
        }
        else
        {
            $("" + match.homeTeam + "	").appendTo(tr)
        }
        $("-	").appendTo(tr)
        if (teamCount[match.awayTeam] > 1)
        {
            $("" + match.awayTeam + "	").appendTo(tr)
        }
        else
        {
            $("" + match.awayTeam + "	").appendTo(tr)
        }
        var createButtons = function (matchday, i)
        {
            var match = matches[matchday][i]
            var td, formGroup
            td = $("	").appendTo(tr)
            formGroup = $("

").appendTo(td)
            var homeGoalsInput = $("<input class=\"form-control\" min=\"0\" type=\"number\" />").appendTo(formGroup)
            if (match.homeGoals !== undefined)
            {
                homeGoalsInput.val(match.homeGoals)
            }
            homeGoalsInput.change
            (
                function ()
                {
                    match.homeGoals = parseInt(homeGoalsInput.val())
                    calculateTable(matchday)
                }
            )
            $(":	").appendTo(tr)
            td = $("	").appendTo(tr)
            formGroup = $("

").appendTo(td)
            var awayGoalsInput = $("<input class=\"form-control\" min=\"0\" type=\"number\" />").appendTo(formGroup)
            if (match.awayGoals !== undefined)
            {
                awayGoalsInput.val(match.awayGoals)
            }
            awayGoalsInput.change
            (
                function ()
                {
                    match.awayGoals = parseInt(awayGoalsInput.val())
                    calculateTable(matchday)
                }
            )
            if (matchday !== 0)
            {
                td = $("	").appendTo(tr)
                var moveUpButton = $("<button class=\"btn btn-warning\">←</button>").appendTo(td)
                moveUpButton.click
                (
                    function ()
                    {
                        matches[matchday - 1].push(matches[matchday].splice(i, 1)[0])
                        loadMatchday(matchday)
                    }
                )
            }
            if (matchday !== matches.length - 1)
            {
                td = $("	").appendTo(tr)
                var moveDownButton = $("<button class=\"btn btn-warning\">→</button>").appendTo(td)
                moveDownButton.click
                (
                    function ()
                    {
                        matches[matchday + 1].push(matches[matchday].splice(i, 1)[0])
                        loadMatchday(matchday)
                    }
                )
            }
        }
        createButtons(matchday, i)
    }
    $("
Tabelle
").appendTo(column)
    $("

").appendTo(column)
    calculateTable(matchday)
}

var updateMatchdayControl = function ()
{
    $("#matchdays").empty()
    var buttonGroup = $("

").appendTo("#matchdays")
    var settings = $("<button class=\"btn btn-default matchday-button\">Einstellungen</button>").appendTo(buttonGroup)
    settings.click
    (
        function ()
        {
            $(".matchday-button").removeClass("active")
            settings.addClass("active")
            $("#content").empty()
            var row = $("

").appendTo("#content")
            var column = $("

").appendTo(row)
            $("
Einstellungen
").appendTo(column)
            loadSettings()
        }
    )
    var firstMatchdayButton
    for (var i = 0; i < matches.length; i++)
    {
        var initMatchdayButton = function (i)
        {
            var button = $("<button class=\"btn btn-default matchday-button\">" + (i + 1) + "</button>").appendTo(buttonGroup)
            if (i === 0)
            {
                firstMatchdayButton = button
            }
            button.click
            (
                function ()
                {
                    $(".matchday-button").removeClass("active")
                    button.addClass("active")
                    loadMatchday(i)
                }
            )
        }
        initMatchdayButton(i)
    }
    firstMatchdayButton.click()
}
<|endoftext|>


<commit_before>var BenchWarmer = require("./benchwarmer");
Handlebars = require("../lib/handlebars");

var dust, Mustache, eco;

try {
  dust = require("dustjs-linkedin");
} catch (err) { /* NOP */ }

try {
  Mustache = require("mustache");
} catch (err) { /* NOP */ }

try {
  var ecoExports = require("eco");
  eco = function(str) {
    return ecoExports(str);
  };
} catch (err) { /* NOP */ }

var benchDetails = {
  string: {
    context: {},
    handlebars: "Hello world",
    dust: "Hello world",
    mustache: "Hello world",
    eco: "Hello world"
  },
  variables: {
    context: {name: "Mick", count: 30},
    handlebars:  "Hello {{name}}! You have {{count}} new messages.",
    dust: "Hello {name}! You have {count} new messages.",
    mustache: "Hello {{name}}! You have {{count}} new messages.",
    eco: "Hello <%= @name %>! You have <%= @count %> new messages."
  },
  object: {
    context:  { person: { name: "Larry", age: 45 } },
    handlebars: "{{#with person}}{{name}}{{age}}{{/with}}",
    dust: "{#person}{name}{age}{/person}",
    mustache: "{{#person}}{{name}}{{age}}{{/person}}"
  },
  array: {
    context:  { names: [{name: "Moe"}, {name: "Larry"}, {name: "Curly"}, {name: "Shemp"}] },
    handlebars: "{{#each names}}{{name}}{{/each}}",
    dust: "{#names}{name}{/names}",
    mustache: "{{#names}}{{name}}{{/names}}",
    eco: "<% for item in @names: %><%= item.name %><% end %>"
  },
  partial: {
    context: { peeps: [{name: "Moe", count: 15}, {name: "Larry", count: 5}, {name: "Curly", count: 1}] },
    partials: {
      mustache: { variables: "Hello {{name}}! You have {{count}} new messages." },
      handlebars: { variables: "Hello {{name}}! You have {{count}} new messages." }
    },
    handlebars: "{{#each peeps}}{{>variables}}{{/each}}",
    dust: "{#peeps}{>variables/}{/peeps}",
    mustache: "{{#peeps}}{{>variables}}{{/peeps}}"
  },
  recursion: {
    context: { name: '1', kids: [{ name: '1.1', kids: [{name: '1.1.1', kids: []}] }] },
    partials: {
      mustache: { recursion: "{{name}}{{#kids}}{{>recursion}}{{/kids}}" },
      handlebars: { recursion: "{{name}}{{#each kids}}{{>recursion}}{{/each}}" }
    },
    handlebars: "{{name}}{{#each kids}}{{>recursion}}{{/each}}",
    dust: "{name}{#kids}{>recursion:./}{/kids}",
    mustache: "{{name}}{{#kids}}{{>recursion}}{{/kids}}"
  },
  complex: {
    handlebars: "
{{header}}
{{#if items}}
{{#each items}}{{#if current}}" +
                "
{{name}}
{{^}}" +
                "
{{name}}
{{/if}}" +
                "{{/each}}
{{^}}
The list is empty.
{{/if}}",

    dust:       "
{header}
\n"                             +
                "{?items}\n"                                      +
                "
\n"                                        +
                "    {#items}\n"                                  +
                "      {#current}\n"                              +
                "
{name}
\n"      +
                "      {:else}\n"                                 +
                "
{name}
\n" +
                "      {/current}\n"                              +
                "    {/items}\n"                                  +
                "
\n"                                       +
                "{:else}\n"                                       +
                "
The list is empty.
\n"                   +
                "{/items}",
    context: {
               header: function() {
                 return "Colors";
               },
               items: [
                 {name: "red", current: true, url: "#Red"},
                 {name: "green", current: false, url: "#Green"},
                 {name: "blue", current: false, url: "#Blue"}
               ]
             }
  }

};

handlebarsTemplates = {};
ecoTemplates = {};

var warmer = new BenchWarmer();

var makeSuite = function(name) {
  warmer.suite(name, function(bench) {
    var templateName = name;
    var details = benchDetails[templateName];
    var mustachePartials = details.partials && details.partials.mustache;
    var mustacheSource = details.mustache;
    var context = details.context;

    var error = function() { throw new Error("EWOT"); };

    bench("handlebars", function() {
      handlebarsTemplates[templateName](context);
    });

    if (dust) {
      if (details.dust) {
        bench("dust", function() {
          dust.render(templateName, context, function(err, out) { });
        });
      } else {
        bench('dust', error);
      }
    }

    if (eco) {
      if(ecoTemplates[templateName]) {
        bench("eco", function() {
          ecoTemplates[templateName](context);
        });
      } else {
        bench("eco", error);
      }
    }

    if (Mustache) {
      if (mustacheSource) {
        bench("mustache", function() {
          Mustache.to_html(mustacheSource, context, mustachePartials);
        });
      } else {
        bench("mustache", error);
      }
    }
  });
}

for(var name in benchDetails) {
  if(benchDetails.hasOwnProperty(name)) {
    if (!benchDetails[name].handlebars) {
      continue;
    }

    if (dust && benchDetails[name].dust) {
      dust.loadSource(dust.compile(benchDetails[name].dust, name));
    }

    handlebarsTemplates[name] = Handlebars.compile(benchDetails[name].handlebars);

    if (eco && benchDetails[name].eco) {
      ecoTemplates[name] = eco(benchDetails[name].eco);
    }

    var partials = benchDetails[name].partials;
    if(partials) {
      for(var partialName in partials.handlebars) {
        if(partials.handlebars.hasOwnProperty(partialName)) {
          Handlebars.registerPartial(partialName, partials.handlebars[partialName]);
        }
      }
    }

    makeSuite(name);
  }
}

warmer.bench();
<commit_msg>Code style<commit_after>var BenchWarmer = require("./benchwarmer");
Handlebars = require("../lib/handlebars");

var dust, Mustache, eco;

try {
  dust = require("dustjs-linkedin");
} catch (err) { /* NOP */ }

try {
  Mustache = require("mustache");
} catch (err) { /* NOP */ }

try {
  var ecoExports = require("eco");
  eco = function(str) {
    return ecoExports(str);
  };
} catch (err) { /* NOP */ }

var benchDetails = {
  string: {
    context: {},
    handlebars: "Hello world",
    dust: "Hello world",
    mustache: "Hello world",
    eco: "Hello world"
  },
  variables: {
    context: {name: "Mick", count: 30},
    handlebars:  "Hello {{name}}! You have {{count}} new messages.",
    dust: "Hello {name}! You have {count} new messages.",
    mustache: "Hello {{name}}! You have {{count}} new messages.",
    eco: "Hello <%= @name %>! You have <%= @count %> new messages."
  },
  object: {
    context:  { person: { name: "Larry", age: 45 } },
    handlebars: "{{#with person}}{{name}}{{age}}{{/with}}",
    dust: "{#person}{name}{age}{/person}",
    mustache: "{{#person}}{{name}}{{age}}{{/person}}"
  },
  array: {
    context:  { names: [{name: "Moe"}, {name: "Larry"}, {name: "Curly"}, {name: "Shemp"}] },
    handlebars: "{{#each names}}{{name}}{{/each}}",
    dust: "{#names}{name}{/names}",
    mustache: "{{#names}}{{name}}{{/names}}",
    eco: "<% for item in @names: %><%= item.name %><% end %>"
  },
  partial: {
    context: { peeps: [{name: "Moe", count: 15}, {name: "Larry", count: 5}, {name: "Curly", count: 1}] },
    partials: {
      mustache: { variables: "Hello {{name}}! You have {{count}} new messages." },
      handlebars: { variables: "Hello {{name}}! You have {{count}} new messages." }
    },
    handlebars: "{{#each peeps}}{{>variables}}{{/each}}",
    dust: "{#peeps}{>variables/}{/peeps}",
    mustache: "{{#peeps}}{{>variables}}{{/peeps}}"
  },
  recursion: {
    context: { name: '1', kids: [{ name: '1.1', kids: [{name: '1.1.1', kids: []}] }] },
    partials: {
      mustache: { recursion: "{{name}}{{#kids}}{{>recursion}}{{/kids}}" },
      handlebars: { recursion: "{{name}}{{#each kids}}{{>recursion}}{{/each}}" }
    },
    handlebars: "{{name}}{{#each kids}}{{>recursion}}{{/each}}",
    dust: "{name}{#kids}{>recursion:./}{/kids}",
    mustache: "{{name}}{{#kids}}{{>recursion}}{{/kids}}"
  },
  complex: {
    handlebars: "
{{header}}
{{#if items}}
{{#each items}}{{#if current}}" +
                "
{{name}}
{{^}}" +
                "
{{name}}
{{/if}}" +
                "{{/each}}
{{^}}
The list is empty.
{{/if}}",

    dust:       "
{header}
\n"                             +
                "{?items}\n"                                      +
                "
\n"                                        +
                "    {#items}\n"                                  +
                "      {#current}\n"                              +
                "
{name}
\n"      +
                "      {:else}\n"                                 +
                "
{name}
\n" +
                "      {/current}\n"                              +
                "    {/items}\n"                                  +
                "
\n"                                       +
                "{:else}\n"                                       +
                "
The list is empty.
\n"                   +
                "{/items}",
    context: {
               header: function() {
                 return "Colors";
               },
               items: [
                 {name: "red", current: true, url: "#Red"},
                 {name: "green", current: false, url: "#Green"},
                 {name: "blue", current: false, url: "#Blue"}
               ]
             }
  }

};

var handlebarsTemplates = {},
    ecoTemplates = {};

var warmer = new BenchWarmer();

function makeSuite(name) {
  warmer.suite(name, function(bench) {
    var templateName = name;
    var details = benchDetails[templateName];
    var mustachePartials = details.partials && details.partials.mustache;
    var mustacheSource = details.mustache;
    var context = details.context;

    var error = function() { throw new Error("EWOT"); };

    bench("handlebars", function() {
      handlebarsTemplates[templateName](context);
    });

    if (dust) {
      if (details.dust) {
        bench("dust", function() {
          dust.render(templateName, context, function(err, out) { });
        });
      } else {
        bench('dust', error);
      }
    }

    if (eco) {
      if(ecoTemplates[templateName]) {
        bench("eco", function() {
          ecoTemplates[templateName](context);
        });
      } else {
        bench("eco", error);
      }
    }

    if (Mustache) {
      if (mustacheSource) {
        bench("mustache", function() {
          Mustache.to_html(mustacheSource, context, mustachePartials);
        });
      } else {
        bench("mustache", error);
      }
    }
  });
}

for(var name in benchDetails) {
  if(benchDetails.hasOwnProperty(name)) {
    if (!benchDetails[name].handlebars) {
      continue;
    }

    if (dust && benchDetails[name].dust) {
      dust.loadSource(dust.compile(benchDetails[name].dust, name));
    }

    handlebarsTemplates[name] = Handlebars.compile(benchDetails[name].handlebars);

    if (eco && benchDetails[name].eco) {
      ecoTemplates[name] = eco(benchDetails[name].eco);
    }

    var partials = benchDetails[name].partials;
    if(partials) {
      for(var partialName in partials.handlebars) {
        if(partials.handlebars.hasOwnProperty(partialName)) {
          Handlebars.registerPartial(partialName, partials.handlebars[partialName]);
        }
      }
    }

    makeSuite(name);
  }
}

warmer.bench();
<|endoftext|>