<commit_before>// TODO: require('tinytap') when https://github.com/tcr/tinytap/issues/4 and https://github.com/tessel/runtime/pull/279 resolved
var test = require("../../node_modules/ttt/ttt.js" || 'ttt'),
    net = require('net');

test('addresses', function (t) {
  // API checks
  t.ok(net.isIP);
  t.ok(net.isIPv4);
  t.ok(net.isIPv6);

  // some samples from http://publib.boulder.ibm.com/infocenter/ts3500tl/v1r0/index.jsp?topic=%2Fcom.ibm.storage.ts3500.doc%2Fopg_3584_IPv4_IPv6_addresses.html
  // c.f. http://tools.ietf.org/id/draft-main-ipaddr-text-rep-02.txt for some grammar discussion

  var validIPv4 = ["0.0.0.0", "127.0.0.1", "255.255.255.255", "1.2.3.4", "101.203.111.200"/*, "01.102.103.104"*/],
      validIPv6 = [
        "2001:db8:3333:4444:5555:6666:7777:8888", "2001:db8:3333:4444:CCCC:DDDD:EEEE:FFFF",
        "::", "2001:db8::", "::1234:5678", "2001:db8::1234:5678",
        "2001:0db8:0001:0000:0000:0ab9:C0A8:0102", "2001:db8:1::ab9:C0A8:102",
        "2001:db8:3333:4444:5555:6666:1.2.3.4",
        "::11.22.33.44", "2001:db8::123.123.123.123", "::1234:5678:91.123.4.56", "::1234:5678:1.2.3.4", "2001:db8::1234:5678:5.6.7.8",
      ],
      totalBunk = [
        "255.255.255.256", "0xFF.0xFF.0xFF.0xFF", "0.0.A.0", "-1.0.0.0", "123.45.67.89zzz", "01.102.103.104",
        "::11.22.33.044", "::255.255.255.256", "::FG", "hello world", void 0, 42, ""
      ];

  // isIP
  validIPv4.forEach(function (v) {
    t.equal(net.isIP(v), 4, v);
  });
  validIPv6.forEach(function (v) {
    t.equal(net.isIP(v), 6, v);
  });
  totalBunk.forEach(function (v) {
    t.equal(net.isIP(v), 0, v);
  });

  // isIPv4
  validIPv4.forEach(function (v) {
    t.equal(net.isIPv4(v), true, v);
  });
  validIPv6.forEach(function (v) {
    t.equal(net.isIPv4(v), false, v);
  });
  totalBunk.forEach(function (v) {
    t.equal(net.isIPv4(v), false, v);
  });

  // isIPv6
  validIPv4.forEach(function (v) {
    t.equal(net.isIPv6(v), false, v);
  });
  validIPv6.forEach(function (v) {
    t.equal(net.isIPv6(v), true, v);
  });
  totalBunk.forEach(function (v) {
    t.equal(net.isIPv6(v), false, v);
  });

  t.end();
});

test('client-basic', function (t) {
  // API checks
  t.ok(net.createConnection, "method available");
  t.ok(net.connect, "method available");

  // see http://nodejs.org/api/net.html#net_net_connect_options_connectionlistener

  // connects
  var client = net.connect(80, "ipcalf.com", function () {
    t.pass("callback called");
  });
  t.ok(client instanceof net.Socket, "returned socket");
  client.on('connect', function () {
    t.pass("socket connected");
    client.write("GET / HTTP/1.1\nHost: ipcalf.com\nAccept: text/plain\n\n");
  });
  client.on('error', function () {
    t.fail("socket error");
  });

  // lives/dies
  client.on('data', function (d) {
    t.equal(d.slice(0,8).toString(), "HTTP/1.1", "got response");
    client.end();
  });
  client.on('end', function () {
    t.ok(true, "socket closed");
    t.end();
  });
});

test('server-basic', function (t) {
  // API checks
  t.ok(net.createServer, "method available");

  // see http://nodejs.org/api/net.html#net_net_createserver_options_connectionlistener

  // listening
  var server = net.createServer(function (c) {
    t.pass("connection callback called");
  });
  server.listen(0, function () {
     t.pass("listening callback called");
  });
  server.on('listening', function () {
    t.pass("got listening event");
    t.ok(server.address().port, "port assigned");
    testConnection(server.address().port);
  });

  // connecting
  server.on('connection', function (c) {
    t.ok(c instanceof net.Socket, "got connection");
    c.on('end', function () {
      t.pass("disconnected");
    });
    c.end("«§»");
  });
  function testConnection(port) {
    //net.connect(port).on('data', function (d) {
    // WORKAROUND: https://github.com/tessel/runtime/issues/311
    net.connect(port, "localhost").on('data', function (d) {
      t.equal(d.toString(), "«§»");
      t.end();
    });
  }
});
<commit_msg>adds a test for port binding behavior, fixes #331<commit_after>// TODO: require('tinytap') when https://github.com/tcr/tinytap/issues/4 and https://github.com/tessel/runtime/pull/279 resolved
var test = require("../../node_modules/ttt/ttt.js" || 'ttt'),
    net = require('net');

test('addresses', function (t) {
  // API checks
  t.ok(net.isIP);
  t.ok(net.isIPv4);
  t.ok(net.isIPv6);

  // some samples from http://publib.boulder.ibm.com/infocenter/ts3500tl/v1r0/index.jsp?topic=%2Fcom.ibm.storage.ts3500.doc%2Fopg_3584_IPv4_IPv6_addresses.html
  // c.f. http://tools.ietf.org/id/draft-main-ipaddr-text-rep-02.txt for some grammar discussion

  var validIPv4 = ["0.0.0.0", "127.0.0.1", "255.255.255.255", "1.2.3.4", "101.203.111.200"/*, "01.102.103.104"*/],
      validIPv6 = [
        "2001:db8:3333:4444:5555:6666:7777:8888", "2001:db8:3333:4444:CCCC:DDDD:EEEE:FFFF",
        "::", "2001:db8::", "::1234:5678", "2001:db8::1234:5678",
        "2001:0db8:0001:0000:0000:0ab9:C0A8:0102", "2001:db8:1::ab9:C0A8:102",
        "2001:db8:3333:4444:5555:6666:1.2.3.4",
        "::11.22.33.44", "2001:db8::123.123.123.123", "::1234:5678:91.123.4.56", "::1234:5678:1.2.3.4", "2001:db8::1234:5678:5.6.7.8",
      ],
      totalBunk = [
        "255.255.255.256", "0xFF.0xFF.0xFF.0xFF", "0.0.A.0", "-1.0.0.0", "123.45.67.89zzz", "01.102.103.104",
        "::11.22.33.044", "::255.255.255.256", "::FG", "hello world", void 0, 42, ""
      ];

  // isIP
  validIPv4.forEach(function (v) {
    t.equal(net.isIP(v), 4, v);
  });
  validIPv6.forEach(function (v) {
    t.equal(net.isIP(v), 6, v);
  });
  totalBunk.forEach(function (v) {
    t.equal(net.isIP(v), 0, v);
  });

  // isIPv4
  validIPv4.forEach(function (v) {
    t.equal(net.isIPv4(v), true, v);
  });
  validIPv6.forEach(function (v) {
    t.equal(net.isIPv4(v), false, v);
  });
  totalBunk.forEach(function (v) {
    t.equal(net.isIPv4(v), false, v);
  });

  // isIPv6
  validIPv4.forEach(function (v) {
    t.equal(net.isIPv6(v), false, v);
  });
  validIPv6.forEach(function (v) {
    t.equal(net.isIPv6(v), true, v);
  });
  totalBunk.forEach(function (v) {
    t.equal(net.isIPv6(v), false, v);
  });

  t.end();
});

test('client-basic', function (t) {
  // API checks
  t.ok(net.createConnection, "method available");
  t.ok(net.connect, "method available");

  // see http://nodejs.org/api/net.html#net_net_connect_options_connectionlistener

  // connects
  var client = net.connect(80, "ipcalf.com", function () {
    t.pass("callback called");
  });
  t.ok(client instanceof net.Socket, "returned socket");
  client.on('connect', function () {
    t.pass("socket connected");
    client.write("GET / HTTP/1.1\nHost: ipcalf.com\nAccept: text/plain\n\n");
  });
  client.on('error', function () {
    t.fail("socket error");
  });

  // lives/dies
  client.on('data', function (d) {
    t.equal(d.slice(0,8).toString(), "HTTP/1.1", "got response");
    client.end();
  });
  client.on('end', function () {
    t.ok(true, "socket closed");
    t.end();
  });
});

test('server-basic', function (t) {
  // API checks
  t.ok(net.createServer, "method available");

  // see http://nodejs.org/api/net.html#net_net_createserver_options_connectionlistener

  // listening
  var server = net.createServer(function (c) {
    t.pass("connection callback called");
  });
  server.listen(0, function () {
     t.pass("listening callback called");
  });
  server.on('listening', function () {
    t.pass("got listening event");
    t.ok(server.address().port, "port assigned");
    testConnection(server.address().port);
  });

  // connecting
  server.on('connection', function (c) {
    t.ok(c instanceof net.Socket, "got connection");
    c.on('end', function () {
      t.pass("disconnected");
    });
    c.end("«§»");
  });
  function testConnection(port) {
    //net.connect(port).on('data', function (d) {
    // WORKAROUND: https://github.com/tessel/runtime/issues/311
    net.connect(port, "localhost").on('data', function (d) {
      t.equal(d.toString(), "«§»");
      t.end();
    });
  }
});

test('server-binding', function (t) {
  var firstServer = net.createServer(),
      otherServer = net.createServer(),
      conflicting = net.createServer();
  firstServer.listen(0, function () {
    var firstPort = firstServer.address().port;
    t.ok(firstPort, "assigned a port");
    otherServer.listen(0, function () {
      t.notEqual(otherServer.address().port, firstPort, "assigned a different port");
    });
    conflicting.listen(firstPort, function () {
      t.fail("this should not be called!");
    });
    conflicting.on('error', function (e) {
      t.ok(e, "got error as expected");
      t.end();
    });
  });
});
<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const md5 = require('md5');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

const CACHE_INVALIDATE = getCacheInvalidateString();
const NODE_MODULE_PATH = path.join(__dirname, 'node_modules');
const SETTINGS_PATH = process.env.SETTINGS_PATH || './settings.js';
const THREADS = getThreadLoaderThreads();

function configure(env, webpackOpts) {
  const WEBPACK_MODE = (webpackOpts && webpackOpts.mode) || 'development';
  const IS_PRODUCTION = WEBPACK_MODE === 'production';

  console.log('Webpack mode: ' + WEBPACK_MODE);

  const config = {
    context: __dirname,
    mode: WEBPACK_MODE,
    stats: 'errors-only',
    watch: process.env.WATCH === 'true',
    entry: {
      settings: SETTINGS_PATH,
      'settings-local': './settings-local.js',
      app: './app/scripts/app.ts',
    },
    output: {
      path: path.join(__dirname, 'build', 'webpack', process.env.SPINNAKER_ENV || ''),
      filename: '[name].js',
    },
    devtool: IS_PRODUCTION ? 'source-map' : 'eval',
    optimization: {
      splitChunks: { chunks: 'all' },
      minimizer: [],
      // TODO(dpeach): figure out how we can minify deck-kayenta without breaking Angular DI.
      // minimizer: IS_PRODUCTION ? [
      //   new UglifyJSPlugin({
      //     parallel: true,
      //     cache: true,
      //     test: /vendors/,
      //     sourceMap: true,
      //   }),
      // ] : [], // Disable minification unless production
    },
    resolve: {
      extensions: ['.json', '.ts', '.tsx', '.js', '.jsx', '.css', '.less', '.html'],
      modules: [NODE_MODULE_PATH, path.join(__dirname, 'app', 'scripts', 'modules')],
      alias: {
        root: __dirname,
        core: path.join(__dirname, 'app', 'scripts', 'modules', 'core', 'src'),
        '@spinnaker/core': path.join(__dirname, 'app', 'scripts', 'modules', 'core', 'src'),
        docker: path.join(__dirname, 'app', 'scripts', 'modules', 'docker', 'src'),
        '@spinnaker/docker': path.join(__dirname, 'app', 'scripts', 'modules', 'docker', 'src'),
        amazon: path.join(__dirname, 'app', 'scripts', 'modules', 'amazon', 'src'),
        '@spinnaker/amazon': path.join(__dirname, 'app', 'scripts', 'modules', 'amazon', 'src'),
        '@spinnaker/titus': path.join(__dirname, 'app', 'scripts', 'modules', 'titus', 'src'),
        google: path.join(__dirname, 'app', 'scripts', 'modules', 'google', 'src'),
        '@spinnaker/google': path.join(__dirname, 'app', 'scripts', 'modules', 'google', 'src'),
        kubernetes: path.join(__dirname, 'app', 'scripts', 'modules', 'kubernetes', 'src'),
        '@spinnaker/kubernetes': path.join(__dirname, 'app', 'scripts', 'modules', 'kubernetes', 'src'),
        openstack: path.join(__dirname, 'app', 'scripts', 'modules', 'openstack', 'src'),
        '@spinnaker/openstack': path.join(__dirname, 'app', 'scripts', 'modules', 'openstack', 'src'),
        coreImports: path.resolve(
          __dirname,
          'app',
          'scripts',
          'modules',
          'core',
          'src',
          'presentation',
          'less',
          'imports',
          'commonImports.less',
        ),
        appengine: path.join(__dirname, 'app', 'scripts', 'modules', 'appengine', 'src'),
        '@spinnaker/appengine': path.join(__dirname, 'app', 'scripts', 'modules', 'appengine', 'src'),
      },
    },
    module: {
      rules: [
        {
          test: /settings\.js/,
          use: [{ loader: 'envify-loader' }],
        },
        {
          test: /\.js$/,
          use: [
            { loader: 'cache-loader', options: { cacheIdentifier: CACHE_INVALIDATE } },
            { loader: 'thread-loader', options: { workers: THREADS } },
            { loader: 'babel-loader' },
            { loader: 'eslint-loader' },
          ],
          exclude: /(node_modules(?!\/clipboard)|settings\.js)/,
        },
        {
          test: /\.tsx?$/,
          use: [
            { loader: 'cache-loader', options: { cacheIdentifier: CACHE_INVALIDATE } },
            { loader: 'thread-loader', options: { workers: THREADS } },
            { loader: 'babel-loader' },
            { loader: 'ts-loader', options: { happyPackMode: true } },
            { loader: 'tslint-loader' },
          ],
          exclude: /node_modules/,
        },
        {
          test: /\.less$/,
          use: [
            { loader: 'style-loader' },
            { loader: 'css-loader' },
            { loader: 'postcss-loader' },
            { loader: 'less-loader' },
          ],
        },
        {
          test: /\.css$/,
          use: [{ loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'postcss-loader' }],
        },
        {
          test: /\.html$/,
          use: [{ loader: 'ngtemplate-loader?relativeTo=' + path.resolve(__dirname) + '/' }, { loader: 'html-loader' }],
        },
        {
          test: /\.(woff|woff2|otf|ttf|eot|png|gif|ico|svg)$/,
          use: [{ loader: 'file-loader', options: { name: '[name].[hash:5].[ext]' } }],
        },
        {
          test: require.resolve('jquery'),
          use: [{ loader: 'expose-loader?$' }, { loader: 'expose-loader?jQuery' }],
        },
        {
          test: /ui-sortable/,
          use: ['imports-loader?$UI=jquery-ui/ui/widgets/sortable'],
        },
      ],
    },
    plugins: [
      new ForkTsCheckerWebpackPlugin({ checkSyntacticErrors: true, tslint: true }),
      new CopyWebpackPlugin([
        {
          from: `${NODE_MODULE_PATH}/@spinnaker/styleguide/public/styleguide.html`,
          to: `./styleguide.html`,
        },
      ]),
      new HtmlWebpackPlugin({
        title: 'Spinnaker',
        template: './app/index.deck',
        favicon: process.env.NODE_ENV === 'production' ? 'app/prod-favicon.ico' : 'app/dev-favicon.ico',
        inject: true,
      }),
    ],
    devServer: {
      disableHostCheck: true,
      port: process.env.DECK_PORT || 9000,
      host: process.env.DECK_HOST || 'localhost',
      https: process.env.DECK_HTTPS === 'true',
      stats: 'errors-only',
    },
    externals: {
      'react/addons': 'react',
      'react/lib/ExecutionEnvironment': 'react',
      'react/lib/ReactContext': 'react',
    },
  };

  if (process.env.DECK_CERT) {
    config.devServer.cert = fs.readFileSync(process.env.DECK_CERT);
    config.devServer.key = fs.readFileSync(process.env.DECK_KEY);
    if (process.env.DECK_CA_CERT) {
      config.devServer.cacert = fs.readFileSync(process.env.DECK_CA_CERT);
    }
  }

  return config;
}

// invalidate webpack cache when webpack config is changed or cache-loader is updated,
function getCacheInvalidateString() {
  return JSON.stringify({
    CACHE_LOADER: require('cache-loader/package.json').version,
    WEBPACK_CONFIG: md5(fs.readFileSync(__filename)),
  });
}

// When running locally, use one less than the physical number of cpus
// When running on travis, use max of 2 threads
// https://docs.travis-ci.com/user/reference/overview/#Virtualization-environments
function getThreadLoaderThreads() {
  const bareMetalThreads = Math.max(require('physical-cpu-count') - 1, 1);
  const travisThreads = Math.min(require('physical-cpu-count'), 2);
  const autoThreads = !!process.env.TRAVIS ? travisThreads : bareMetalThreads;
  const threads = process.env.THREADS || autoThreads;

  console.log(
    `INFO: cpus: ${
      require('os').cpus().length
    } physical: ${require('physical-cpu-count')} thread-loader threads: ${threads}`,
  );

  return threads;
}

module.exports = configure;
<commit_msg>fix(build): re-minify build (#5239)<commit_after>const fs = require('fs');
const path = require('path');
const md5 = require('md5');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

const CACHE_INVALIDATE = getCacheInvalidateString();
const NODE_MODULE_PATH = path.join(__dirname, 'node_modules');
const SETTINGS_PATH = process.env.SETTINGS_PATH || './settings.js';
const THREADS = getThreadLoaderThreads();

function configure(env, webpackOpts) {
  const WEBPACK_MODE = (webpackOpts && webpackOpts.mode) || 'development';
  const IS_PRODUCTION = WEBPACK_MODE === 'production';

  console.log('Webpack mode: ' + WEBPACK_MODE);

  const config = {
    context: __dirname,
    mode: WEBPACK_MODE,
    stats: 'errors-only',
    watch: process.env.WATCH === 'true',
    entry: {
      settings: SETTINGS_PATH,
      'settings-local': './settings-local.js',
      app: './app/scripts/app.ts',
    },
    output: {
      path: path.join(__dirname, 'build', 'webpack', process.env.SPINNAKER_ENV || ''),
      filename: '[name].js',
    },
    devtool: IS_PRODUCTION ? 'source-map' : 'eval',
    optimization: {
      splitChunks: { chunks: 'all' },
      minimizer: IS_PRODUCTION
        ? [
            new UglifyJSPlugin({
              parallel: true,
              cache: true,
              test: /vendors/,
              sourceMap: true,
              uglifyOptions: { mangle: false },
            }),
          ]
        : [], // Disable minification unless production
    },
    resolve: {
      extensions: ['.json', '.ts', '.tsx', '.js', '.jsx', '.css', '.less', '.html'],
      modules: [NODE_MODULE_PATH, path.join(__dirname, 'app', 'scripts', 'modules')],
      alias: {
        root: __dirname,
        core: path.join(__dirname, 'app', 'scripts', 'modules', 'core', 'src'),
        '@spinnaker/core': path.join(__dirname, 'app', 'scripts', 'modules', 'core', 'src'),
        docker: path.join(__dirname, 'app', 'scripts', 'modules', 'docker', 'src'),
        '@spinnaker/docker': path.join(__dirname, 'app', 'scripts', 'modules', 'docker', 'src'),
        amazon: path.join(__dirname, 'app', 'scripts', 'modules', 'amazon', 'src'),
        '@spinnaker/amazon': path.join(__dirname, 'app', 'scripts', 'modules', 'amazon', 'src'),
        '@spinnaker/titus': path.join(__dirname, 'app', 'scripts', 'modules', 'titus', 'src'),
        google: path.join(__dirname, 'app', 'scripts', 'modules', 'google', 'src'),
        '@spinnaker/google': path.join(__dirname, 'app', 'scripts', 'modules', 'google', 'src'),
        kubernetes: path.join(__dirname, 'app', 'scripts', 'modules', 'kubernetes', 'src'),
        '@spinnaker/kubernetes': path.join(__dirname, 'app', 'scripts', 'modules', 'kubernetes', 'src'),
        openstack: path.join(__dirname, 'app', 'scripts', 'modules', 'openstack', 'src'),
        '@spinnaker/openstack': path.join(__dirname, 'app', 'scripts', 'modules', 'openstack', 'src'),
        coreImports: path.resolve(
          __dirname,
          'app',
          'scripts',
          'modules',
          'core',
          'src',
          'presentation',
          'less',
          'imports',
          'commonImports.less',
        ),
        appengine: path.join(__dirname, 'app', 'scripts', 'modules', 'appengine', 'src'),
        '@spinnaker/appengine': path.join(__dirname, 'app', 'scripts', 'modules', 'appengine', 'src'),
      },
    },
    module: {
      rules: [
        {
          test: /settings\.js/,
          use: [{ loader: 'envify-loader' }],
        },
        {
          test: /\.js$/,
          use: [
            { loader: 'cache-loader', options: { cacheIdentifier: CACHE_INVALIDATE } },
            { loader: 'thread-loader', options: { workers: THREADS } },
            { loader: 'babel-loader' },
            { loader: 'eslint-loader' },
          ],
          exclude: /(node_modules(?!\/clipboard)|settings\.js)/,
        },
        {
          test: /\.tsx?$/,
          use: [
            { loader: 'cache-loader', options: { cacheIdentifier: CACHE_INVALIDATE } },
            { loader: 'thread-loader', options: { workers: THREADS } },
            { loader: 'babel-loader' },
            { loader: 'ts-loader', options: { happyPackMode: true } },
            { loader: 'tslint-loader' },
          ],
          exclude: /node_modules/,
        },
        {
          test: /\.less$/,
          use: [
            { loader: 'style-loader' },
            { loader: 'css-loader' },
            { loader: 'postcss-loader' },
            { loader: 'less-loader' },
          ],
        },
        {
          test: /\.css$/,
          use: [{ loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'postcss-loader' }],
        },
        {
          test: /\.html$/,
          use: [{ loader: 'ngtemplate-loader?relativeTo=' + path.resolve(__dirname) + '/' }, { loader: 'html-loader' }],
        },
        {
          test: /\.(woff|woff2|otf|ttf|eot|png|gif|ico|svg)$/,
          use: [{ loader: 'file-loader', options: { name: '[name].[hash:5].[ext]' } }],
        },
        {
          test: require.resolve('jquery'),
          use: [{ loader: 'expose-loader?$' }, { loader: 'expose-loader?jQuery' }],
        },
        {
          test: /ui-sortable/,
          use: ['imports-loader?$UI=jquery-ui/ui/widgets/sortable'],
        },
      ],
    },
    plugins: [
      new ForkTsCheckerWebpackPlugin({ checkSyntacticErrors: true, tslint: true }),
      new CopyWebpackPlugin([
        {
          from: `${NODE_MODULE_PATH}/@spinnaker/styleguide/public/styleguide.html`,
          to: `./styleguide.html`,
        },
      ]),
      new HtmlWebpackPlugin({
        title: 'Spinnaker',
        template: './app/index.deck',
        favicon: process.env.NODE_ENV === 'production' ? 'app/prod-favicon.ico' : 'app/dev-favicon.ico',
        inject: true,
      }),
    ],
    devServer: {
      disableHostCheck: true,
      port: process.env.DECK_PORT || 9000,
      host: process.env.DECK_HOST || 'localhost',
      https: process.env.DECK_HTTPS === 'true',
      stats: 'errors-only',
    },
    externals: {
      'react/addons': 'react',
      'react/lib/ExecutionEnvironment': 'react',
      'react/lib/ReactContext': 'react',
    },
  };

  if (process.env.DECK_CERT) {
    config.devServer.cert = fs.readFileSync(process.env.DECK_CERT);
    config.devServer.key = fs.readFileSync(process.env.DECK_KEY);
    if (process.env.DECK_CA_CERT) {
      config.devServer.cacert = fs.readFileSync(process.env.DECK_CA_CERT);
    }
  }

  return config;
}

// invalidate webpack cache when webpack config is changed or cache-loader is updated,
function getCacheInvalidateString() {
  return JSON.stringify({
    CACHE_LOADER: require('cache-loader/package.json').version,
    WEBPACK_CONFIG: md5(fs.readFileSync(__filename)),
  });
}

// When running locally, use one less than the physical number of cpus
// When running on travis, use max of 2 threads
// https://docs.travis-ci.com/user/reference/overview/#Virtualization-environments
function getThreadLoaderThreads() {
  const bareMetalThreads = Math.max(require('physical-cpu-count') - 1, 1);
  const travisThreads = Math.min(require('physical-cpu-count'), 2);
  const autoThreads = !!process.env.TRAVIS ? travisThreads : bareMetalThreads;
  const threads = process.env.THREADS || autoThreads;

  console.log(
    `INFO: cpus: ${
      require('os').cpus().length
    } physical: ${require('physical-cpu-count')} thread-loader threads: ${threads}`,
  );

  return threads;
}

module.exports = configure;
<|endoftext|>


<commit_before>let express = require('express');
let app = express();
let mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/testingSkilletHub');
let port = process.env.PORT || 3000;

require('./middleware.js')(app, express);
require('./routes.js')(app, express);

app.listen(port, function() {
  console.log('Now running on port: ', port);
});<commit_msg>Insert tags into db at server start<commit_after>let express = require('express');
let app = express();
let mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/testingSkilletHub');
let port = process.env.PORT || 3000;
let tags = require(`${__dirname}/tags.js`);
let Tag = require(`${__dirname}/schemas.js`).Tag;

require('./middleware.js')(app, express);
require('./routes.js')(app, express);

app.listen(port, function() {
  console.log('Now running on port: ', port);

  Tag.find().then(results => {
    return results.length < 1 ? Tag.create(tags.tags) : 'existing';
  }).then(result => {
    if (result !== 'existing') {
      console.log('Tags inserted');
    }
  }).catch(error => {
    console.log(error);
  });
});<|endoftext|>


<commit_before>//main game logic, including the primary parse logic

'use strict'

const express = require('express');
const request = require('request');
const db = require('./db.js');
const fb = require('./fb.js');
const player = require('./player.js');
const message_templates = require('./message_templates.js');

/**
 * Parse ICM based on user postback, and depending on user current state. Send relevant OGM
 * @param user_id
 * @param messageItem
 * @param userObj
 */
function parseIncoming(user_id, messageItem, userObj) {
	var current_state = "welcome_message";
	if (userObj != null) {
		current_state = userObj.current_state;
	}

	// If the user sends us anything with a payload
	if ((messageItem.postback && messageItem.postback.payload)){
		var button_payload_state = messageItem.postback.payload;

    console.log("Received postback "+button_payload_state);

		switch (button_payload_state) {
			case "get_options":
				fb.sendGeneric(user_id, message_templates.templates["options_message"]);
				break;
			case "no_options":
				fb.sendText(user_id, "Ok. There is so much you can do with stateful bots!");
				break;
      case "Greeting":
        fb.sendGeneric(user_id,message_templates.templates["greeting_template"]);
        break;
			case "FAMILY_REPORT_PAYLOAD":
				fb.sendGeneric(user_id,message_templates.templates["family_options"]);
				break;
			case "NET_WORTH_PAYLOAD":
				fb.sendGeneric(user_id,message_templates.templates["quick_reply_test"]);
				break;
			case "CAPOS_PAYLOAD":
				fb.sendGeneric(user_id,message_templates.templates["capo_list_static"]);
				break;
			case "TUTORIAL_PAYLOAD":
				fb.sendGeneric(user_id,message_templates.templates["tutorial_template"]);
				break;
			case "CAPO_CRAZY_IVAN_CONTACT":
				fb.sendText(user_id,"I'm free boss, what do you want me to do?");
					fb.sendGeneric(user_id,message_templates.templates["capo_job_template"]);
					break;
			case "DB_PAYLOAD":
					fb.sendText(user_id,""+userObj);
					break;
			default:
        fb.sendText(user_id,"you want to "+button_payload_state);
        break;
		}
	}

	//if user sent with a quick reply
	else if (messageItem.message.quick_reply.payload){
		// need to convert this to a switch at some point
		fb.sendText(user_id,"Got a quick reply: "+messageItem.message.quick_reply.payload);
}

	// If we recieve any text message, parse and respond accordingly
	else if(messageItem.message && messageItem.message.text) {

		switch (messageItem.message.text) {
			case 'generic':
				fb.sendGeneric(user_id, message_templates.templates["welcome_message"]);
				break;
			case 'add':
				player.addMoney(user_id, userObj, 100);
				break;
			default:
			//sending a repeat back to user
			fb.sendText(user_id, messageItem.message.text+" from heroku");
		}

	}
	// Save new user state. If user does not exist in DB, will create a new user.
	db.setUserFieldById(user_id, "current_state", "");
}

module.exports = {
	parseIncoming:parseIncoming
};
<commit_msg>adding reset function<commit_after>//main game logic, including the primary parse logic

'use strict'

const express = require('express');
const request = require('request');
const db = require('./db.js');
const fb = require('./fb.js');
const player = require('./player.js');
const message_templates = require('./message_templates.js');

/**
 * Parse ICM based on user postback, and depending on user current state. Send relevant OGM
 * @param user_id
 * @param messageItem
 * @param userObj
 */
function parseIncoming(user_id, messageItem, userObj) {
	var current_state = "welcome_message";
	if (userObj != null) {
		current_state = userObj.current_state;
	}

	// If the user sends us anything with a payload
	if ((messageItem.postback && messageItem.postback.payload)){
		var button_payload_state = messageItem.postback.payload;

    console.log("Received postback "+button_payload_state);

		switch (button_payload_state) {
			case "get_options":
				fb.sendGeneric(user_id, message_templates.templates["options_message"]);
				break;
			case "no_options":
				fb.sendText(user_id, "Ok. There is so much you can do with stateful bots!");
				break;
      case "Greeting":
        fb.sendGeneric(user_id,message_templates.templates["greeting_template"]);
        break;
			case "FAMILY_REPORT_PAYLOAD":
				fb.sendGeneric(user_id,message_templates.templates["family_options"]);
				break;
			case "NET_WORTH_PAYLOAD":
				fb.sendGeneric(user_id,message_templates.templates["quick_reply_test"]);
				break;
			case "CAPOS_PAYLOAD":
				fb.sendGeneric(user_id,message_templates.templates["capo_list_static"]);
				break;
			case "TUTORIAL_PAYLOAD":
				fb.sendGeneric(user_id,message_templates.templates["tutorial_template"]);
				break;
			case "CAPO_CRAZY_IVAN_CONTACT":
				fb.sendText(user_id,"I'm free boss, what do you want me to do?");
					fb.sendGeneric(user_id,message_templates.templates["capo_job_template"]);
					break;
			case "DB_PAYLOAD":
					fb.sendText(user_id,""+userObj);
					break;
			default:
        fb.sendText(user_id,"you want to "+button_payload_state);
        break;
		}
	}

	//if user sent with a quick reply
	else if (messageItem.message.quick_reply.payload){
		// need to convert this to a switch at some point
		fb.sendText(user_id,"Got a quick reply: "+messageItem.message.quick_reply.payload);
}

	// If we recieve any text message, parse and respond accordingly
	else if(messageItem.message && messageItem.message.text) {

		switch (messageItem.message.text.toLowerCase()) {
			case 'generic':
				fb.sendGeneric(user_id, message_templates.templates["welcome_message"]);
				break;
			case 'add':
				player.addMoney(user_id, userObj, 100);
				break;
			case 'reset':
				fb.sendText(user_id,"resetting your user db entry");
				db.getAndSetNewUser(user_id);
				fb.sendText(user_id,"reset");
			default:
			//sending a repeat back to user
			fb.sendText(user_id, messageItem.message.text+" from heroku");
		}

	}
	// Save new user state. If user does not exist in DB, will create a new user.
	db.setUserFieldById(user_id, "current_state", "");
}

module.exports = {
	parseIncoming:parseIncoming
};
<|endoftext|>


<commit_before>//var debug = process.env.NODE_ENV !== "production";

var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin')

var scriptConfig = function (env) {
  return {
    context: path.join(__dirname, "src"),
    devtool: (env && env.chain !== "mainnet") ? "inline-sourcemap" : false,
    entry: ['babel-polyfill', "./js/client.js", "./assets/css/app.scss"],
    // resolve: {
    //   modules: [path.resolve(__dirname, "src"), "node_modules"],
    //   alias: {
    //     ETHEREUM_CONSTANT: path.resolve(__dirname, entryChain)
    //   },
    //   extensions: ['.js']
    // },
    module: {
      loaders: [{
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        loader: 'babel-loader',
        query: {
          presets: ['react', 'es2015', 'stage-0'],
          plugins: ['react-html-attrs', 'transform-decorators-legacy', 'transform-class-properties'],
        }
      },
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader'])
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [{
          loader: 'file-loader',
          options: {
            query: {
              name: '[name].[ext]'
            }
          }
        },
        {
          loader: 'image-webpack-loader',
          options: {
            query: {
              mozjpeg: {
                progressive: true,
              },
              gifsicle: {
                interlaced: true,
              },
              optipng: {
                optimizationLevel: 7,
              }
            }
          }
        }
        ]
      }
      ]
    },
    output: {
      path: __dirname + "/src/",
      filename: "client.min.js"
    },
    plugins: (env && env.chain !== "mainnet") ? [
      new ExtractTextPlugin({ // define where to save the file
        filename: 'app.bundle.css',
        allChunks: true,
      }),
      new webpack.DefinePlugin({
        'env': env && env.chain ? '"' + env.chain + '"' : '"kovan"'
      })
    ] : [
        new webpack.optimize.DedupePlugin(),
        new webpack.optimize.OccurrenceOrderPlugin(),
        new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
        new ExtractTextPlugin({ // define where to save the file
          filename: 'app.bundle.css',
          allChunks: true,
        }),
        new webpack.DefinePlugin({
          'env': '"kovan"'
        })
      ],
    devServer: {
      compress: true,
      disableHostCheck: true,
    }
  }
};

var indexConfig = function (env) {
  var HtmlWebpackPlugin = require('html-webpack-plugin')
  return {
    entry: ['./src/client.min.js'],
    output: {
      path: __dirname + '/src',
      filename: 'client.min.js'
    },
    plugins: [
      new HtmlWebpackPlugin({
        hash: true,
        title: "Wallet - kyber.network",
        template: './src/app.html.template',
        inject: 'body',
        styleFile:'app.bundle.css?v=' + Date.now()
      }),

    ]
  }
}

module.exports = [scriptConfig, indexConfig]<commit_msg>fix config<commit_after>//var debug = process.env.NODE_ENV !== "production";

var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin')

var scriptConfig = function (env) {
  return {
    context: path.join(__dirname, "src"),
    devtool: (env && env.chain !== "mainnet") ? "inline-sourcemap" : false,
    entry: ['babel-polyfill', "./js/client.js", "./assets/css/app.scss"],
    // resolve: {
    //   modules: [path.resolve(__dirname, "src"), "node_modules"],
    //   alias: {
    //     ETHEREUM_CONSTANT: path.resolve(__dirname, entryChain)
    //   },
    //   extensions: ['.js']
    // },
    module: {
      loaders: [{
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        loader: 'babel-loader',
        query: {
          presets: ['react', 'es2015', 'stage-0'],
          plugins: ['react-html-attrs', 'transform-decorators-legacy', 'transform-class-properties'],
        }
      },
      {
        test: /\.scss$/,
        loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader'])
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [{
          loader: 'file-loader',
          options: {
            query: {
              name: '[name].[ext]'
            }
          }
        },
        {
          loader: 'image-webpack-loader',
          options: {
            query: {
              mozjpeg: {
                progressive: true,
              },
              gifsicle: {
                interlaced: true,
              },
              optipng: {
                optimizationLevel: 7,
              }
            }
          }
        }
        ]
      }
      ]
    },
    output: {
      path: __dirname + "/src/",
      filename: "client.min.js"
    },
    plugins: (env && env.chain !== "mainnet") ? [
      new ExtractTextPlugin({ // define where to save the file
        filename: 'app.bundle.css',
        allChunks: true,
      }),
      new webpack.DefinePlugin({
        'env': env && env.chain ? '"' + env.chain + '"' : '"kovan"'
      })
    ] : [
        new webpack.optimize.DedupePlugin(),
        new webpack.optimize.OccurrenceOrderPlugin(),
        new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
        new ExtractTextPlugin({ // define where to save the file
          filename: 'app.bundle.css',
          allChunks: true,
        }),
        new webpack.DefinePlugin({
          'env': '"mainnet"'
        })
      ],
    devServer: {
      compress: true,
      disableHostCheck: true,
    }
  }
};

var indexConfig = function (env) {
  var HtmlWebpackPlugin = require('html-webpack-plugin')
  return {
    entry: ['./src/client.min.js'],
    output: {
      path: __dirname + '/src',
      filename: 'client.min.js'
    },
    plugins: [
      new HtmlWebpackPlugin({
        hash: true,
        title: "Wallet - kyber.network",
        template: './src/app.html.template',
        inject: 'body',
        styleFile:'app.bundle.css?v=' + Date.now()
      }),

    ]
  }
}

module.exports = [scriptConfig, indexConfig]<|endoftext|>


<commit_before>// Clear old cache files
(require('./clear-cache')());

var

// Needed modules
fs = require('fs'),
sys = require('sys'),
url = require('url'),
ejs = require('ejs'),
http = require('http'),
path = require('path'),
gzip = require('gzip'),
crypto = require('crypto'),
uglify = require('uglify-js'),
bufferjs = require('bufferjs'),

// Load the config
conf = require('./config'),

// File path constants
CLIENT_PATH = path.join(__dirname, '../client'),
POLYFILL_PATH = path.join(CLIENT_PATH, 'polyfills'),
POLYFILL_CACHE_PATH = path.join(CLIENT_PATH, 'polyfill-cache'),
CORE_FILE = 'core.js',
MIN_EXT = '.min',
GZIP_EXT = '.gz',

// The request handle ID
nextId = 1000,

// Create the http server
server = http.createServer(function(req, res) {

	var handle = {
		id: nextId++,
		req: req,
		res: res,
		url: (function() {
			var urlData = url.parse(req.url, true);
			if (urlData.pathname === '') {
				urlData.pathname = '/';
			}
			urlData.segments = urlData.pathname.split('/');
			return urlData;
		}()),
		responseHeaders: {
			'Content-Type': 'text/plain'
		},
		isJavaScript: function() {
			handle.responseHeaders['Content-Type'] = 'application/javascript';
		},
		gzipSupport: null,
		isGzip: function() {
			handle.gzipSupport = true;
			handle.responseHeaders['Content-Encoding'] = 'gzip';
		},
		error: function(err, msg) {
			handleError(handle, err, msg);
		}
	};

	// Log the request
	sys.puts('[' + handle.id + '] HTTP ' + req.method + ' ' + req.url + ' (for ' + req.client.remoteAddress + ')');

	switch (handle.url.segments[1]) {
		case '':
			fs.readdir(POLYFILL_PATH, function(err, files) {
				if (err) {
					return handle.error(err);
				}
				var welcome = path.join(__dirname, 'welcome.ejs');
				fs.readFile(welcome, function(err, data) {
					if (err) {
						return handle.error(err);
					}
					var body = ejs.render(String(data), {
						locals: {
							files: files
						}
					});
					handle.responseHeaders['Content-Type'] = 'text/html';
					server.ok(handle, body);
				});
			});
		break;

		// Handle loading the core
		case 'core':
			var parseVars = {
				baseurl: conf.baseUrl,
				polyfills: fs.readFileSync(
					path.join(CLIENT_PATH, 'polyfills.js')
				)
			};
			loadJavaScriptFile(CORE_FILE, CLIENT_PATH, CLIENT_PATH, parseVars, function(err, data) {
				if (err) {
					return handle.error(err[0], err[1]);
				}
				// Get the ETag value
				var etag = hash('sha1', data).substring(0, 7);
				// Send a 304 if no changes were made
				var ifNoneMatch = handle.req.headers['if-none-match'] || null;
				if (ifNoneMatch === etag) {
					return server.notModified(handle);
				}
				// If there were changes, send a new ETag header
				handle.responseHeaders['ETag'] = etag;
				// If it needs gzip, handle that...
				if (supportsGzip(handle)) {
					gzipJavaScriptFile(data, CORE_FILE, CLIENT_PATH, function(err, data) {
						if (err) {
							return handle.error(err[0], err[1]);
						}
						handle.isJavaScript();
						server.ok(handle, data);
					});
				} else {
					handle.isJavaScript();
					server.ok(handle, data);
				}
			});
		break;

		// Handle loading polyfills
		case 'polyfill':
			if (! (handle.url.query.p && handle.url.query.p.length)) {
				return server.notFound(handle, '// Error 404: Not Found\n// No polyfills given');
			}
			var id = handle.url.query.id;
			var polyfills = handle.url.query.p.split(',').sort();
			var cacheFile = polyfills.join(',') + '.js';
			var content = '';
			(function getNext() {
				var next = polyfills.shift();
				if (! path.existsSync(path.join(POLYFILL_PATH, next) + '.js')) {
					return server.notFound(handle, '// Error 404: Not Found\n// Polyfill "' + next + '" does not exist');
				}
				loadJavaScriptFile(next + '.js', POLYFILL_PATH, POLYFILL_CACHE_PATH, function(err, data) {
					if (err) {
						return handle.error(err[0], err[1]);
					}
					content += String(data) + ';Polyfill.loaded("' + next + '");';
					if (polyfills.length) {
						getNext();
					} else {
						content += ';Polyfill.done(' + id + ');';
						// Get the ETag value
						var etag = hash('sha1', content).substring(0, 7);
						// Send a 304 if no changes were made
						var ifNoneMatch = handle.req.headers['if-none-match'] || null;
						if (ifNoneMatch === etag) {
							return server.notModified(handle);
						}
						// If there were changes, send a new ETag header
						handle.responseHeaders['ETag'] = etag;
						// Compress the content
						content = uglify(content);
						if (supportsGzip(handle)) {
							gzipJavaScriptFile(content, cacheFile, POLYFILL_CACHE_PATH, function(err, data) {
								if (err) {
									return handle.error(err[0], err[1]);
								}
								handle.isJavaScript();
								server.ok(handle, data);
							});
						} else {
							handle.isJavaScript();
							server.ok(handle, content);
						}
					}
				});
			}());
		break;

		// Unknown route
		default:
			server.notFound(handle, 'Unknown route ' + handle.url.pathname);
		break;
	}

});

// Start listening
server.listen(conf.port, function() {
	sys.puts('Listening on port ' + conf.port);
});

// ----------------------------------------------------------------------------
//  Helpers

// Check if the client supports gziping
function supportsGzip(handle) {
	if (! conf.gzip) {
		handle.gzipSupport = false;
	}
	if (handle.gzipSupport === null) {
		(function() {
			var encodings = handle.req.headers['accept-encoding'] || '';
			encodings = encodings.split(',');
			for (var i = 0, c = encodings.length; i < c; i++) {
				if (encodings[i].trim() === 'gzip') {
					handle.isGzip();
					return;
				}
			}
			handle.gzipSupport = false;
		}());
	}
	return handle.gzipSupport;
};

// Log an error
function logError(error) {
	sys.puts('[E] ' + error);
	console.trace();
};

// Log an error and respond to the client
function handleError(handle, error, msg) {
	logError(error);
	server.internalError(handle, msg);
};

// Do file gzipping and storage
function gzipJavaScriptFile(ugly, file, cacheDir, after) {
	// File paths
	var gzFile = path.join(cacheDir, file) + MIN_EXT + GZIP_EXT;
	path.exists(gzFile, function(exists) {
		if (! exists) {
			// Gzip the source
			gzip(ugly, 9, function(err, data) {
				if (err) {
					return after([err, 'Error: Could not gzip source code']);
				}
				fs.writeFile(gzFile, data);
				after(null, data);
			});
		} else {
			// Read cached gzip source file
			fs.readFile(gzFile, function(err, data) {
				if (err) {
					return after([err, 'Error: Could not read ' + file + '.min.gz']);
				}
				after(null, data);
			});
		}
	});
}

// Load a JavaScript file
function loadJavaScriptFile(file, sourceDir, cacheDir, parseVars, after) {
	// File paths
	var srcFile = path.join(sourceDir, file);
	var minFile = path.join(cacheDir, file) + MIN_EXT;
	// Check for variables given
	if (after === void(0)) {
		after = parseVars;
		parseVars = null;
	}
	// Check if the minified file already exists
	path.exists(minFile, function(exists) {
		var ugly;
		// Minify the original source if not yet done...
		if (! exists) {
			try {
				var orig = String(
					fs.readFileSync(srcFile)
				);
				// Parse the data if needed
				if (parseVars) {
					orig = ejs.render(orig, {
						locals: parseVars
					});
				}
				ugly = uglify(orig);
				// Write to the cache file
				if (! path.existsSync(cacheDir)) {
					fs.mkdirSync(cacheDir, 0777);
				}
				fs.writeFileSync(minFile, ugly);
			} catch (err) {
				return after([err, 'Error: Could not uglify ' + file]);
			}
		}
		// ...or read the already minified source
		else {
			try {
				ugly = fs.readFileSync(minFile);
			} catch (err) {
				return after([err, 'Error: Could not read ' + file + '.min']);
			}
		}
		after(null, ugly);
	});
};

// Hash a string
function hash(alg, str) {
	var hashsum = crypto.createHash(alg);
	// Add the string data
	hashsum.update(str);
	return hashsum.digest('hex');
};

// ----------------------------------------------------------------------------
//  Shortcut functions for sending server responses

// Sends an HTTP response
server.respond = function(handle, status, body) {
	handle.res.writeHead(status, handle.responseHeaders);
	if (status < 300 || status >= 400) {
		handle.res.write(body);
	}
	handle.res.end();
	// Log the response
	sys.puts('[' + handle.id + ']  Response - HTTP ' + status);
};

// Sends a 200 OK
server.ok = function(handle, body) {
	server.respond(handle, 200, body);
};

// Sends a 304 Not Modified
server.notModified = function(handle) {
	server.respond(handle, 304);
};

// Sends a 404 Not Found
server.notFound = function(handle, body) {
	server.respond(handle, 404, body);
};

// Sends a 500 Internal Server Error
server.internalError = function(handle, body) {
	server.respond(handle, 500, body);
};

/* End of file server.js */
<commit_msg>updated server to use "util" instead of "sys"<commit_after>// Clear old cache files
(require('./clear-cache')());

var

// Needed modules
fs = require('fs'),
url = require('url'),
ejs = require('ejs'),
util = require('util'),
http = require('http'),
path = require('path'),
gzip = require('gzip'),
crypto = require('crypto'),
uglify = require('uglify-js'),
bufferjs = require('bufferjs'),

// Load the config
conf = require('./config'),

// File path constants
CLIENT_PATH = path.join(__dirname, '../client'),
POLYFILL_PATH = path.join(CLIENT_PATH, 'polyfills'),
POLYFILL_CACHE_PATH = path.join(CLIENT_PATH, 'polyfill-cache'),
CORE_FILE = 'core.js',
MIN_EXT = '.min',
GZIP_EXT = '.gz',

// The request handle ID
nextId = 1000,

// Create the http server
server = http.createServer(function(req, res) {

	var handle = {
		id: nextId++,
		req: req,
		res: res,
		url: (function() {
			var urlData = url.parse(req.url, true);
			if (urlData.pathname === '') {
				urlData.pathname = '/';
			}
			urlData.segments = urlData.pathname.split('/');
			return urlData;
		}()),
		responseHeaders: {
			'Content-Type': 'text/plain'
		},
		isJavaScript: function() {
			handle.responseHeaders['Content-Type'] = 'application/javascript';
		},
		gzipSupport: null,
		isGzip: function() {
			handle.gzipSupport = true;
			handle.responseHeaders['Content-Encoding'] = 'gzip';
		},
		error: function(err, msg) {
			handleError(handle, err, msg);
		}
	};

	// Log the request
	util.puts('[' + handle.id + '] HTTP ' + req.method + ' ' + req.url + ' (for ' + req.client.remoteAddress + ')');

	switch (handle.url.segments[1]) {
		case '':
			fs.readdir(POLYFILL_PATH, function(err, files) {
				if (err) {
					return handle.error(err);
				}
				var welcome = path.join(__dirname, 'welcome.ejs');
				fs.readFile(welcome, function(err, data) {
					if (err) {
						return handle.error(err);
					}
					var body = ejs.render(String(data), {
						locals: {
							files: files
						}
					});
					handle.responseHeaders['Content-Type'] = 'text/html';
					server.ok(handle, body);
				});
			});
		break;

		// Handle loading the core
		case 'core':
			var parseVars = {
				baseurl: conf.baseUrl,
				polyfills: fs.readFileSync(
					path.join(CLIENT_PATH, 'polyfills.js')
				)
			};
			loadJavaScriptFile(CORE_FILE, CLIENT_PATH, CLIENT_PATH, parseVars, function(err, data) {
				if (err) {
					return handle.error(err[0], err[1]);
				}
				// Get the ETag value
				var etag = hash('sha1', data).substring(0, 7);
				// Send a 304 if no changes were made
				var ifNoneMatch = handle.req.headers['if-none-match'] || null;
				if (ifNoneMatch === etag) {
					return server.notModified(handle);
				}
				// If there were changes, send a new ETag header
				handle.responseHeaders['ETag'] = etag;
				// If it needs gzip, handle that...
				if (supportsGzip(handle)) {
					gzipJavaScriptFile(data, CORE_FILE, CLIENT_PATH, function(err, data) {
						if (err) {
							return handle.error(err[0], err[1]);
						}
						handle.isJavaScript();
						server.ok(handle, data);
					});
				} else {
					handle.isJavaScript();
					server.ok(handle, data);
				}
			});
		break;

		// Handle loading polyfills
		case 'polyfill':
			if (! (handle.url.query.p && handle.url.query.p.length)) {
				return server.notFound(handle, '// Error 404: Not Found\n// No polyfills given');
			}
			var id = handle.url.query.id;
			var polyfills = handle.url.query.p.split(',').sort();
			var cacheFile = polyfills.join(',') + '.js';
			var content = '';
			(function getNext() {
				var next = polyfills.shift();
				if (! path.existsSync(path.join(POLYFILL_PATH, next) + '.js')) {
					return server.notFound(handle, '// Error 404: Not Found\n// Polyfill "' + next + '" does not exist');
				}
				loadJavaScriptFile(next + '.js', POLYFILL_PATH, POLYFILL_CACHE_PATH, function(err, data) {
					if (err) {
						return handle.error(err[0], err[1]);
					}
					content += String(data) + ';Polyfill.loaded("' + next + '");';
					if (polyfills.length) {
						getNext();
					} else {
						content += ';Polyfill.done(' + id + ');';
						// Get the ETag value
						var etag = hash('sha1', content).substring(0, 7);
						// Send a 304 if no changes were made
						var ifNoneMatch = handle.req.headers['if-none-match'] || null;
						if (ifNoneMatch === etag) {
							return server.notModified(handle);
						}
						// If there were changes, send a new ETag header
						handle.responseHeaders['ETag'] = etag;
						// Compress the content
						content = uglify(content);
						if (supportsGzip(handle)) {
							gzipJavaScriptFile(content, cacheFile, POLYFILL_CACHE_PATH, function(err, data) {
								if (err) {
									return handle.error(err[0], err[1]);
								}
								handle.isJavaScript();
								server.ok(handle, data);
							});
						} else {
							handle.isJavaScript();
							server.ok(handle, content);
						}
					}
				});
			}());
		break;

		// Unknown route
		default:
			server.notFound(handle, 'Unknown route ' + handle.url.pathname);
		break;
	}

});

// Start listening
server.listen(conf.port, function() {
	util.puts('Listening on port ' + conf.port);
});

// ----------------------------------------------------------------------------
//  Helpers

// Check if the client supports gziping
function supportsGzip(handle) {
	if (! conf.gzip) {
		handle.gzipSupport = false;
	}
	if (handle.gzipSupport === null) {
		(function() {
			var encodings = handle.req.headers['accept-encoding'] || '';
			encodings = encodings.split(',');
			for (var i = 0, c = encodings.length; i < c; i++) {
				if (encodings[i].trim() === 'gzip') {
					handle.isGzip();
					return;
				}
			}
			handle.gzipSupport = false;
		}());
	}
	return handle.gzipSupport;
};

// Log an error
function logError(error) {
	util.puts('[E] ' + error);
	console.trace();
};

// Log an error and respond to the client
function handleError(handle, error, msg) {
	logError(error);
	server.internalError(handle, msg);
};

// Do file gzipping and storage
function gzipJavaScriptFile(ugly, file, cacheDir, after) {
	// File paths
	var gzFile = path.join(cacheDir, file) + MIN_EXT + GZIP_EXT;
	path.exists(gzFile, function(exists) {
		if (! exists) {
			// Gzip the source
			gzip(ugly, 9, function(err, data) {
				if (err) {
					return after([err, 'Error: Could not gzip source code']);
				}
				fs.writeFile(gzFile, data);
				after(null, data);
			});
		} else {
			// Read cached gzip source file
			fs.readFile(gzFile, function(err, data) {
				if (err) {
					return after([err, 'Error: Could not read ' + file + '.min.gz']);
				}
				after(null, data);
			});
		}
	});
}

// Load a JavaScript file
function loadJavaScriptFile(file, sourceDir, cacheDir, parseVars, after) {
	// File paths
	var srcFile = path.join(sourceDir, file);
	var minFile = path.join(cacheDir, file) + MIN_EXT;
	// Check for variables given
	if (after === void(0)) {
		after = parseVars;
		parseVars = null;
	}
	// Check if the minified file already exists
	path.exists(minFile, function(exists) {
		var ugly;
		// Minify the original source if not yet done...
		if (! exists) {
			try {
				var orig = String(
					fs.readFileSync(srcFile)
				);
				// Parse the data if needed
				if (parseVars) {
					orig = ejs.render(orig, {
						locals: parseVars
					});
				}
				ugly = uglify(orig);
				// Write to the cache file
				if (! path.existsSync(cacheDir)) {
					fs.mkdirSync(cacheDir, 0777);
				}
				fs.writeFileSync(minFile, ugly);
			} catch (err) {
				return after([err, 'Error: Could not uglify ' + file]);
			}
		}
		// ...or read the already minified source
		else {
			try {
				ugly = fs.readFileSync(minFile);
			} catch (err) {
				return after([err, 'Error: Could not read ' + file + '.min']);
			}
		}
		after(null, ugly);
	});
};

// Hash a string
function hash(alg, str) {
	var hashsum = crypto.createHash(alg);
	// Add the string data
	hashsum.update(str);
	return hashsum.digest('hex');
};

// ----------------------------------------------------------------------------
//  Shortcut functions for sending server responses

// Sends an HTTP response
server.respond = function(handle, status, body) {
	handle.res.writeHead(status, handle.responseHeaders);
	if (status < 300 || status >= 400) {
		handle.res.write(body);
	}
	handle.res.end();
	// Log the response
	util.puts('[' + handle.id + ']  Response - HTTP ' + status);
};

// Sends a 200 OK
server.ok = function(handle, body) {
	server.respond(handle, 200, body);
};

// Sends a 304 Not Modified
server.notModified = function(handle) {
	server.respond(handle, 304);
};

// Sends a 404 Not Found
server.notFound = function(handle, body) {
	server.respond(handle, 404, body);
};

// Sends a 500 Internal Server Error
server.internalError = function(handle, body) {
	server.respond(handle, 500, body);
};

/* End of file server.js */
<|endoftext|>


<commit_before>const webpack = require('webpack');
// eslint-disable-next-line prefer-destructuring
const resolve = require('path').resolve;

module.exports = {
  entry: {
    g6: './src/index.ts',
  },
  output: {
    filename: '[name].min.js',
    library: 'G6',
    libraryTarget: 'umd',
    libraryExport: 'default',
    path: resolve(process.cwd(), 'dist/'),
  },
  resolve: {
    // Add `.ts` as a resolvable extension.
    extensions: ['.ts', '.js'],
  },
  module: {
    rules: [
      {
        test: /\.worker\.ts$/,
        exclude: /(node_modules)/,
        use: [
          {
            loader: 'worker-loader',
            options: {
              inline: true,
              fallback: false,
              name: 'g6Layout.worker.js',
            },
          },
        ],
      },
      {
        test: /\.js$/,
        include: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            // babelrc: true,
            presets: [
              '@babel/preset-env',
              plugins: [
                '@babel/plugin-proposal-class-properties'
              ]
            ],
          },
        },
      },
      {
        test: /\.ts$/,
        use: {
          loader: 'ts-loader',
          options: {
            transpileOnly: true,
          },
        },
      },
    ],
  },
  plugins: [new webpack.NoEmitOnErrorsPlugin(), new webpack.optimize.AggressiveMergingPlugin()],
  devtool: 'source-map',
};
<commit_msg>chore: update bablerc, package.json, and webpack.config.js.<commit_after>const webpack = require('webpack');
// eslint-disable-next-line prefer-destructuring
const resolve = require('path').resolve;

module.exports = {
  entry: {
    g6: './src/index.ts',
  },
  output: {
    filename: '[name].min.js',
    library: 'G6',
    libraryTarget: 'umd',
    libraryExport: 'default',
    path: resolve(process.cwd(), 'dist/'),
  },
  resolve: {
    // Add `.ts` as a resolvable extension.
    extensions: ['.ts', '.js'],
  },
  module: {
    rules: [
      {
        test: /\.worker\.ts$/,
        exclude: /(node_modules)/,
        use: [
          {
            loader: 'worker-loader',
            options: {
              inline: true,
              fallback: false,
              name: 'g6Layout.worker.js',
            },
          },
        ],
      },
      {
        test: /\.js$/,
        include: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            // babelrc: true,
            presets: [
              '@babel/preset-env',
              {
                plugins: [
                  '@babel/plugin-proposal-class-properties'
                ]
              }
            ],
          },
        },
      },
      {
        test: /\.ts$/,
        use: {
          loader: 'ts-loader',
          options: {
            transpileOnly: true,
          },
        },
      },
    ],
  },
  plugins: [new webpack.NoEmitOnErrorsPlugin(), new webpack.optimize.AggressiveMergingPlugin()],
  devtool: 'source-map',
};
<|endoftext|>


<commit_before>
/**
 * Module dependencies
 */

var Edit = require('../lib/edit').Edit
  , Q = require('q');

module.exports = function() {
  describe('Edit', function() {
    describe('#contructor', function() {
      it('should set default locale from global config', function() {
        var edit = new Edit;
        expect(edit.defaultLocale).to.equal(cf.defaultLocale);
      });

      it('should set locales from global config', function() {
        var edit = new Edit;
        expect(edit.locales).to.equal(cf.locales);
      });
    });

    describe('#edit', function() {
      it('should show an error if first parameter is not of type string', function() {
        var logStub = { error : sinon.spy() };
        var Edit = proxyquire('../lib/edit', { './_log' : logStub }).Edit;
        var edit = new Edit;
        edit.edit(1);
        logStub.error.should.have.been.calledOnce;
        logStub.error.should.have.been.calledWith('ref must be of type string');
      });

      it('should show an error if second parameter is not of type string', function() {
        var logStub = { error : sinon.spy() };
        var Edit = proxyquire('../lib/edit', { './_log' : logStub }).Edit;
        var edit = new Edit;
        edit.edit('test', 1);
        logStub.error.should.have.been.calledOnce;
        logStub.error.should.have.been.calledWith('value must be of type string');
      });

      it('should show an error if third parameter locale is not in global config', function() {
        var logStub = { error : sinon.spy() };
        var Edit = proxyquire('../lib/edit', { './_log' : logStub }).Edit;
        var edit = new Edit;
        edit.locales = { 'en-US' : 'English' };
        edit.edit('test', 'wef', 'zh-CN');
        logStub.error.should.have.been.calledOnce;
        logStub.error.should.have.been.calledWith('locale is not defined');
      });

      it('should write the translaton on edit', function(done) {
        var logStub = { success : sinon.spy() };
        var fileStub = { writeTranslations : sinon.stub().callsArg(1) };
        var Edit = proxyquire('../lib/edit', {  './file' : fileStub, './_log' : logStub }).Edit;
        var edit = new Edit;
        edit._getKey = sinon.stub().returns(Q.resolve('tewefwst'));
        edit._replace = sinon.stub().returns({});
        edit.edit('test', 'test', 'zh-CN');
        setTimeout(function() {
          expect(fileStub.writeTranslations.args[0][0]).to.eql({});
          fileStub.writeTranslations.should.have.been.calledOnce;
          done();
        }, 0);
      });

      it('should show succes text', function(done) {
        var logStub = { success : sinon.spy() };
        var fileStub = { writeTranslations : sinon.stub().callsArg(1) };
        var Edit = proxyquire('../lib/edit', {  './file' : fileStub, './_log' : logStub }).Edit;
        var edit = new Edit;
        edit._getKey = sinon.stub().returns(Q.resolve('tewefwst'));
        edit._replace = sinon.stub().returns({});
        edit.edit('test', 'test', 'zh-CN');
        setTimeout(function() {
          logStub.success.should.have.been.calledWithMatch('successfully');
          logStub.success.should.have.been.calledOnce;
          done();
        }, 0);
      });

      it('should show error if get key fails', function(done) {
        var logStub = { error : sinon.spy() };
        var Edit = proxyquire('../lib/edit', { './_log' : logStub }).Edit;
        var edit = new Edit;
        var err = new TypeError;
        edit._getKey = sinon.stub().returns(Q.reject(err));
        edit.edit('test', 'test', 'en-US');
        setTimeout(function() {
          logStub.error.should.have.been.calledWith('Couldn\'t edit your translations');
          logStub.error.should.have.been.calledOnce;
          done();
        }, 0);
      })
    });

    describe('#_getKey', function() {
      it('should eventually return an error if supplied key is not of type string', function(done) {
        var edit = new Edit;
        edit._getKey(1).should.be.rejectedWith(/first parameter is not of type string/).notify(done);
      });

      it('should get key from latest search if it begins with `@`', function(done) {
        var edit = new Edit;
        edit._getKeyFromLatestSearch = sinon.stub().returns(Q.resolve('test'));
        edit._getKey('@1').then(function(key) {
          edit._getKeyFromLatestSearch.should.have.been.calledOnce;
          done();
        });
      });

      it('should get formated key whenever ref begins with `@`', function(done) {
        var edit = new Edit;
        edit._getKeyFromLatestSearch = sinon.stub().returns(Q.resolve('test'));
        edit._getKey('@1').then(function(key) {
          edit._getKeyFromLatestSearch.should.have.been.calledWith('1');
          done();
        });
      });

      it('should get key from latest translations if it begins with `-`', function(done) {
        var edit = new Edit;
        edit._getKeyFromLatestTranslations = sinon.stub().returns(Q.resolve('test'));
        edit._getKey('%1').then(function(key) {
          edit._getKeyFromLatestTranslations.should.have.been.calledOnce;
          edit._getKeyFromLatestTranslations.should.have.been.calledWith(1);
          done();
        });
      });

      it('should return the same ref if it isn\'t beginning with `@` or `-`', function(done) {
        var edit = new Edit;
        edit._getKey('test').should.eventually.equal('test').notify(done);
      });
    });

    describe('#_getKeyFromLatestSearch', function() {
      it('should eventually return a key from a search reference of type string', function(done) {
        var fileStub = { readSearchTranslations : sinon.stub().returns(Q.resolve([{
          ref : 'test'
        }]))};
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestSearch('1').should.eventually.equal('test').notify(done);
      });

      it('should eventually return a key from a search reference of type number', function(done) {
        var fileStub = { readSearchTranslations : sinon.stub().returns(Q.resolve([{
          ref : 'test'
        }]))};
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestSearch(1).should.eventually.equal('test').notify(done);
      });

      it('should reject, if ref is smaller than 1', function(done) {
        var fileStub = { readSearchTranslations : sinon.stub().returns(Q.resolve([{
          ref : 'test'
        }]))};
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestSearch(0).should.be.rejectedWith(TypeError, /ref is out of index/).notify(done);
      });

      it('should reject, if ref is bigger than cached search length ', function(done) {
        var fileStub = { readSearchTranslations : sinon.stub().returns(Q.resolve([{
          ref : 'test'
        }]))};
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestSearch(2).should.be.rejectedWith(TypeError, /ref is out of index/).notify(done);
      });
    });

    describe('#_getKeyFromLatestTranslations', function() {
      it('should reject if ref is smaller than 1', function(done) {
        var fileStub = { readTranslations : sinon.stub().returns([]) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestTranslations(0).should.be.rejectedWith(TypeError, /ref is out of index/).notify(done);
      });

      it('should reject if ref is out of index in translations', function(done) {
        var fileStub = { readTranslations : sinon.stub().returns([{}, {}]) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestTranslations(-3).should.be.rejectedWith(TypeError, /ref is out of index/).notify(done);
      });

      it('should reject if ref is out of index in translations', function(done) {
        var fileStub = { readTranslations : sinon.stub().returns([{}, {}]) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestTranslations(-3).should.be.rejectedWith(TypeError, /ref is out of index/).notify(done);
      });

      it('should return key', function(done) {
        var fileStub = { readTranslations : sinon.stub().returns({ 'en-US' : [{ key : 'test' }] }) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestTranslations(1).should.become('test').notify(done);
      });
    });

    describe('#_replace', function() {
      it('should set the default locale if no locale is specified', function() {
        var fileStub = { readTranslations : sinon.stub().returns({ 'en-US' : { 'test' : { value : [], text : '' }}}) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        var res = edit._replace('test', 'test');
        expect(res[cf.defaultLocale]['test'].value).to.equal('test');
        expect(res[cf.defaultLocale]['test'].text).to.equal('test');
      });

      it('should show an error if locale is not translations', function() {
        var logStub = { error : sinon.spy() };
        var fileStub = { readTranslations : sinon.stub().returns({ 'en-US' : { 'test' : { value : [], text : '' }}}) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub, './_log' : logStub }).Edit;
        var edit = new Edit;
        var res = edit._replace('test', 'test', 'zh-CN');
        logStub.error.should.have.been.calledWithMatch('is not in current translations');
      });

      it('should show an error if key is not translations', function() {
        var logStub = { error : sinon.spy() };
        var fileStub = { readTranslations : sinon.stub().returns({ 'en-US' : { 'test' : { value : [], text : '' }}}) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub, './_log' : logStub }).Edit;
        var edit = new Edit;
        var res = edit._replace('test2', 'test', 'en-US');
        logStub.error.should.have.been.calledWithMatch('is not in current translations');
      });

      it('should edit value and text', function() {
        var fileStub = { readTranslations : sinon.stub().returns({ 'en-US' : { 'test' : { value : [], text : '' }}}) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        var res = edit._replace('test', 'test');
        expect(res[cf.defaultLocale]['test'].value).to.equal('test');
        expect(res[cf.defaultLocale]['test'].text).to.equal('test');
      });
    });
  });
};
<commit_msg>Removed mathcing text arg<commit_after>
/**
 * Module dependencies
 */

var Edit = require('../lib/edit').Edit
  , Q = require('q');

module.exports = function() {
  describe('Edit', function() {
    describe('#contructor', function() {
      it('should set default locale from global config', function() {
        var edit = new Edit;
        expect(edit.defaultLocale).to.equal(cf.defaultLocale);
      });

      it('should set locales from global config', function() {
        var edit = new Edit;
        expect(edit.locales).to.equal(cf.locales);
      });
    });

    describe('#edit', function() {
      it('should show an error if first parameter is not of type string', function() {
        var logStub = { error : sinon.spy() };
        var Edit = proxyquire('../lib/edit', { './_log' : logStub }).Edit;
        var edit = new Edit;
        edit.edit(1);
        logStub.error.should.have.been.calledOnce;
        logStub.error.should.have.been.calledWith('ref must be of type string');
      });

      it('should show an error if second parameter is not of type string', function() {
        var logStub = { error : sinon.spy() };
        var Edit = proxyquire('../lib/edit', { './_log' : logStub }).Edit;
        var edit = new Edit;
        edit.edit('test', 1);
        logStub.error.should.have.been.calledOnce;
        logStub.error.should.have.been.calledWith('value must be of type string');
      });

      it('should show an error if third parameter locale is not in global config', function() {
        var logStub = { error : sinon.spy() };
        var Edit = proxyquire('../lib/edit', { './_log' : logStub }).Edit;
        var edit = new Edit;
        edit.locales = { 'en-US' : 'English' };
        edit.edit('test', 'wef', 'zh-CN');
        logStub.error.should.have.been.calledOnce;
        logStub.error.should.have.been.calledWith('locale is not defined');
      });

      it('should write the translaton on edit', function(done) {
        var logStub = { success : sinon.spy() };
        var fileStub = { writeTranslations : sinon.stub().callsArg(1) };
        var Edit = proxyquire('../lib/edit', {  './file' : fileStub, './_log' : logStub }).Edit;
        var edit = new Edit;
        edit._getKey = sinon.stub().returns(Q.resolve('tewefwst'));
        edit._replace = sinon.stub().returns({});
        edit.edit('test', 'test', 'zh-CN');
        setTimeout(function() {
          expect(fileStub.writeTranslations.args[0][0]).to.eql({});
          fileStub.writeTranslations.should.have.been.calledOnce;
          done();
        }, 20);
      });

      it('should show succes text', function(done) {
        var logStub = { success : sinon.spy() };
        var fileStub = { writeTranslations : sinon.stub().callsArg(1) };
        var Edit = proxyquire('../lib/edit', {  './file' : fileStub, './_log' : logStub }).Edit;
        var edit = new Edit;
        edit._getKey = sinon.stub().returns(Q.resolve('tewefwst'));
        edit._replace = sinon.stub().returns({});
        edit.edit('test', 'test', 'zh-CN');
        setTimeout(function() {
          logStub.success.should.have.been.calledOnce;
          done();
        }, 0);
      });

      it('should show error if get key fails', function(done) {
        var logStub = { error : sinon.spy() };
        var Edit = proxyquire('../lib/edit', { './_log' : logStub }).Edit;
        var edit = new Edit;
        var err = new TypeError;
        edit._getKey = sinon.stub().returns(Q.reject(err));
        edit.edit('test', 'test', 'en-US');
        setTimeout(function() {
          logStub.error.should.have.been.calledOnce;
          done();
        }, 0);
      })
    });

    describe('#_getKey', function() {
      it('should eventually return an error if supplied key is not of type string', function(done) {
        var edit = new Edit;
        edit._getKey(1).should.be.rejectedWith(/first parameter is not of type string/).notify(done);
      });

      it('should get key from latest search if it begins with `@`', function(done) {
        var edit = new Edit;
        edit._getKeyFromLatestSearch = sinon.stub().returns(Q.resolve('test'));
        edit._getKey('@1').then(function(key) {
          edit._getKeyFromLatestSearch.should.have.been.calledOnce;
          done();
        });
      });

      it('should get formated key whenever ref begins with `@`', function(done) {
        var edit = new Edit;
        edit._getKeyFromLatestSearch = sinon.stub().returns(Q.resolve('test'));
        edit._getKey('@1').then(function(key) {
          edit._getKeyFromLatestSearch.should.have.been.calledWith('1');
          done();
        });
      });

      it('should get key from latest translations if it begins with `-`', function(done) {
        var edit = new Edit;
        edit._getKeyFromLatestTranslations = sinon.stub().returns(Q.resolve('test'));
        edit._getKey('%1').then(function(key) {
          edit._getKeyFromLatestTranslations.should.have.been.calledOnce;
          edit._getKeyFromLatestTranslations.should.have.been.calledWith(1);
          done();
        });
      });

      it('should return the same ref if it isn\'t beginning with `@` or `-`', function(done) {
        var edit = new Edit;
        edit._getKey('test').should.eventually.equal('test').notify(done);
      });
    });

    describe('#_getKeyFromLatestSearch', function() {
      it('should eventually return a key from a search reference of type string', function(done) {
        var fileStub = { readSearchTranslations : sinon.stub().returns(Q.resolve([{
          ref : 'test'
        }]))};
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestSearch('1').should.eventually.equal('test').notify(done);
      });

      it('should eventually return a key from a search reference of type number', function(done) {
        var fileStub = { readSearchTranslations : sinon.stub().returns(Q.resolve([{
          ref : 'test'
        }]))};
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestSearch(1).should.eventually.equal('test').notify(done);
      });

      it('should reject, if ref is smaller than 1', function(done) {
        var fileStub = { readSearchTranslations : sinon.stub().returns(Q.resolve([{
          ref : 'test'
        }]))};
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestSearch(0).should.be.rejectedWith(TypeError, /ref is out of index/).notify(done);
      });

      it('should reject, if ref is bigger than cached search length ', function(done) {
        var fileStub = { readSearchTranslations : sinon.stub().returns(Q.resolve([{
          ref : 'test'
        }]))};
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestSearch(2).should.be.rejectedWith(TypeError, /ref is out of index/).notify(done);
      });
    });

    describe('#_getKeyFromLatestTranslations', function() {
      it('should reject if ref is smaller than 1', function(done) {
        var fileStub = { readTranslations : sinon.stub().returns([]) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestTranslations(0).should.be.rejectedWith(TypeError, /ref is out of index/).notify(done);
      });

      it('should reject if ref is out of index in translations', function(done) {
        var fileStub = { readTranslations : sinon.stub().returns([{}, {}]) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestTranslations(-3).should.be.rejectedWith(TypeError, /ref is out of index/).notify(done);
      });

      it('should reject if ref is out of index in translations', function(done) {
        var fileStub = { readTranslations : sinon.stub().returns([{}, {}]) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestTranslations(-3).should.be.rejectedWith(TypeError, /ref is out of index/).notify(done);
      });

      it('should return key', function(done) {
        var fileStub = { readTranslations : sinon.stub().returns({ 'en-US' : [{ key : 'test' }] }) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        edit._getKeyFromLatestTranslations(1).should.become('test').notify(done);
      });
    });

    describe('#_replace', function() {
      it('should set the default locale if no locale is specified', function() {
        var fileStub = { readTranslations : sinon.stub().returns({ 'en-US' : { 'test' : { value : [], text : '' }}}) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        var res = edit._replace('test', 'test');
        expect(res[cf.defaultLocale]['test'].value).to.equal('test');
        expect(res[cf.defaultLocale]['test'].text).to.equal('test');
      });

      it('should show an error if locale is not translations', function() {
        var logStub = { error : sinon.spy() };
        var fileStub = { readTranslations : sinon.stub().returns({ 'en-US' : { 'test' : { value : [], text : '' }}}) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub, './_log' : logStub }).Edit;
        var edit = new Edit;
        var res = edit._replace('test', 'test', 'zh-CN');
        logStub.error.should.have.been.calledWithMatch('is not in current translations');
      });

      it('should show an error if key is not translations', function() {
        var logStub = { error : sinon.spy() };
        var fileStub = { readTranslations : sinon.stub().returns({ 'en-US' : { 'test' : { value : [], text : '' }}}) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub, './_log' : logStub }).Edit;
        var edit = new Edit;
        var res = edit._replace('test2', 'test', 'en-US');
        logStub.error.should.have.been.calledWithMatch('is not in current translations');
      });

      it('should edit value and text', function() {
        var fileStub = { readTranslations : sinon.stub().returns({ 'en-US' : { 'test' : { value : [], text : '' }}}) };
        var Edit = proxyquire('../lib/edit', { './file' : fileStub }).Edit;
        var edit = new Edit;
        var res = edit._replace('test', 'test');
        expect(res[cf.defaultLocale]['test'].value).to.equal('test');
        expect(res[cf.defaultLocale]['test'].text).to.equal('test');
      });
    });
  });
};
<|endoftext|>


<commit_before>function initGame() {
  this.addLayer("one")
  this.addSprite(
    "drop", "assets/drop.png", 96, 96,
    this.draw.bind(this, "one", "drop", 10, 10, 96, 96)
  )
}
<commit_msg>added simple movement to demo sprite<commit_after>function initGame() {
  this.addLayer("one")
  this.addSprite(
    "drop", "assets/drop.png", 96, 96,
    this.draw.bind(this, "one", "drop", 10, 10, 96, 96)
  )
  var x = 10
  var y = 10

  function gameLoop() {
    if(x < 694 && y == 10) x+=2
    else if(x == 694 && y < 494) y+=2
    else if(x > 10 && y == 494) x-=2
    else if(x == 10 && y > 10) y-=2

    this.draw("one", "drop", x, y, 96, 96)

    requestAnimationFrame(gameLoop.bind(this));
  }

  gameLoop.apply(this)
}
<|endoftext|>


<commit_before>var dotenv = require('dotenv');
dotenv.load();
var express = require('express');
var bodyParser = require('body-parser');
var colors = require('colors');
var fs = require('fs');
var os = require('os');
var path = require('path');
var prettyjson = require('prettyjson');
var querystring = require('querystring');
var request = require('request');

var port = 3000;

// shell commands
require('shelljs/global');

var app = express();
app.use(bodyParser({limit: '50mb'}));
app.use(express.static(__dirname + '/uploaded_data'));
app.use("/", express.static(__dirname + '/landing'));
app.use(function(req, res, next) { // enable CORS
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  res.setHeader('Content-Type', 'application/json');
  next();
});

// for getting network data
var ifaces = os.networkInterfaces();

app.post('/food-analysis', function (req, res) {
  res.setHeader('Content-Type', 'application/json');

  if (req.body.image) {

    var imageID = generatePushID(); // generate a unique token for each image

    fs.writeFile(__dirname+'/uploaded_data/'+imageID+'.jpeg', req.body.image, 'base64', function (err) {
      if (err) throw err;
      console.log('Image successfully uploaded.'.green);
      console.log((process.env.HOSTNAME+"/uploaded_img/"+imageID).blue);

      var form = {
          'image_request[remote_image_url]': process.env.HOSTNAME+"/uploaded_img/"+imageID+".jpeg",
          "image_request[locale]": "en-US"
      };

      var formData = querystring.stringify(form);
      var contentLength = formData.length;

      console.log(process.env.CLOUDSIGHT_KEY);

        request({
            headers: {
              'Authorization': 'CloudSight '+ process.env.CLOUDSIGHT_KEY,
              'Content-Length': contentLength,
              'Content-Type': 'application/x-www-form-urlencoded'
            },
            uri: 'https://api.cloudsightapi.com/image_requests',
            body: formData,
            method: 'POST'
          }, function (err, resPost, body) {
            //it works!
            if (err) {
              res.send({"Error": "There was an error from images-request"})
            } else {
              console.log(body);
              var resToken = JSON.parse(body).token;

              console.log("Processing image information...".cyan);

              loopResponseCloud();
              function loopResponseCloud() {
                  request({url: "https://api.cloudsightapi.com/image_responses/"+resToken, headers: {'Authorization': 'CloudSight '+ process.env.CLOUDSIGHT_KEY}}, function (resError, resResponse, resBody) {
                      if (JSON.parse(resBody).status == "not completed") {
                        loopResponseCloud();
                      } else if (JSON.parse(resBody).status == "skipped") {
                        res.send({"Error": "Error reading the photo. Please try again."});
                      } else if (JSON.parse(resBody).status == "completed") { // if the image recognition occurred, start finding nutritional data

                        console.log(resBody);

                        if (typeof JSON.parse(resBody).name !== "undefined") {
                          console.log((JSON.parse(resBody).name).green);

                          // get nutritional data
                          var nutritionalParameters = {
                            "appId":process.env.NUTRITION_APP_ID,
                            "appKey":process.env.NUTRITION_API_KEY,
                            "phrase":JSON.parse(resBody).name,
                            "fields":"*",
                            "results":"0:50",
                            "cal_min":0,
                            "cal_max":50000
                          };

                          var nutritionData = querystring.stringify(nutritionalParameters);
                          request({
                              uri: 'https://api.nutritionix.com/v1_1/search/'+encodeURIComponent(nutritionalParameters.phrase)+"?results="+encodeURIComponent(nutritionalParameters.results)+"&cal_min="+nutritionalParameters.cal_min+"&cal_max="+nutritionalParameters.cal_max+"&fields="+encodeURIComponent(nutritionalParameters.fields)+"&appId="+nutritionalParameters.appId+"&appKey="+nutritionalParameters.appKey,
                              body: nutritionData,
                              method: 'GET'
                            }, function (nutriErr, nutriRes, nutriBody) {
                              if (nutriErr) {
                                var returnedData = {"imageB64":req.body.image, "Scan_Error": "There is no nutritional value in consuming a '" + JSON.parse(resBody).name+"'"};
                                res.send(returnedData);
                                fs.writeFile(__dirname+"/user_cache/"+generatePushID()+".json", JSON.stringify(returnedData), function(err) {
                                  if (err) throw err;

                                });
                              } else {
                                var parsedData = JSON.parse(nutriBody);
                                console.log(("NUTRITIONAL RELEVANCE SCORE: " + parsedData.max_score).magenta);
                                if (parsedData.max_score > 0.82) {
                                  var relevantNutrition = parsedData.hits[0];
                                  console.log(relevantNutrition.fields.item_name);

                                  var easyDisplayName = toTitleCase(relevantNutrition.fields.item_name); // so it looks better on the iphone
                                  console.log("EVERYTHING WORKED".green);
                                  console.log(Math.round(parsedData.max_score * 100)/100);
                                  console.log(relevantNutrition.fields["nf_ingredient_statement"]);

                                  for (var key in relevantNutrition.fields) {
                                    if (key !== "item_name") {
                                      if (key !== "nf_calories") {
                                        if (key !== "nf_serving_size_qty") {
                                          if (key !== "nf_serving_size_unit") {
                                            if ((key.indexOf("allergen") > -1) == false) {
                                                  if (relevantNutrition.fields[key] == null) {
                                                    relevantNutrition.fields[key] = "0";
                                                  }
                                                  if (key == "nf_sodium") {
                                                    relevantNutrition.fields[key] += "mg";
                                                  } else if (key == "nf_cholesterol") {
                                                    relevantNutrition.fields[key] += "mg";
                                                  } else if (key == "nf_ingredient_statement") {
                                                    if (relevantNutrition.fields[key] == null) {
                                                      relevantNutrition.fields[key] = "No ingredients.";
                                                    }
                                                  } else {
                                                    relevantNutrition.fields[key] += "g";
                                                  }
                                            }
                                          }
                                        }
                                      }
                                    }
                                  }

                                  console.log(relevantNutrition.fields["nf_ingredient_statement"]);
                                  var awesomeData = {"imageB64":req.body.image, "result":{"object_name":toTitleCase(JSON.parse(resBody).name), "confidence": Math.round(parsedData.max_score * 100)/100, "easy_display_name": easyDisplayName, "data": relevantNutrition}};
                                  res.send(awesomeData);
                                  fs.writeFile(__dirname+"/user_cache/"+generatePushID()+".json", JSON.stringify(awesomeData), function(err) {
                                    if (err) throw err;
                                  });

                                } else {
                                  var returnData = {"imageB64":req.body.image, "Scan_Error": "There is no nutritional value in consuming a '" + JSON.parse(resBody).name+"'"};
                                  res.send(returnData);
                                  fs.writeFile(__dirname+"/user_cache/"+ generatePushID() +".json", JSON.stringify(returnData), function(err) {
                                    if (err) throw err;
                                  });
                                }

                              }

                          }); // end nutritoinix api

                        } else {
                          res.send({"Error": "There was an error."});
                        }
                      }
                  });
                }
            }
          });
    });
  }
}); // end food-analysis

app.get('/uploaded_img/:id', function (req, res) {
  res.set('Content-Type', 'application/jpeg');
  res.sendFile(__dirname + "/uploaded_data/" +req.param('id'));
});

app.get("/saved-user-data", function (req, res) {
  res.setHeader('Content-Type', 'application/json');

  var finalJSON = [];
  var savedContents = ls(__dirname+'/user_cache');
  console.log(savedContents);

  if (savedContents.length > 0) {
    var fileIndex = 0;
    loopJSON();

    function loopJSON() {
      console.log(savedContents[fileIndex]);
      fs.readFile(__dirname+"/user_cache/"+savedContents[fileIndex], "utf-8", function (err, data) {
        if (err) throw err;

        finalJSON.push(JSON.parse(data));
        rm('-rf', __dirname+"/user_cache/"+savedContents[fileIndex]);

        if (fileIndex < savedContents.length-1) {
          fileIndex++;
          loopJSON();
        } else {
          res.send(JSON.stringify(finalJSON));
        }
      });

    }
  } else {
    res.setHeader('Content-Type', 'application/text');
    res.send("No new content.");
  }
});

// fire up the server
var server = app.listen(port, function () {
  Object.keys(ifaces).forEach(function (ifname) {
    var alias = 0;
    ifaces[ifname].forEach(function (iface) {
      if ('IPv4' !== iface.family || iface.internal !== false) {
        return;
      }
      console.log(("Server running on "+iface.address+":"+port).blue);
    });
  });
});

generatePushID = (function() {
  var PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
  var lastPushTime = 0;
  var lastRandChars = [];
  return function() {
    var now = new Date().getTime();
    var duplicateTime = (now === lastPushTime);
    lastPushTime = now;
    var timeStampChars = new Array(8);
    for (var i = 7; i >= 0; i--) {
      timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
      now = Math.floor(now / 64);
    }
    if (now !== 0) throw new Error('We should have converted the entire timestamp.');
    var id = timeStampChars.join('');
    if (!duplicateTime) {
      for (i = 0; i < 12; i++) {
        lastRandChars[i] = Math.floor(Math.random() * 64);
      }
    } else {
      for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {
        lastRandChars[i] = 0;
      }
      lastRandChars[i]++;
    }
    for (i = 0; i < 12; i++) {
      id += PUSH_CHARS.charAt(lastRandChars[i]);
    }
    if(id.length != 20) throw new Error('Length should be 20.');

    return id;
  };
})();

function toTitleCase(str)
{
    return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
<commit_msg>starting the server fresh<commit_after>var dotenv = require('dotenv');
dotenv.load();
var express = require('express');
var bodyParser = require('body-parser');
var colors = require('colors');
var fs = require('fs');
var os = require('os');
var path = require('path');
var prettyjson = require('prettyjson');
var querystring = require('querystring');
var request = require('request');

var port = 3000;

// shell commands
require('shelljs/global');

var app = express();
app.use(bodyParser({limit: '50mb'}));
app.use(express.static(__dirname + '/uploaded_data'));
app.use("/", express.static(__dirname + '/landing'));
app.use(function(req, res, next) { // enable CORS
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  res.setHeader('Content-Type', 'application/json');
  next();
});

// for getting network data
var ifaces = os.networkInterfaces();

app.post('/food-analysis', function (req, res) {
  res.setHeader('Content-Type', 'application/json');

  if (req.body.image) {
    var imageID = generatePushID();

    fs.writeFile(__dirname+'/uploaded_data/'+imageID+'.jpeg', req.body.image, 'base64', function (err) {
      if (err) throw err;
      console.log('Image successfully uploaded.'.green);
      console.log((process.env.HOSTNAME+"/uploaded_img/"+imageID).blue);

      console.log()
    });

  } else {
    res.send({"Error": "Missing parameters."});
  }
}); // end food-analysis

app.get('/uploaded_img/:id', function (req, res) {
  res.set('Content-Type', 'application/jpeg');
  res.sendFile(__dirname + "/uploaded_data/" +req.param('id'));
});

app.get("/saved-user-data", function (req, res) {
  res.setHeader('Content-Type', 'application/json');

  var finalJSON = [];
  var savedContents = ls(__dirname+'/user_cache');
  console.log(savedContents);

  if (savedContents.length > 0) {
    var fileIndex = 0;
    loopJSON();

    function loopJSON() {
      console.log(savedContents[fileIndex]);
      fs.readFile(__dirname+"/user_cache/"+savedContents[fileIndex], "utf-8", function (err, data) {
        if (err) throw err;

        finalJSON.push(JSON.parse(data));
        rm('-rf', __dirname+"/user_cache/"+savedContents[fileIndex]);

        if (fileIndex < savedContents.length-1) {
          fileIndex++;
          loopJSON();
        } else {
          res.send(JSON.stringify(finalJSON));
        }
      });

    }
  } else {
    res.setHeader('Content-Type', 'application/text');
    res.send("No new content.");
  }
});

// fire up the server
var server = app.listen(port, function () {
  Object.keys(ifaces).forEach(function (ifname) {
    var alias = 0;
    ifaces[ifname].forEach(function (iface) {
      if ('IPv4' !== iface.family || iface.internal !== false) {
        return;
      }
      console.log(("Server running on "+iface.address+":"+port).blue);
    });
  });
});

generatePushID = (function() {
  var PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
  var lastPushTime = 0;
  var lastRandChars = [];
  return function() {
    var now = new Date().getTime();
    var duplicateTime = (now === lastPushTime);
    lastPushTime = now;
    var timeStampChars = new Array(8);
    for (var i = 7; i >= 0; i--) {
      timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
      now = Math.floor(now / 64);
    }
    if (now !== 0) throw new Error('We should have converted the entire timestamp.');
    var id = timeStampChars.join('');
    if (!duplicateTime) {
      for (i = 0; i < 12; i++) {
        lastRandChars[i] = Math.floor(Math.random() * 64);
      }
    } else {
      for (i = 11; i >= 0 && lastRandChars[i] === 63; i--) {
        lastRandChars[i] = 0;
      }
      lastRandChars[i]++;
    }
    for (i = 0; i < 12; i++) {
      id += PUSH_CHARS.charAt(lastRandChars[i]);
    }
    if(id.length != 20) throw new Error('Length should be 20.');

    return id;
  };
})();

function toTitleCase(str)
{
    return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
}
<|endoftext|>