const path = require('path');
const webpack = require('webpack');

module.exports = [{
    entry: path.join(__dirname, 'src', 'Flatline.ts'),
    output: {
        path: path.join(__dirname, 'build'),
        filename: "flatline-browser.js",
        library: "Flatline",
        libraryTarget: "var"
    },
    resolve: {
        extensions: [".ts", ".tsx"]
    },
    module: {
        rules: [{
            test: /\.tsx?$/,
            include: [
                path.join(__dirname, 'src')
            ],
            loader: 'ts-loader'
        }]
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: { warnings: false, dead_code: true },
            mangle: true,
            sourceMap: true,
            beautify: false
        })
    ]
}, {
    entry: path.join(__dirname, 'src', 'Flatline.ts'),
    output: {
        path: path.join(__dirname, 'build'),
        filename: "flatline-common.js",
        libraryTarget: "commonjs"
    },
    resolve: {
        extensions: [".ts", ".tsx"]
    },
    module: {
        rules: [{
            test: /\.tsx?$/,
            include: [
                path.join(__dirname, 'src')
            ],
            loader: 'ts-loader'
        }]
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: { warnings: false, dead_code: true },
            mangle: true,
            sourceMap: true,
            beautify: false
        })
    ]
}]

const path = require('path');
const webpack = require('webpack');

module.exports = [{
    entry: path.join(__dirname, 'src', 'Flatline.ts'),
    output: {
        path: path.join(__dirname, 'build'),
        filename: "flatline-browser.min.js",
        library: "Flatline",
        libraryTarget: "var"
    },
    resolve: {
        extensions: [".ts", ".tsx"]
    },
    module: {
        rules: [{
            test: /\.tsx?$/,
            include: [
                path.join(__dirname, 'src')
            ],
            loader: 'ts-loader'
        }]
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: { warnings: false, dead_code: true },
            mangle: true,
            sourceMap: true,
            beautify: false
        })
    ]
}, {
    entry: path.join(__dirname, 'src', 'Flatline.ts'),
    output: {
        path: path.join(__dirname, 'build'),
        filename: "flatline-common.min.js",
        libraryTarget: "commonjs"
    },
    resolve: {
        extensions: [".ts", ".tsx"]
    },
    module: {
        rules: [{
            test: /\.tsx?$/,
            include: [
                path.join(__dirname, 'src')
            ],
            loader: 'ts-loader'
        }]
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin({
            compress: { warnings: false, dead_code: true },
            mangle: true,
            sourceMap: true,
            beautify: false
        })
    ]
}]

Fix the file extensions for the bundles


/* eslint-disable */
const webpack = require('webpack');

module.exports = {
  mode: process.env.NODE_ENV || 'production',
  devtool: 'source-map',
  entry: './src/index.js',
  output: {
    path: __dirname + "/dist",
    filename: 'ReactToastify.js',
    libraryTarget: 'umd',
    library: 'ReactToastify'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  },
  externals: [
    'react',
    'react-dom',
    'prop-types',
    'react-transition-group',
    'classnames'
  ],
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    })
  ]
};

/* eslint-disable */
const webpack = require('webpack');

module.exports = {
  mode: process.env.NODE_ENV || 'production',
  devtool: 'source-map',
  entry: './src/index.js',
  output: {
    path: __dirname + "/dist",
    filename: 'ReactToastify.js',
    libraryTarget: 'umd',
    library: 'ReactToastify'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  },
  externals: [
    'react',
    'react-dom',
    'prop-types',
    'react-transition-group/Transition',
    'classnames'
  ],
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    })
  ]
};

Exclude react-transition-group from umd bundle


#!/usr/bin/env node

var nodeFS = require('fs');

var filename = '{test.wasm}';
var ret = nodeFS['readFileSync'](filename);

function instantiate(bytes, imports) {
  return WebAssembly.compile(bytes).then(
    m => new WebAssembly.Instance(m, imports), reason => console.log(reason) );
}

var dependencies = {
    "global": {},
    "env": {}
};
dependencies["global.Math"] = Math;

instantiate( ret, dependencies ).then(
  instance => console.log( instance.exports[process.argv[2]]( ...process.argv.slice(3) ) ),
  reason => console.log(reason)
);

#!/usr/bin/env node

var nodeFS = require('fs');

var filename = '{test.wasm}';
var ret = nodeFS['readFileSync'](filename);

function instantiate(bytes, imports) {
  return WebAssembly.compile(bytes).then(
    m => new WebAssembly.Instance(m, imports), reason => console.log(reason) );
}

var dependencies = {
    "global": {},
    "env": {}
};
dependencies["global.Math"] = Math;

function callExport(instance) {
    try{
        console.log( instance.exports[process.argv[2]]( ...process.argv.slice(3) ) );
    }catch(err){
        console.log(err)
    }
}

instantiate( ret, dependencies ).then(
  instance => callExport(instance),
  reason => console.log(reason)
);

Add try catch to execution errors


/*
 * Appcelerator Titanium Mobile
 * Copyright (c) 2011-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */

module.exports = new function() {
	var finish;
	var valueOf;
	this.init = function(testUtils) {
		finish = testUtils.finish;
		valueOf = testUtils.valueOf;
	}

	this.name = "jss";
	this.tests = [
		{name: "platform_jss_dirs"}
	]

	this.platform_jss_dirs = function(testRun) {
		var test = Ti.UI.createView({ id: "test" });
		valueOf(testRun, test).shouldNotBeNull();

		if (Ti.Platform.name == "android") {
			valueOf(testRun, test.backgroundColor).shouldBe("red");
		} else if (Ti.Platform.name == "tizen") {
			// In Tizen, test.backgroundColor is undefined by default.
			valueOf(testRun, test.backgroundColor).shouldBeUndefined();
		} else {
			valueOf(testRun, test.backgroundColor).shouldBe("blue");
		}

		finish(testRun);
	}
}

/*
 * Appcelerator Titanium Mobile
 * Copyright (c) 2011-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */

module.exports = new function() {
	var finish;
	var valueOf;
	this.init = function(testUtils) {
		finish = testUtils.finish;
		valueOf = testUtils.valueOf;
	}

	this.name = "jss";
	this.tests = [
		{name: "platform_jss_dirs"}
	]

	this.platform_jss_dirs = function(testRun) {
		var test = Ti.UI.createView({ id: "test" });
		valueOf(testRun, test).shouldNotBeNull();

		if (Ti.Platform.name == "android") {
			valueOf(testRun, test.backgroundColor).shouldBe("red");
		} else if (Ti.Platform.osname == "tizen") {
			// In Tizen, test.backgroundColor is undefined by default.
			valueOf(testRun, test.backgroundColor).shouldBeUndefined();
		} else {
			valueOf(testRun, test.backgroundColor).shouldBe("blue");
		}

		finish(testRun);
	}
}

Change Ti.Platform.name to Ti.Platform.osname in Anvil for Tizen calls


import raven from 'raven'
import {GraphQLError} from 'graphql/error'

import {parseQueryError} from 'src/server/db/errors'
import {getPlayerById} from 'src/server/db/player'
import {getLatestCycleForChapter} from 'src/server/db/cycle'

const sentry = new raven.Client(process.env.SENTRY_SERVER_DSN)

export async function assertPlayersCurrentCycleInState(currentUser, state) {
  const player = await getPlayerById(currentUser.id, {mergeChapter: true})
  const cycleInReflection = await getLatestCycleForChapter(player.chapter.id)('state')
    .eq(state)

  if (!cycleInReflection) {
    throw new GraphQLError(`This action is not allowed when the cycle is not in the ${state} state`)
  }
}

export function handleError(unparsedError, defaultMsg) {
  const err = parseQueryError(unparsedError)
  if (err.name === 'BadInputError' || err.name === 'LGCustomQueryError') {
    throw err
  }
  console.error(err.stack)
  sentry.captureException(err)
  throw new GraphQLError(defaultMsg || err)
}

import raven from 'raven'
import {GraphQLError} from 'graphql/error'

import {parseQueryError} from 'src/server/db/errors'
import {getPlayerById} from 'src/server/db/player'
import {getLatestCycleForChapter} from 'src/server/db/cycle'

const sentry = new raven.Client(process.env.SENTRY_SERVER_DSN)

export async function assertPlayersCurrentCycleInState(currentUser, state) {
  const player = await getPlayerById(currentUser.id, {mergeChapter: true})
  const cycleInReflection = await getLatestCycleForChapter(player.chapter.id)('state')
    .eq(state)

  if (!cycleInReflection) {
    throw new GraphQLError(`This action is not allowed when the cycle is not in the ${state} state`)
  }
}

export function handleError(unparsedError, defaultMsg) {
  const err = parseQueryError(unparsedError)
  if (err.name === 'BadInputError' || err.name === 'LGCustomQueryError') {
    throw err
  }
  console.error(err.stack || err)
  sentry.captureException(err)
  throw new GraphQLError(defaultMsg || err.message || err)
}

Use the `message` attribute if present when creating a GraphQLError


var geneticAlgorithmConstructor = require('geneticalgorithm')
var mutationModule  = require('./MutationModule')
var crossoverModule = require('./CrossoverModule')
var fitnessModule   = require('./FitnessModule')
var fileIOModule    = require('./FileIOModule')

var firstPhenotype =
{
  dummyKey : "dummyValue"
  // enter phenotype data here
}

var geneticAlgorithm = geneticAlgorithmConstructor({
  mutationFunction:   mutationModule.mutationFunction,
  crossoverFunction: crossoverModule.crossoverFunction,
  fitnessFunction: fitnessModule.fitnessFunction,
  population: [ firstPhenotype ]
});

geneticAlgorithm.evolve()
var best = geneticAlgorithm.best()

var geneticAlgorithmConstructor = require('geneticalgorithm')
var competitionModule = require('./CompetitionBModule')
var mutationModule  = require('./MutationModule')
var crossoverModule = require('./CrossoverModule')
var fitnessModule   = require('./FitnessModule')
var fileIOModule    = require('./FileIOModule')

var firstPhenotype =
{
  dummyKey : "dummyValue"
  // enter phenotype data here
}

var geneticAlgorithm = geneticAlgorithmConstructor({
  mutationFunction:   mutationModule.mutationFunction,
  crossoverFunction:  crossoverModule.crossoverFunction,
  doesABeatBFunction: competitionModule.competitionFunction,
  fitnessFunction:    fitnessModule.fitnessFunction,
  population: [ firstPhenotype ],
  populationSize:     200
});

geneticAlgorithm.evolve()
var best = geneticAlgorithm.best()

Update Configuration of GeneticAlgorithm Constructor


const I18nPlugin = require('../ui-build/webpack/i18nPlugin')
const path = require('path')
const baseWebpackConfig = require('../ui-build/webpack')

const root = path.resolve(__dirname, '..')

module.exports = {
  stories: [
    '../ui/**/*.stories.mdx',
    '../ui/**/*.stories.@(js|jsx|ts|tsx)'
  ],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials'
  ],
  webpackFinal: async (config) => {
    config.module.noParse = [/i18nliner\/dist\/lib\/i18nliner/]
    config.plugins.push(new I18nPlugin())
    config.resolveLoader.modules = [
      path.resolve(__dirname, '../ui-build/webpack'),
      'node_modules'
    ]

    config.resolve.modules = [
      path.resolve(__dirname, '../ui/shims'),
      path.resolve(__dirname, '../public/javascripts'), // for translations
      'node_modules'
    ]
    config.resolve.alias = {...baseWebpackConfig.resolve.alias, ...config.resolve.alias}
    config.module.rules = [
      ...config.module.rules,
      {
        test: /\.coffee$/,
        include: [path.resolve(__dirname, '../ui')],
        loaders: ['coffee-loader']
      },
      {
        test: /\.handlebars$/,
        include: [path.resolve(__dirname, '../ui')],
        loaders: ['i18nLinerHandlebars']
      }
    ]

    return config
  }
}

const I18nPlugin = require('../ui-build/webpack/i18nPlugin')
const path = require('path')
const baseWebpackConfig = require('../ui-build/webpack')

const root = path.resolve(__dirname, '..')

module.exports = {
  stories: [
    '../ui/**/*.stories.mdx',
    '../ui/**/*.stories.@(js|jsx|ts|tsx)'
  ],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials'
  ],
  webpackFinal: async (config) => {
    config.module.noParse = [/i18nliner\/dist\/lib\/i18nliner/]
    config.plugins.push(I18nPlugin)
    config.resolveLoader.modules = [
      path.resolve(__dirname, '../ui-build/webpack'),
      'node_modules'
    ]

    config.resolve.modules = [
      path.resolve(__dirname, '../ui/shims'),
      path.resolve(__dirname, '../public/javascripts'), // for translations
      'node_modules'
    ]
    config.resolve.alias = {...baseWebpackConfig.resolve.alias, ...config.resolve.alias}
    config.module.rules = [
      ...config.module.rules,
      {
        test: /\.coffee$/,
        include: [path.resolve(__dirname, '../ui')],
        loaders: ['coffee-loader']
      },
      {
        test: /\.handlebars$/,
        include: [path.resolve(__dirname, '../ui')],
        loaders: ['i18nLinerHandlebars']
      }
    ]

    return config
  }
}

Fix i18nPlugin issue introduced with g/277926


//  Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without modification,
//  are permitted provided that the following conditions are met:
//  1. Redistributions of source code must retain the above copyright notice, this
//  list of conditions and the following disclaimer.
//  2. Redistributions in binary form must reproduce the above copyright notice,
//  this list of conditions and the following disclaimer in the documentation and/or
//  other materials provided with the distribution.
//  3. Neither the name of the organization nor the names of its contributors may be
//  used to endorse or promote products derived from this software without specific
//  prior written permission.

require.config({
	config : {
        'workers/WorkerProxy' : {'workerUrl' : '/scripts/readium-worker.js'},
        'EpubLibraryManager' : {
        							'canHandleUrl' : true,
        							'canHandleDirectory' : true
    						   },
    	'EpubReader' : {
    		'annotationCssUrl' : self.location.origin  + '/css/annotations.css',
    		'mathJaxUrl' : self.location.origin  + '/scripts/mathjax/MathJax.js?config=readium-iframe'
    	}
    }
});

//  Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without modification,
//  are permitted provided that the following conditions are met:
//  1. Redistributions of source code must retain the above copyright notice, this
//  list of conditions and the following disclaimer.
//  2. Redistributions in binary form must reproduce the above copyright notice,
//  this list of conditions and the following disclaimer in the documentation and/or
//  other materials provided with the distribution.
//  3. Neither the name of the organization nor the names of its contributors may be
//  used to endorse or promote products derived from this software without specific
//  prior written permission.

require.config({
	config : {
        'workers/WorkerProxy' : {'workerUrl' : '/scripts/readium-worker.js'},
        'EpubLibraryManager' : {
        							'canHandleUrl' : true,
        							'canHandleDirectory' : true
    						   },
    	'EpubReader' : {
    		'annotationCssUrl' : self.location.origin  + '/css/annotations.css',
    		'mathJaxUrl' : self.location.origin  + '/scripts/mathjax/MathJax.js'
    	}
    }
});

Remove config parameter from mathJaxUrl.


var Logger = require('./vendor/src/logger');
var Recorder = require('./handlers/recorder');

var consoleHandler = Logger.createDefaultHandler();
var logRecorder = new Recorder();

/**
 * @returns {String}
 */
Logger.getFormattedRecords = function() {
  return logRecorder.getFormattedRecords();
};

/**
 * @returns {{date: {Date}, messages: *[], context: {Object}}[]}
 */
Logger.getRecords = function() {
  return logRecorder.getRecords();
};

Logger.setHandler(function(messages, context) {
  consoleHandler(messages, context);
  logRecorder.addRecord(messages, context);
});

Logger.setLevel(Logger.DEBUG);

module.exports = Logger;

var Logger = require('./vendor/src/logger');
var Recorder = require('./handlers/recorder');

var consoleHandler = Logger.createDefaultHandler();
var logRecorder = new Recorder();

var options = {
  dev: false
};

/**
 * @returns {String}
 */
Logger.getFormattedRecords = function() {
  return logRecorder.getFormattedRecords();
};

/**
 * @returns {{date: {Date}, messages: *[], context: {Object}}[]}
 */
Logger.getRecords = function() {
  return logRecorder.getRecords();
};

Logger.setHandler(function(messages, context) {
  var isDev = context.level.value < Logger.WARN.value;
  if (!isDev || (options.dev && isDev)) {
    consoleHandler(messages, context);
  }
  logRecorder.addRecord(messages, context);
});

Logger.configure = function(newOptions) {
  _.extend(options, newOptions);
};

Logger.setLevel(Logger.DEBUG);

module.exports = Logger;

Introduce dev mode for cm.logger


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

import os from 'os';
import * as BuildUtils from './utils';

export default {
  // System information
  platform: os.platform(),
  arch: 'x64',

  // Electron information
  electron: BuildUtils.getElectronVersion(),

  // Version number, with extra build numbers if in a CI environment
  version: BuildUtils.getAppVersion(),

  // If this build occurred on Travis CI
  travis: BuildUtils.IS_TRAVIS,

  // If this build occurred on Appveyor
  appveyor: BuildUtils.IS_APPVEYOR,

  // The `development` option indicates whether or not the build is
  // using hot reloading and unminified content and other things like that.
  development: false,

  // Whether or not the build is being tested
  test: false,

  // The Google Analytics tracking identifier to use when instrumenting.
  googleAnalyticsTrackingID: 'UA-76122102-1',
};

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

import os from 'os';
import * as BuildUtils from './utils';

export default {
  // System information
  platform: os.platform(),
  arch: 'x64',

  // Electron information
  electron: BuildUtils.getElectronVersion(),

  // Version number, with extra build numbers if in a CI environment
  version: BuildUtils.getAppVersion(),

  // The `development` option indicates whether or not the build is
  // using hot reloading and unminified content and other things like that.
  development: false,

  // Whether or not the build is being tested
  test: false,

  // The Google Analytics tracking identifier to use when instrumenting.
  googleAnalyticsTrackingID: 'UA-76122102-1',
};

Remove 'travis' and 'appveyor' properties on the build-config


import React from 'react';
import '../scss/_recipeContainer.scss';

import RecipeEntry from '../../client/components/RecipeEntry.js';
import RecipeListEntry from '../../client/components/RecipeListEntry.js';

const RecipeContainer = (props) => {
  let childRecipes;
  if (!props.recipes || props.recipes.length === 0) {
    childRecipes =
No recipes to show.
;
  } else if (props.type === 'Recipe History') {
    childRecipes = props.recipes.map((recipe) => <RecipeListEntry recipe={recipe} />);
  } else {
    childRecipes = props.recipes.map((recipe) => <RecipeEntry recipe={recipe} />);
  }
  return (

{props.type}

        {childRecipes}

  );
};

export default RecipeContainer;

Change wording to make it less redundant


/*
 * jquery.textnodes
 *
 *
 * Copyright (c) 2014 Mark Florian
 * Licensed under the MIT license.
 */

(function($) {

  var rNonWhiteSpace = /\S/;

  function getChildTextNodes($el, list, includeWhiteSpace) {
    $el.contents().each(function () {
      var isNonWhiteSpace;
      if (this.nodeType === 3) {
        isNonWhiteSpace = rNonWhiteSpace.test(this.nodeValue);
        if (isNonWhiteSpace || includeWhiteSpace) {
          list.push(this);
        }
      } else if (this.nodeType === 1) {
        getChildTextNodes($(this), list, includeWhiteSpace);
      }
      return list;
    });
  }

  $.fn.textNodes = function (includeWhiteSpace) {
    var textNodes = [];
    getChildTextNodes(this, textNodes, includeWhiteSpace);
    return $(textNodes);
  };

}(jQuery));

/*
 * jquery.textnodes
 *
 *
 * Copyright (c) 2014 Mark Florian
 * Licensed under the MIT license.
 */

(function($) {

  // Match anything that isn't whitespace or the non-breaking space,
  // which IE < 9 does not consider whitespace.
  var rNonWhiteSpace = /[^\s\u00a0]/;

  function getChildTextNodes($el, list, includeWhiteSpace) {
    $el.contents().each(function () {
      var isNonWhiteSpace;
      if (this.nodeType === 3) {
        isNonWhiteSpace = rNonWhiteSpace.test(this.nodeValue);
        if (isNonWhiteSpace || includeWhiteSpace) {
          list.push(this);
        }
      } else if (this.nodeType === 1) {
        getChildTextNodes($(this), list, includeWhiteSpace);
      }
      return list;
    });
  }

  $.fn.textNodes = function (includeWhiteSpace) {
    var textNodes = [];
    getChildTextNodes(this, textNodes, includeWhiteSpace);
    return $(textNodes);
  };

}(jQuery));

Fix IE < 9's idea that   isn't whitespace.


var fork = require('child_process').fork
var path = require('path')
var grabStdio = require('../grab-stdio')

module.exports = {
  'loads scripts from a relative path': function (done) {
    var stdio = {}
    var child = fork('../../../cli', [], {
      cwd: path.join(__dirname, '..', 'fixtures', 'relative-path-loading'),
      silent: true,
      env: {
        npm_lifecycle_event: 'secret',
        npm_package_scripty_path: '../custom-user-scripts',
        SCRIPTY_SILENT: true
      }
    })

    grabStdio(stdio)(child)

    child.on('exit', function (code) {
      assert.equal(code, 0)
      assert.includes(stdio.stdout, 'SSHHH')

      done()
    })
  }
}

var fork = require('child_process').fork
var path = require('path')
var grabStdio = require('../grab-stdio')

module.exports = {
  'loads scripts from a relative path': function (done) {
    var stdio = {}
    var windowsSuffix = process.platform === 'win32' ? '-win' : ''
    var child = fork('../../../cli', [], {
      cwd: path.join(__dirname, '..', 'fixtures', 'relative-path-loading'),
      silent: true,
      env: {
        npm_lifecycle_event: 'secret',
        npm_package_scripty_path: '../custom-user-scripts' + windowsSuffix,
        SCRIPTY_SILENT: true
      }
    })

    grabStdio(stdio)(child)

    child.on('exit', function (code) {
      assert.equal(code, 0)
      assert.includes(stdio.stdout, 'SSHHH')

      done()
    })
  }
}

Fix relative path test on windows


import React from 'react';

import './NavMenu.css';

export default function NavMenu({ currentPage, setCurrentPage }) {
  const chooseClasses = ['entry', 'choose'];
  const browseClasses = ['entry', 'browse'];

  if (currentPage === 'choose') {
    chooseClasses.push('selected');
  } else {
    browseClasses.push('selected');
  }

  return (
    <nav className="NavMenu">
      <span
        onClick={() => setCurrentPage('choose')}
        className={chooseClasses.join(' ')}
      >
        Choose the most common stereotype
      </span>{' '}
      {/* or{' '}
      <span
        onClick={() => setCurrentPage('browse')}
        className={browseClasses.join(' ')}
      >
        browse stereotypes
  </span>*/}
    </nav>
  );
}

import React from 'react';

import './NavMenu.css';

export default function NavMenu({ currentPage, setCurrentPage }) {
  const chooseClasses = ['entry', 'choose'];
  const browseClasses = ['entry', 'browse'];

  if (currentPage === 'choose') {
    chooseClasses.push('selected');
  } else {
    browseClasses.push('selected');
  }

  return (
    <nav className="NavMenu">
      <span
        onClick={() => setCurrentPage('choose')}
        className={chooseClasses.join(' ')}
      >
        Choose the most common stereotype
      </span>{' '}
      or{' '}
      <span
        onClick={() => setCurrentPage('browse')}
        className={browseClasses.join(' ')}
      >
        browse stereotypes
      </span>
    </nav>
  );
}

Revert "Hide browse menu entry"


const { defineConfig } = require('cypress')

module.exports = defineConfig({
  e2e: {
    // We've imported your old cypress plugins here.
    // You may want to clean this up later by importing these.
    setupNodeEvents(on, config) {
      return require('./cypress/plugins/index.js')(on, config)
    },
  },
})

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  retries: 3,
  video: false,
  e2e: {
    setupNodeEvents(on, config) {
      return require('./cypress/plugins/index.js')(on, config)
    },
  },
})

Disable video recording in Cypress


// Program that creates a binary search tree: each node has up to two children, and all left descendants of a node is less than or equal to the node and all right descendants are greater than the node

// create node class
function Node(val) {
	this.value = val;
	this.left = null;
	this.right = null;
}

// create constructor for binary search tree
function BinarySearchTree() {
	this.root = null;
}

BinarySearchTree.prototype.push = function(val){
	var rootNode = this.root;

	if(!rootNode){
		this.root = new Node(val);
		return;
	}

	var currentNode = rootNode;
	var newNode = new Node(val);

	while(currentNode){
		if(val < currentNode.value){
			if(!currentNode.left){
				currentNode.left = newNode;
				break;
			} else {
				currentNode = currentNode.left;
			}
		} else {
			if(!currentNode.right) {
				currentNode.right = newNode;
				break;
			} else {
				currentNode = currentNode.right;
			}
		}
	}
}

// Program that creates a binary search tree: each node has up to two children, and all left descendants of a node is less than or equal to the node and all right descendants are greater than the node

// create node class
function Node(val) {
	this.value = val;
	this.left = null;
	this.right = null;
}

// create constructor for binary search tree
function BinarySearchTree() {
	this.root = null;
}

// function for inserting value into appropriate location in tree
BinarySearchTree.prototype.push = function(val){
	var rootNode = this.root;

	// if there is no root node
	if(!rootNode){
		this.root = new Node(val);
		return;
	}

	var currentNode = rootNode;
	var newNode = new Node(val);

	while(currentNode){
		if(val < currentNode.value){
			if(!currentNode.left){
				currentNode.left = newNode;
				break;
			} else {
				currentNode = currentNode.left;
			}
		} else {
			if(!currentNode.right) {
				currentNode.right = newNode;
				break;
			} else {
				currentNode = currentNode.right;
			}
		}
	}
}

// test case
var testTree = new BinarySearchTree();
testTree.push(4);
testTree.push(9);
testTree.push(2);
testTree.push(7);
testTree.push(3);
// expect 4 to be root node, 2 to be left child and 9 to be right child of 4, 7 to be left child of 9, and 3 to be right child of 2
console.log(testTree);

Add test case for binary search tree program


var uuid = require("uuid");
var Dialog = require("../dialog");

module.exports = function(apiToken, botId) {
  this.apiToken = apiToken;
  this.botId = botId;

  this.incoming = function(message) {
    var payload = {
      message: {
        conversation_distinct_id: message.chatId,
        creator_distinct_id: message.from,
        distinct_id: message.id,
        platform: 'kik',
        provider: 'kik',
        mtype: message.type,
        sent_at: message.timestamp / 1000,
        properties: {
          text: message.body
        }
      }
    };

    return Dialog.track(apiToken, botId, payload);
  },

  this.outgoing = function(object) {
    var payload = {
      message: {
        conversation_distinct_id: object.chatId,
        distinct_id: uuid.v4(),
        platform: 'kik',
        provider: 'kik',
        mtype: object.type,
        sent_at: new Date().getTime() / 1000,
        properties: {
          text: object.body
        }
      }
    };

    return Dialog.track(apiToken, botId, payload);
  }
};

var uuid = require("uuid");
var Dialog = require("../dialog");

module.exports = function(apiToken, botId) {
  this.apiToken = apiToken;
  this.botId = botId;

  this.incoming = function(message) {
    var payload = {
      message: {
        conversation_distinct_id: message.chatId,
        creator_distinct_id: message.from,
        creator_type: 'Interlocutor',
        distinct_id: message.id,
        platform: 'kik',
        provider: 'kik',
        mtype: message.type,
        sent_at: message.timestamp / 1000,
        properties: {
          text: message.body
        }
      }
    };

    return Dialog.track(apiToken, botId, payload);
  },

  this.outgoing = function(object) {
    var payload = {
      message: {
        conversation_distinct_id: object.chatId,
        creator_distinct_id: botId,
        creator_type: 'Bot',
        distinct_id: uuid.v4(),
        platform: 'kik',
        provider: 'kik',
        mtype: object.type,
        sent_at: new Date().getTime() / 1000,
        properties: {
          text: object.body
        }
      }
    };

    return Dialog.track(apiToken, botId, payload);
  }
};

Add creator_type and creator_distinct_id in payload


module.exports = function(config) {
  config.set({
    frameworks: ['mocha'],

    exclude: ['build/test/external.spec.js'],

    files: [
      'vendor/es5-shim.js',
      'vendor/es5-sham.js',
      'vendor/rsvp.js',
      'vendor/unexpected-magicpen.min.js',
      'build/test/promisePolyfill.js',
      'unexpected.js',
      'build/test/common.js',
      'build/test/**/*.spec.js'
    ],

    browsers: ['ChromeHeadlessNoSandbox', 'ie11'],

    client: {
      mocha: {
        reporter: 'html'
      }
    },

    browserStack: {
      video: false,
      project: 'unexpected'
    },

    customLaunchers: {
      ChromeHeadlessNoSandbox: {
        base: 'ChromeHeadless',
        flags: ['--no-sandbox']
      },
      ie11: {
        base: 'BrowserStack',
        browser: 'IE',
        browser_version: '11',
        os: 'Windows',
        os_version: '7'
      }
    },

    reporters: ['dots', 'BrowserStack']
  });
};

module.exports = function(config) {
  config.set({
    frameworks: ['mocha'],

    exclude: ['build/test/external.spec.js'],

    files: [
      'vendor/es5-shim.js',
      'vendor/es5-sham.js',
      'vendor/rsvp.js',
      'vendor/unexpected-magicpen.min.js',
      'build/test/promisePolyfill.js',
      'unexpected.js',
      'build/test/common.js',
      'build/test/**/*.spec.js'
    ],

    browsers: ['ChromeHeadlessNoSandbox', 'ie11'],

    client: {
      mocha: {
        reporter: 'html',
        timeout: 10000
      }
    },

    browserStack: {
      video: false,
      project: 'unexpected'
    },

    customLaunchers: {
      ChromeHeadlessNoSandbox: {
        base: 'ChromeHeadless',
        flags: ['--no-sandbox']
      },
      ie11: {
        base: 'BrowserStack',
        browser: 'IE',
        browser_version: '11',
        os: 'Windows',
        os_version: '7'
      }
    },

    reporters: ['dots', 'BrowserStack']
  });
};

Increase the timeout to 10s in an attempt to avoid random failures


/*jslint browser: true, undef: true *//*global Ext*/
Ext.define('SlateAdmin.proxy.API', {
    extend: 'Emergence.proxy.API',
    alias: 'proxy.slateapi',

    config: {
        include: null
    },

    connection: 'SlateAdmin.API'
});

/*jslint browser: true, undef: true *//*global Ext*/
Ext.define('SlateAdmin.proxy.API', {
    extend: 'Jarvus.proxy.API',
    alias: 'proxy.slateapi',

    config: {
        include: null
    },

    connection: 'SlateAdmin.API'
});

Remove reference to deleted file


'use strict'

class HelloMessage2 extends Cape.Component {
  constructor(name) {
    super()
    this.names = [ 'alice', 'bob', 'charlie' ]
    this.name = name
  }

  render(m) {
    m.h1('Greeting')
    m.p('Who are you?')
    m.div(m => {
      this.names.forEach(name => {
        m.checked(name === this.name)
          .onclick(e => { this.name = e.target.value; this.refresh() })
          .radioButton('name', name)
        m.sp()
        m.text(name)
      })
    })
    m.class('message').p(m => {
      m.text('Hello, ')
      m.em(this.name + '!')
      m.sp()
      m.text('My name is Cape.JS.')
    })
  }
}

if (typeof module !== 'undefined' && module.exports) module.exports = HelloMessage2

'use strict'

class HelloMessage2 extends Cape.Component {
  constructor(name) {
    super()
    this.names = [ 'alice', 'bob', 'charlie' ]
    this.name = name
  }

  render(m) {
    m.h1('Greeting')
    m.p('Who are you?')
    m.div(m => {
      this.names.forEach(name => {
        m.label(m => {
          m.checked(name === this.name)
            .onclick(e => { this.name = e.target.value; this.refresh() })
            .radioButton('name', name)
          m.sp()
          m.text(name)
        })
      })
    })
    m.class('message').p(m => {
      m.text('Hello, ')
      m.em(this.name + '!')
      m.sp()
      m.text('My name is Cape.JS.')
    })
  }
}

if (typeof module !== 'undefined' && module.exports) module.exports = HelloMessage2

Put radio buttons within <label> element


/* jshint unused: false */
import ajax from 'ghost/utils/ajax';
import ValidationEngine from 'ghost/mixins/validation-engine';

var ForgottenController = Ember.Controller.extend(ValidationEngine, {
    email: '',
    submitting: false,

    // ValidationEngine settings
    validationType: 'forgotten',

    actions: {
        submit: function () {
            var self = this,
                data = self.getProperties('email');

            this.toggleProperty('submitting');
            this.validate({ format: false }).then(function () {
                ajax({
                    url: self.get('ghostPaths.url').api('authentication', 'passwordreset'),
                    type: 'POST',
                    data: {
                        passwordreset: [{
                            email: data.email
                        }]
                    }
                }).then(function (resp) {
                    self.toggleProperty('submitting');
                    self.notifications.showSuccess('Please check your email for instructions.');
                    self.transitionToRoute('signin');
                }).catch(function (resp) {
                    self.toggleProperty('submitting');
                    self.notifications.showAPIError(resp, 'There was a problem logging in, please try again.');
                });
            }).catch(function (errors) {
                self.toggleProperty('submitting');
                self.notifications.showErrors(errors);
            });
        }
    }
});

export default ForgottenController;

/* jshint unused: false */
import ajax from 'ghost/utils/ajax';
import ValidationEngine from 'ghost/mixins/validation-engine';

var ForgottenController = Ember.Controller.extend(ValidationEngine, {
    email: '',
    submitting: false,

    // ValidationEngine settings
    validationType: 'forgotten',

    actions: {
        submit: function () {
            var self = this,
                data = self.getProperties('email');

            this.toggleProperty('submitting');
            this.validate({ format: false }).then(function () {
                ajax({
                    url: self.get('ghostPaths.url').api('authentication', 'passwordreset'),
                    type: 'POST',
                    data: {
                        passwordreset: [{
                            email: data.email
                        }]
                    }
                }).then(function (resp) {
                    self.toggleProperty('submitting');
                    self.notifications.showSuccess('Please check your email for instructions.');
                    self.transitionToRoute('signin');
                }).catch(function (resp) {
                    self.toggleProperty('submitting');
                    self.notifications.closePassive();
                    self.notifications.showAPIError(resp, 'There was a problem logging in, please try again.');
                });
            }).catch(function (errors) {
                self.toggleProperty('submitting');
                self.notifications.closePassive();
                self.notifications.showErrors(errors);
            });
        }
    }
});

export default ForgottenController;

Stop validation error notification stack


/*******************************************************************************
 * @license
 * Copyright (c) 2013 VMware, Inc. All Rights Reserved.
 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
 * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
 * CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
 * You can obtain a current copy of the Eclipse Public License from
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * Contributors:
 * Andy Clement - initial version
 ******************************************************************************/

/**
 * This code will launch the scripted server (via scriptedServer.js) and then
 * optionally open a URL on that server.
 */

var path = require('path');
var openBrowser = require('./open').open;
var url = "http://localhost:7261";
var suppressOpen = process.argv[2]=='true';
var file = process.argv[3];

var filesystem = require('../server/utils/filesystem').withBaseDir(null);

// Launch the server
var server=require('../server/scriptedServer.js').start(filesystem);

// on return, assume it is up and open the browser
if (!suppressOpen) {
	openBrowser(process.argv[3]);
}

/*******************************************************************************
 * @license
 * Copyright (c) 2013 VMware, Inc. All Rights Reserved.
 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
 * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
 * CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
 * You can obtain a current copy of the Eclipse Public License from
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * Contributors:
 * Andy Clement - initial version
 ******************************************************************************/

/**
 * This code will launch the scripted server (via scriptedServer.js) and then
 * optionally open a URL on that server.
 */

var path = require('path');
var openBrowser = require('./open').open;
var url = "http://localhost:7261";
var suppressOpen = process.argv[2]=='true';
var file = process.argv[3];

var filesystem = require('../server/utils/filesystem').withBaseDir(null);

// Hack alert! The code below is just to play with a very simple case of
// a 'plugable fs'.
//var filesystem = require('../server/utils/filesystem').withBaseDir('/home/kdvolder', {
//	userHome: '/',
//	scriptedHome: 'commandline-dev/new-tools/scripted'
//});

// Launch the server
var server=require('../server/scriptedServer.js').start(filesystem);

// on return, assume it is up and open the browser
if (!suppressOpen) {
	openBrowser(process.argv[3]);
}

Add some commented code to play with a different fs.


// @flow

import { reduxForm, SubmissionError } from 'redux-form';
import { handleSubmissionError } from './utils';

type Props = {
  onSubmitFail: any => any,
  onSubmit: any => Promise<*>,
  /* Enable auto submissionError */
  enableSubmissionError?: boolean,
  /* Move the screen to the first error in the list on SubmissionError */
  enableFocusOnError?: boolean,
  ...any
};

const legoForm = ({
  onSubmitFail = () => {},
  onSubmit,
  enableSubmissionError = true,
  enableFocusOnError = true,
  ...rest
}: Props) =>
  reduxForm({
    ...rest,
    onSubmitFail: errors => {
      onSubmitFail(errors);

      if (!enableFocusOnError) {
        return;
      }

      try {
        // We should instead check if error is SubmissionError. Does not work now
        const [firstErrorField] = Object.keys(errors);

        const field = document.querySelector(`[name="${firstErrorField}"]`);
        if (field && field.focus) {
          field.focus();
        }
      } catch (e) {
        //
      }
    },
    onSubmit: (values, dispatch, props) =>
      onSubmit(values, dispatch, props).catch(error => {
        if (error instanceof SubmissionError || !enableSubmissionError) {
          throw error;
        }

        return handleSubmissionError(error);
      })
  });

export default legoForm;

// @flow

import { reduxForm, SubmissionError } from 'redux-form';
import { handleSubmissionError } from './utils';
import { pick, difference } from 'lodash';
type Props = {
  onSubmitFail: any => any,
  onSubmit: any => Promise<*>,
  /* Enable auto submissionError */
  enableSubmissionError?: boolean,
  /* Move the screen to the first error in the list on SubmissionError */
  enableFocusOnError?: boolean,
  ...any
};

const legoForm = ({
  onSubmitFail = () => {},
  onSubmit,
  enableSubmissionError = true,
  enableFocusOnError = true,
  ...rest
}: Props) =>
  reduxForm({
    ...rest,
    onSubmitFail: errors => {
      onSubmitFail(errors);

      if (!enableFocusOnError) {
        return;
      }

      try {
        // We should instead check if error is SubmissionError. Does not work now
        const [firstErrorField] = Object.keys(errors);

        const field = document.querySelector(`[name="${firstErrorField}"]`);
        if (field && field.focus) {
          field.focus();
        }
      } catch (e) {
        //
      }
    },
    onSubmit: (values, dispatch, props) => {
      const data = pick(values, Object.keys(props.registeredFields));

      console.log(
        'Diff (lost in translation): ',
        difference(Object.keys(values), Object.keys(data))
      );

      return onSubmit(data, dispatch, props).catch(error => {
        if (error instanceof SubmissionError || !enableSubmissionError) {
          throw error;
        }

        return handleSubmissionError(error);
      });
    }
  });

export default legoForm;

Add initial support for value filtering


const readDir = require('../readDir.js')

describe('readDir.js', () => {
  describe('fileArrayToObject', () => {
    it('transforms an array to an object', () => {
      expect(
        readDir.fileArrayToObject([
          { name: 'one' },
          { name: 'two' },
          { name: 'three' },
        ]),
      ).toEqual({
        '0': {
          name: 'one',
        },
        '1': {
          name: 'two',
        },
        '2': {
          name: 'three',
        },
      })
    })
  })
  describe('harmonizeRelativePath', () => {
    it('harmonizes a basic POSIX path', () => {
      expect(readDir.harmonizeRelativePath('test/a/path')).toEqual('/a/path')
    })
    it('does not mangle absolute Windows paths', () => {
      expect(readDir.harmonizeRelativePath('C:\\dataset\\directory')).toEqual(
        '/dataset/directory',
      )
    })
    it('does not mangle relative Windows paths', () => {
      expect(readDir.harmonizeRelativePath('dataset\\directory')).toEqual(
        '/directory',
      )
    })
  })
})

const readDir = require('../readDir.js')

describe('readDir.js', () => {
  describe('fileArrayToObject', () => {
    it('transforms an array to an object', () => {
      expect(
        readDir.fileArrayToObject([
          { name: 'one' },
          { name: 'two' },
          { name: 'three' },
        ]),
      ).toEqual({
        '0': {
          name: 'one',
        },
        '1': {
          name: 'two',
        },
        '2': {
          name: 'three',
        },
      })
    })
  })
  describe('harmonizeRelativePath', () => {
    it('harmonizes a basic POSIX path', () => {
      expect(readDir.harmonizeRelativePath('test/a/path')).toEqual('/a/path')
    })
    it('does not mangle absolute Windows paths', () => {
      expect(readDir.harmonizeRelativePath('C:\\dataset\\directory')).toEqual(
        '/dataset/directory',
      )
    })
    it('does not mangle relative Windows paths', () => {
      expect(readDir.harmonizeRelativePath('dataset\\directory')).toEqual(
        '/directory',
      )
    })
    it('does not mangle relative Windows paths with parent directories', () => {
      expect(
        readDir.harmonizeRelativePath('..\\..\\dataset\\directory'),
      ).toEqual('/../dataset/directory')
    })
  })
})

Add one more test for Windows paths in harmonizeRelativePath


const {Button, TextView, contentView} = require('tabris');

new Button({
  centerX: true, top: 100,
  text: 'Show message'
}).onSelect(() => {
  textView.text = 'Tabris.js rocks!';
}).appendTo(contentView);

const textView = new TextView({
  centerX: true, top: 'prev() 50',
  font: '24px'
}).appendTo(contentView);

const {Button, TextView, contentView} = require('tabris');

contentView.append(
  Button({
    centerX: true, top: 100,
    text: 'Show message',
    onSelect: () => $(TextView).only().text = 'Tabris.js rocks!'
  }),
  TextView({
    centerX: true, top: 'prev() 50',
    font: '24px'
  })
);

Update vanilla JavaScript template to use factory API


var request = require('supertest');
var JSONAPIValidator = require('jsonapi-validator').Validator;

validateJSONapi = function(res) {
  var validator = new JSONAPIValidator();

  validator.validate(res.body);
}

describe('Error handling', function() {
  describe('GET /fake', function() {
    it('Should return 404', function(done) {
      request(sails.hooks.http.app)
        .get('/fake')
        .expect(404)
        .expect(validateJSONapi)
        .end(done);
    });
  });

  describe('GET /users/42', function() {
    it('Should return 404', function(done) {
      request(sails.hooks.http.app)
        .get('/users/42')
        .expect(404)
        .expect(validateJSONapi)

  describe('GET categories?invalid=true', function() {
    it('Should return 400', function(done) {
      request(sails.hooks.http.app)
        .get('/categories?invalid=true')
        .expect(400)
        .expect(validateJSONapi)
        .expect({
          'errors': [
            {
              status: "400",
              title: 'Bad request'
            }
          ]
        })
        .end(done);
    });
  });
});

var request = require('supertest');
var JSONAPIValidator = require('jsonapi-validator').Validator;

validateJSONapi = function(res) {
  var validator = new JSONAPIValidator();

  validator.validate(res.body);
}

describe('Error handling', function() {
  describe('GET /fake', function() {
    it('Should return 404', function(done) {
      request(sails.hooks.http.app)
        .get('/fake')
        .expect(404)
        .expect(validateJSONapi)
        .expect({
          'errors': [
            {
              status: "404",
              title: 'Resource not found'
            }
          ]
        })
        .end(done);
    });
  });

  describe('GET /users/42', function() {
    it('Should return 404', function(done) {
      request(sails.hooks.http.app)
        .get('/users/42')
        .expect(404)
        .expect(validateJSONapi)
        .expect({
          'errors': [
            {
              status: "404",
              title: 'Resource not found',
              detail: 'No record found with the specified id.'
            }
          ]
        })
        .end(done);
    });
  });

  describe('GET categories?invalid=true', function() {
    it('Should return 400', function(done) {
      request(sails.hooks.http.app)
        .get('/categories?invalid=true')
        .expect(400)
        .expect(validateJSONapi)
        .expect({
          'errors': [
            {
              status: "400",
              title: 'Bad request'
            }
          ]
        })
        .end(done);
    });
  });
});

Add expectation on Error output


// Webpack config to serve the JSX component with bundled styles

import path from 'path';

const demoPath = path.join(__dirname, './demo');
const sourcePath = path.join(__dirname, './src');

export default {
  entry: {
    js: [demoPath.concat('/render.js')],
  },
  output: {
    path: demoPath,
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        loaders: [
          'style-loader',
          {
            loader: 'css-loader',
            query: {
              modules: true,
            },
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: ['.js', '.jsx'],
    modules: [
      path.resolve(__dirname, 'node_modules'),
      sourcePath,
    ],
  },
};

// Webpack config to serve the JSX component with bundled styles

import path from 'path';

const demoPath = path.join(__dirname, './demo');
const sourcePath = path.join(__dirname, './src');

export default {
  entry: {
    js: [demoPath.concat('/render.js')],
  },
  output: {
    path: demoPath,
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        loaders: [
          'style-loader',
          {
            loader: 'css-loader',
            query: {
              modules: false,
            },
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: ['.js', '.jsx'],
    modules: [
      path.resolve(__dirname, 'node_modules'),
      sourcePath,
    ],
  },
};

Use global classes for easier testing


/*globals define*/
define(function() {
  'use strict';

  var PI2 = 2 * Math.PI;

  var DEG_TO_RAD = Math.PI / 180,
      RAD_TO_DEG = 180 / Math.PI;

  function clamp( value, min, max ) {
    return Math.min( Math.max( value, min ), max );
  }

  return {
    PI2: PI2,

    DEG_TO_RAD: DEG_TO_RAD,
    RAD_TO_DEG: RAD_TO_DEG,

    clamp: clamp
  };
});

/*globals define*/
define(function() {
  'use strict';

  var PI2 = 2 * Math.PI;

  var DEG_TO_RAD = Math.PI / 180,
      RAD_TO_DEG = 180 / Math.PI;

  function clamp( value, min, max ) {
    return Math.min( Math.max( value, min ), max );
  }

  function distanceSquared( x0, y0, x1, y1 ) {
    var dx = x1 - x0,
        dy = y1 - y0;

    return dx * dx + dy * dy;
  }

  function distance( x0, y0, x1, y1 ) {
    return Math.sqrt( distanceSquared( x0, y0, x1 ,y1 ) );
  }

  function circleContains( x, y, cx, cy, radius ) {
    return distanceSquared( x, y, cx, cy ) < radius * radius;
  }

  return {
    PI2: PI2,

    DEG_TO_RAD: DEG_TO_RAD,
    RAD_TO_DEG: RAD_TO_DEG,

    clamp: clamp,

    distanceSquared: distanceSquared,
    distance: distance,

    circleContains: circleContains
  };
});

Add distance/circleContains functions to Utils.


var fs = require('fs');

var ids = [];
var dir = fs.readdirSync('draw/metadata');
for (var i = 0; i < dir.length; i++) {
	var filename = dir[i];
	if (filename.substr(0, 1) == '.') continue;
	ids.push(filename.substr(0, filename.length - 5))
}

fs.writeFile('draw/metadata-id-list.json', JSON.stringify(ids));

var fs = require('fs');
var jsonFile = process.argv[2];

// Input file
if (jsonFile == undefined) {
	console.error('Please specify a JSON file to parse!');
	process.exit(1);
}
if (!fs.existsSync(jsonFile)) {
	console.error('Specified file does not exist!', jsonFile);
	process.exit(2);
}

var ids = [];
var data = require('./' + jsonFile);
for (var i = 0; i < data.length; i++) {
	// Try and find an ID
	if (data[i].hasOwnProperty('ID'))
		var id = data[i].ID.toString();
	else if (data[i].hasOwnProperty('id'))
		var id = data[i].id.toString();
	else {
		console.warn('Cannot determine ID:', data[i]);
		continue;
	}

	ids.push(id)
}

fs.writeFile('draw/metadata-id-list.json', JSON.stringify(ids));

Update generate metadata id script for draw


const dataviews = require('./');

module.exports = class DataviewFactory {
    static get dataviews() {
        return Object.keys(dataviews).reduce((allDataviews, dataviewClassName) => {
            allDataviews[dataviewClassName.toLowerCase()] = dataviews[dataviewClassName];
            return allDataviews;
        }, {});
    }

    static getDataview (query, dataviewDefinition) {
        const type = dataviewDefinition.type;
        if (!this.dataviews[type]) {
            throw new Error('Invalid dataview type: "' + type + '"');
        }
        return new this.dataviews[type](query, dataviewDefinition.options, dataviewDefinition.sql);
    }
};

const dataviews = require('./');

module.exports = class DataviewFactory {
    static get dataviews() {
        return Object.keys(dataviews).reduce((allDataviews, dataviewClassName) => {
            allDataviews[dataviewClassName.toLowerCase()] = dataviews[dataviewClassName];
            return allDataviews;
        }, {});
    }

    static getDataview (query, dataviewDefinition) {
        const { type, options, sql } = dataviewDefinition;

        if (!this.dataviews[type]) {
            throw new Error('Invalid dataview type: "' + type + '"');
        }

        return new this.dataviews[type](query, options, sql);
    }
};

Use destructuring assignment to improve readability


export default [
  { "id": "002", "desc": "Email" },
  { "id": "001", "desc": "Mail (Primary Address)" },
  { "id": "003", "desc": "Text message" },
];

export default [
  { id: '002', desc: 'Email' },
  { id: '001', desc: 'Mail (Primary Address)' },
  { id: '003', desc: 'Text message' },
];

Fix ESLint errors. Towards UIU-372


import * as utility from './utility.js'

/**
 * the function to submit form via ajax in dendrogram
 * @returns {void} - nothing is returned from this function.
 */
function generateDendrogram () {
  // show loading icon
  $('#status-analyze').css({'visibility': 'visible'})

  // convert form into an object map string to string
  const form = utility.jsonifyForm()

  // send the ajax request
  utility.sendAjaxRequest('/dendrogramDiv', form)
    .done(
      function (response) {
        $('#dendrogram-result').html(response)
      })
    .fail(
      function (jqXHR, textStatus, errorThrown) {
        console.log('textStatus: ' + textStatus)
        console.log('errorThrown: ' + errorThrown)
        utility.runModal('error encountered while plotting the dendrogram.')
      })
    .always(
      function () {
        $('#status-analyze').css({'visibility': 'hidden'})
      })
}

/**
 * Scrolls to dendrogram results after they are generated.
 * @returns {void}
 */
function scrollToDendro () {
  $('html, body').animate({
    scrollTop: $('#dendrogram-result').offset().top
  }, 1000)
}

/**
 * When the HTML documents finish loading
 */
$(function () {
  /**
   * the events after dendrogram is clicked
   */
  $('#getdendro').on('click', function () {
    const error = utility.submissionError(2) // the error happens during submission

    if (error === null) { // if there is no error
      generateDendrogram()
      scrollToDendro()
    } else {
      utility.runModal(error)
    }
  })
})

import * as utility from './utility.js'

/**
 * the function to submit form via ajax in dendrogram
 * @returns {void} - nothing is returned from this function.
 */
function generateDendrogram () {
  // show loading icon
  $('#status-analyze').css({'visibility': 'visible'})

  // convert form into an object map string to string
  const form = utility.jsonifyForm()

  // send the ajax request
  utility.sendAjaxRequest('/dendrogramDiv', form)
    .done(
      function (response) {
        $('#dendrogram-result').html(response)
      })
    .fail(
      function (jqXHR, textStatus, errorThrown) {
        console.log('textStatus: ' + textStatus)
        console.log('errorThrown: ' + errorThrown)
        utility.runModal('error encountered while plotting the dendrogram.')
      })
    .always(
      function () {
        $('#status-analyze').css({'visibility': 'hidden'})
      })
}

/**
 * When the HTML documents finish loading
 */
$(function () {
  /**
   * the events after dendrogram is clicked
   */
  $('#getdendro').on('click', function () {
    const error = utility.submissionError(2) // the error happens during submission

    if (error === null) { // if there is no error
      generateDendrogram()
      utility.scrollToDiv($('#dendrogram-result'))
    } else {
      utility.runModal(error)
    }
  })
})

Use the function in dendrogram


var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: path.join(__dirname, './docs/index.ts'),
  output: {
    path: path.join(__dirname, './docs/assets'),
    filename: 'app.js'
  },
  devtool: 'source-map',
  resolve: {
    alias: {
      'css-animator': '../src/css-animator'
    },
    extensions: ['.ts', '.js']
  },
  module: {
    rules: [
      {
        test: /\.(js|ts)$/,
        exclude: [path.join(__dirname, 'node_modules', '@angular/compiler')],
        use: ['source-map-loader'],
        enforce: 'pre'
      }, {
        test: /\.tsx?$/,
        use: [
          {
            loader: 'ts-loader'
          }
        ]
      }
    ]
  },
  plugins: [
    // See https://github.com/angular/angular/issues/11580
    // See https://github.com/angular/angular/issues/14898
    new webpack.ContextReplacementPlugin(
      /angular(\\|\/)core(\\|\/)(@angular|esm5)/,
      path.resolve(__dirname, '../src')
    )
  ]
}

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: path.join(__dirname, './docs/index.ts'),
  output: {
    path: path.join(__dirname, './docs/assets'),
    filename: 'app.js'
  },
  devtool: 'source-map',
  resolve: {
    alias: {
      'css-animator': '../src/css-animator'
    },
    extensions: ['.ts', '.js']
  },
  module: {
    rules: [
      {
        test: /\.(js|ts)$/,
        exclude: [path.join(__dirname, 'node_modules')],
        use: ['source-map-loader'],
        enforce: 'pre'
      }, {
        test: /\.tsx?$/,
        use: [
          {
            loader: 'ts-loader'
          }
        ]
      }
    ]
  },
  plugins: [
    // See https://github.com/angular/angular/issues/11580
    // See https://github.com/angular/angular/issues/14898
    new webpack.ContextReplacementPlugin(
      /angular(\\|\/)core(\\|\/)(@angular|esm5)/,
      path.resolve(__dirname, '../src')
    )
  ]
}

Exclude node_modules from example source maps


//= require jquery
//= require jquery.ui.all
//= require jquery_ujs
//= require jquery-fileupload
//= require twitter/bootstrap
//= require select2
//= require shadowbox
//= require mousetrap

//= require ckeditor/init
//= require_tree .//ckeditor

//= require handlebars.runtime
//= require underscore
//= require backbone
//= require_tree ./../../templates/
//= require_tree .//models
//= require_tree .//collections
//= require_tree .//views
//= require_tree .//routers

//= require .//backbone-relational
//= require .//bootstrap
//= require .//featured-image
//= require .//form-actions
//= require .//jquery.mjs.nestedSortable
//= require .//jquery.ui.touch-punch
//= require .//keybindings
//= require .//media
//= require .//pages
//= require .//panels
//= require .//tags

//= require jquery
//= require jquery.ui.all
//= require jquery_ujs
//= require jquery-fileupload
//= require twitter/bootstrap
//= require select2
//= require shadowbox
//= require mousetrap

//= require ckeditor/init
//= require_tree .//ckeditor

//= require handlebars.runtime
//= require underscore
//= require backbone
//= require georgia/backbone-relational
//= require georgia/panels
//= require_tree ./../../templates/
//= require_tree .//models
//= require_tree .//collections
//= require_tree .//views
//= require_tree .//routers

//= require georgia/bootstrap
//= require georgia/featured-image
//= require georgia/form-actions
//= require georgia/jquery.mjs.nestedSortable
//= require georgia/jquery.ui.touch-punch
//= require georgia/keybindings
//= require georgia/media
//= require georgia/pages
//= require georgia/tags

Fix javascript file ordering in manifest


'use strict'

import React, { Component } from 'react'
import ReactCSS from 'reactcss'

import colors from '../../assets/styles/variables/colors'

class ComposerFormSubmit extends Component {
  classes() {
    return {
      'default': {
        confirm: {
          color: '#fff',
          padding: '10px 30px',
          borderRadius: '5px',
          backgroundColor: colors.primary,
          textDecoration: 'none',
          cursor: 'pointer',
          textAlign: 'center',
          display: 'block',
          transition: '200ms ease-in-out',
        },
      },
      hover: {
        confirm: {
          backgroundColor: '#BF1B23',
        },
      },
    }
  }

  render() {
    return (
      { this.props.value }
    )
  }
}

export default ReactCSS.Hover(ReactCSS(ComposerFormSubmit))

'use strict'

import React, { Component } from 'react'
import ReactCSS from 'reactcss'

import colors from '../../assets/styles/variables/colors'

class ComposerFormSubmit extends Component {
  state = { value: this.props.value }

  classes() {
    return {
      'default': {
        confirm: {
          color: '#fff',
          padding: '10px 30px',
          borderRadius: '5px',
          backgroundColor: colors.primary,
          textDecoration: 'none',
          cursor: 'pointer',
          textAlign: 'center',
          display: 'block',
          transition: '200ms ease-in-out',
        },
      },
      hover: {
        confirm: {
          backgroundColor: '#BF1B23',
        },
      },
    }
  }

  componentWillReceiveProps = (nextProps) => {
    this.setState({ value: nextProps.value })
  }

  handleClick = (clickFn) => {
    return () => {
      this.setState({ value: 'Hold Your Breath...' })
      clickFn()
    }
  }

  render() {
    return (
      <a
        is="link confirm"
        onClick={ this.handleClick(this.props.onClick) }
      >
        { this.state.value }
      </a>
    )
  }
}

export default ReactCSS.Hover(ReactCSS(ComposerFormSubmit))

Add loading message to submit button


var fs = require('fs');
var path = require('path');

var root = path.join(__dirname, 'aws-sdk');
if (!fs.existsSync(root)) {
  root = path.join(__dirname, '..', 'lib');
}
root = path.normalize(root);

module.exports = {
  root: root,
  mainFile: path.join(root, 'aws.js'),
  browserFile: path.join(root, 'browser.js'),
  servicesFile: path.join(root, 'services.js'),
  defaultServices: 'dynamodb,s3,sqs,sns,sts'
};

var fs = require('fs');
var path = require('path');

var root = path.join(__dirname, 'aws-sdk');
if (!fs.existsSync(root)) {
  root = path.join(__dirname, '..', 'lib');
}
root = path.normalize(root);

module.exports = {
  root: root,
  mainFile: path.join(root, 'aws.js'),
  browserFile: path.join(root, 'browser.js'),
  servicesFile: path.join(root, 'services.js'),
  defaultServices: 'dynamodb,s3,sqs,sns,sts,kinesis,cloudwatch'
};

Add Amazon Kinesis and Amazon CloudWatch to default hosted build.


"use strict";

import h from "yasmf-h";
import el from "$LIB/templates/el";
import L from "$APP/localization/localization";

import glyph from "$WIDGETS/glyph";
import list from "$WIDGETS/list";
import listItem from "$WIDGETS/listItem";
import listItemContents from "$WIDGETS/listItemContents";
import listItemActions from "$WIDGETS/listItemActions";
import lemmaActions from "./lemmaActions";

export default function lemmaList(lemmas) {
    return list({
        contents: lemmas.map( lemma => {
            return listItem({
                contents: listItemContents({
                    props: {
                        value: lemma
                    },
                    contents: [
                        h.el("div.y-flex", lemma)
                    ]
                }),
                actions: listItemActions({ contents: lemmaActions() })
           });
        })
    });
}

"use strict";

import h from "yasmf-h";
import el from "$LIB/templates/el";
import L from "$APP/localization/localization";

import glyph from "$WIDGETS/glyph";
import list from "$WIDGETS/list";
import listItem from "$WIDGETS/listItem";
import listItemContents from "$WIDGETS/listItemContents";
import listItemActions from "$WIDGETS/listItemActions";
import lemmaActions from "./lemmaActions";

export default function lemmaList(lemmas) {
    return list({
        contents: lemmas.map( lemma => {
            return listItem({
                contents: listItemContents({
                    props: {
                        value: lemma
                    },
                    contents: [
                        h.el("div.y-flex", lemma)
                    ]
                })
           });
        })
    });
}

Remove actions from each lemma


var fs = require('fs');
var classes = require('bespoke-classes');
var insertCss = require('insert-css');

module.exports = function() {
  return function(deck) {
    classes()(deck);
    var css = fs.readFileSync(__dirname + '/tmp/theme.css', 'utf8');
    insertCss(css, { prepend: true });
  };
};

var fs = require('fs');
var classes = require('bespoke-classes');
var insertCss = require('insert-css');

module.exports = function() {
  var css = fs.readFileSync(__dirname + '/tmp/theme.css', 'utf8');
  insertCss(css, { prepend: true });

  return function(deck) {
    classes()(deck);
  };
};

Insert CSS during config phase


/**
 * Mediate those wretched vendor prefixes for onTransitionEnd.
 *
 * Older browsers only supported the event with prefixed names (Opera being
 * the worst offender). Whichever name is needed to support transition events
 * in a running browser (prefixed or not) is stored in TransitionEvent.END.
 *
 * URL: https://developer.mozilla.org/en-US/docs/Web/Events/transitionend
 */
(function(o){
	if(o.END) return;
	for(var names = "transitionend webkitTransitionEnd oTransitionEnd otransitionend".split(" "), i = 0; i < 4; ++i)
		if("on"+names[i].toLowerCase() in window) return (o.END = names[i]);
	return (o.END = names[0]);
}(window.TransitionEvent || {}));

/**
 * Mediate those wretched vendor prefixes for onTransitionEnd.
 *
 * Older browsers only supported the event with prefixed names (Opera being
 * the worst offender). The function returns whichever name is needed to
 * support transition events in a running browser (prefixed or not).
 *
 * URL: https://developer.mozilla.org/en-US/docs/Web/Events/transitionend
 */
 var transitionEnd = (function(){
	for(var names = "transitionend webkitTransitionEnd oTransitionEnd otransitionend".split(" "), i = 0; i < 4; ++i)
		if("on"+names[i].toLowerCase() in window) return names[i];
	return names[0];
}());

Use a less invasive approach to store TransitionEvent support


import React, { Component } from 'react';
import SetPage from '../components/SetPage';

export default class Pollard extends Component {
  render() {
    return (
      <div className="container">
				{ this.props.children }
      </div>
    );
  }
}

import React, { Component } from 'react';
import { Link } from 'react-router';

import SetPage from '../components/SetPage';

export default class Pollard extends Component {
  render() {
    return (

<Link to="/setlist" activeClassName="active">Setlist</Link>

				{ this.props.children }

    );
  }
}

Add routing link on /


(function() {
  var ReviewMenuCtrl = function($scope, Menu) {
    var reviewMenu = this

    reviewMenu.locate = window.currLocation.coords;

    LocationData = {
      lat: reviewMenu.locate.latitude,
      lng: reviewMenu.locate.longitude
    };
    console.log('000', LocationData)

    Menu.getByLocation(LocationData, null)
      .then(function(data) {
        reviewMenu.menus = data;
      });

    reviewMenu.newSearch = newSearch

    function newSearch(nearbyFilter) {

      var menuFilter = menuFilter || "empty";

      Menu.getByLocation(LocationData, nearbyFilter)
        .then(function(data) {
          reviewMenu.menus = data;
        });
    };
  };

  ReviewMenuCtrl
    .$inject = ['$scope', 'Menu'];
  angular
    .module('app.modules.tabs.review.controllers', [])
    .controller('ReviewMenuCtrl', ReviewMenuCtrl);
})();

(function() {
  var ReviewMenuCtrl = function($scope, Menu, BackgroundGeo) {
    var reviewMenu = this

    reviewMenu.locate = window.currLocation.coords;

    var LocationData = {
      lat: reviewMenu.locate.latitude,
      lng: reviewMenu.locate.longitude,
      dist: 1.0
    };

    Menu.getByLocation(LocationData, null)
      .then(function(data) {
        console.log(data)
        // item.dist = BackgroundGeo.distance(item.lat, item.lon)
        reviewMenu.menus = data;
        _.each(reviewMenu.menus, function(item) {
          item.dist = BackgroundGeo.distance(item.latitude, item.longitude);
          console.log(item.dist);
        })
        console.log('u',reviewMenu.menus);
      });

    reviewMenu.newSearch = newSearch;

    function newSearch(nearbyFilter) {

      var menuFilter = menuFilter || "empty";

      Menu.getByLocation(LocationData, nearbyFilter)
        .then(function(data) {
          reviewMenu.menus = data;
        });
    };
  };

  ReviewMenuCtrl
    .$inject = ['$scope', 'Menu', 'BackgroundGeo'];
  angular
    .module('app.modules.tabs.review.controllers', [])
    .controller('ReviewMenuCtrl', ReviewMenuCtrl);
})();

Configure review controller to handle new menu location return data


Add minimized version of updated script.


module.exports = {
  COLORS: [
    '#7F3C8D',
    '#11A579',
    '#3969AC',
    '#E73F74',
    '#80BA5A',
    '#E68310',
    '#008695',
    '#CF1C90',
    '#f97b72',
    '#A5AA99'
  ],

  /**
   * Returns a color given a letter
   * @param  {String} Letter. eg: 'a', 'b', 'c', etc.
   * @return {String} Hex color code: eg: '#7F3C8D'
   */
  getColorForLetter: function (letter) {
    if (!letter) {
      return this.COLORS[0];
    }

    var letterNumber = letter.charCodeAt(0) - 97;
    var colorIndex = ((letterNumber / this.COLORS.length % 1) * 10).toFixed();
    return this.COLORS[colorIndex] || this.COLORS[0];
  }
};

module.exports = {
  COLORS: [
    '#F24440',
    '#11A579',
    '#3969AC',
    '#E73F74',
    '#80BA5A',
    '#E68310',
    '#008695',
    '#CF1C90',
    '#f97b72',
    '#A5AA99'
  ],

  /**
   * Returns a color given a letter
   * @param  {String} Letter. eg: 'a', 'b', 'c', etc.
   * @return {String} Hex color code: eg: '#7F3C8D'
   */
  getColorForLetter: function (letter) {
    if (!letter) {
      return this.COLORS[0];
    }

    var letterNumber = letter.charCodeAt(0) - 97;
    var colorIndex = ((letterNumber / this.COLORS.length % 1) * 10).toFixed();
    return this.COLORS[colorIndex] || this.COLORS[0];
  }
};

Use color suggested by @xavijam


Application.Controllers.controller('projectsProject',
                                   ["$scope", "$stateParams", "actionStatus", "provStep",
                                    "model.projects", "projectColors", projectsProject]);

function projectsProject ($scope, $stateParams, actionStatus, provStep, projects, projectColors) {
    $scope.isActive = function (tab) {
        return tab === $scope.activeTab;
    };

    actionStatus.addProject($stateParams.id);
    provStep.addProject($stateParams.id);

    projects.get($stateParams.id).then(function(project) {
        $scope.project = project;
        projectColors.setCurrentProjectByID($stateParams.id);
    });
}

Application.Controllers.controller('projectsProject',
                                   ["$scope", "$stateParams", "actionStatus", "provStep",
                                    "model.projects", "projectColors", projectsProject]);

function projectsProject ($scope, $stateParams, actionStatus, provStep, projects, projectColors) {
    $scope.isActive = function (tab) {
        return tab === $scope.activeTab;
    };

    actionStatus.addProject($stateParams.id);
    provStep.addProject($stateParams.id);

    projects.get($stateParams.id).then(function(project) {
        $scope.project = project;
        //console.dir(project);
        projectColors.setCurrentProjectByID($stateParams.id);
    });
}

Comment out console statement that will be needed later.


#! /usr/bin/env node

/**
Command-line interface (CLI) for HackMyResume.
@license MIT. See LICENSE.md for details.
@module index.js
*/

try {

  require('./cli/main')( process.argv );

}
catch( ex ) {

  console.log(ex);
  if(ex.stack) console.log(ex.stack);
  require('./cli/error').err( ex, true );

}

#! /usr/bin/env node

/**
Command-line interface (CLI) for HackMyResume.
@license MIT. See LICENSE.md for details.
@module index.js
*/

try {

  require('./cli/main')( process.argv );

}
catch( ex ) {

  require('./cli/error').err( ex, true );

}

Remove extraneous console.log added by Calhoun.


/**
 * Base module.
 * @module base
 */

import './init-dom'

import './polyfills'

import features from './features'
import utils from './utils'
import eventHub from './eventHub'

export {
  /** Features module. */
  features,
  /** Utility modules. */
  utils,
  /** Global event hub. */
  eventHub
}

/**
 * Base module.
 * @module base
 */
import features from './features'
import utils from './utils'
import eventHub from './eventHub'

export {
  /** Features module. */
  features,
  /** Utility modules. */
  utils,
  /** Global event hub. */
  eventHub
}

Remove side-effects from main bundle


function verifiyKeyword(keywordList, content) {

	for (var i = 0; i < keywordList.length; i++){

		var keyword = Object.keys(keywordList[i])[0];

		var re = new RegExp(keyword, "gi");

		var result = content.match(re);

		if(result){

			var key = result[0];

			var response = keywordList[i][key];

			return response;
		}
	}
}

module.exports = {
	'verifiyKeyword': verifiyKeyword
};

function verifiyKeyword(keywordList, content) {

	for (var i = 0; i < keywordList.length; i++){

		//從keywordList的Array裡提取關鍵字

		var keyword = Object.keys(keywordList[i])[0];

		//透過正規表達式搜尋關鍵字

		var re = new RegExp(keyword, "gi");

		var result = content.match(re);

		//如輸入的內容裡有符合的關鍵字，則作出相應的回應

		if(result){

			var key = result[0];

			var minNumber = 0;

			var maxNumber = keywordList[i][key].length - 1;

			//隨機抽取一個數字，再透過此數字從回應的陣列裡取出對應的回應

			var responseNumber = _getRandomInt(minNumber, maxNumber);

			var response = keywordList[i][key][responseNumber];

			return response;
		}
	}
}

function _getRandomInt(min, max) {

	return Math.floor(Math.random() * (max - min + 1)) + min;

}

module.exports = {
	'verifiyKeyword': verifiyKeyword
};

Add comment and random reply function


"use strict";

(function () {
    angular
        .module("argo")
        .factory("activityService", activityService);

    activityService.$inject = ["$http", "$q", "sessionService"];
    function activityService($http, $q, sessionService) {
        var activities = [],
            service = {
                getActivities: getActivities,
                addActivity: addActivity
            };

        return service;

        function getActivities() {
            var deferred = $q.defer();

            sessionService.isLogged().then(function (credentials) {
                $http.post("/api/transactions", {
                    environment: credentials.environment,
                    token: credentials.token,
                    accountId: credentials.accountId
                }).then(function (transactions) {
                    activities = transactions.data;
                    deferred.resolve(activities);
                });
            });

            return deferred.promise;
        }

        function addActivity(activity) {
            activities.push({
                id: activity.id,
                type: activity.type,
                instrument: activity.instrument,
                units: activity.units,
                price: activity.price,
                pl: activity.pl,
                // PROFIT (PIPS)
                // PROFIT (%)
                accountBalance: activity.accountBalance,
                time: activity.time
            });
        }
    }

}());

"use strict";

(function () {
    angular
        .module("argo")
        .factory("activityService", activityService);

    activityService.$inject = ["$http", "$q", "sessionService"];
    function activityService($http, $q, sessionService) {
        var activities = [],
            service = {
                getActivities: getActivities,
                addActivity: addActivity
            };

        return service;

        function getActivities() {
            var deferred = $q.defer();

            sessionService.isLogged().then(function (credentials) {
                $http.post("/api/transactions", {
                    environment: credentials.environment,
                    token: credentials.token,
                    accountId: credentials.accountId
                }).then(function (transactions) {
                    activities = transactions.data;
                    deferred.resolve(activities);
                });
            });

            return deferred.promise;
        }

        function addActivity(activity) {
            activities.splice(0, 0, {
                id: activity.id,
                type: activity.type,
                instrument: activity.instrument,
                units: activity.units,
                price: activity.price,
                pl: activity.pl,
                // PROFIT (PIPS)
                // PROFIT (%)
                accountBalance: activity.accountBalance,
                time: activity.time
            });
        }
    }

}());

Put new activity at the top of the array.


/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

import Runner from "./Runner";

process.title = "ExpoSE Test Runner";

function getTarget() {
    return process.argv[process.argv.length - 2];
}

function getFn() {
    return process.argv[process.argv.length - 1];
}

function getArgument(name, dResult) {
    for (let i = 0; i < process.argv.length - 1; i++) {
        if (process.argv[i] === name) {
            return process.argv[i+1];
        }
    }

    return dResult;
}

if (process.argv.length >= 3) {
    const target = getTarget();
    const fn = getFn();

    console.log("Test runner searching " + target);

    const concurrent = getArgument("--concurrent", 8);

    console.log("Launching with max concurrent of " + concurrent);

    new Runner(concurrent).done(errors => process.exit(errors)).start(target, fn);
} else {
    console.log("Wrong number of arguments");
    console.log("Usage ./TestRunner --concurrent XX Directory");
}

/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

import Runner from "./Runner";
const os = require('os');

process.title = "ExpoSE Test Runner";

function getTarget() {
    return process.argv[process.argv.length - 2];
}

function getFn() {
    return process.argv[process.argv.length - 1];
}

function getArgument(name, dResult) {
    for (let i = 0; i < process.argv.length - 1; i++) {
        if (process.argv[i] === name) {
            return process.argv[i+1];
        }
    }

    return dResult;
}

if (process.argv.length >= 3) {
    const target = getTarget();
    const fn = getFn();

    console.log("Test runner searching " + target);

    const concurrent = getArgument("--concurrent", os.cpus().length);

    console.log("Launching with max concurrent of " + concurrent);

    new Runner(concurrent).done(errors => process.exit(errors)).start(target, fn);
} else {
    console.log("Wrong number of arguments");
    console.log("Usage ./TestRunner --concurrent XX Directory");
}

Revert to test run with full CPUs


/*

    ___ usage ___ en_US ___
    node highlight.bin.js <options> [sockets directory, sockets directory...]

    options:

        --help                          display help message
        -j, --json          <string>    optional json to feed to template

    ___ $ ___ en_US ___

        select is required:
            the `--select` argument is a required argument

        language is required:
            the `--language` argument is a required argument
    ___ . ___

 */
require('arguable')(module, require('cadence')(function (async, program) {
    var pug = require('pug')

    var delta = require('delta')

    program.helpIf(program.ultimate.help)

    async(function () {
        program.stdin.resume()
        delta(async()).ee(program.stdin).on('data', []).on('end')
    }, function (lines) {
        var f = pug.compile(Buffer.concat(lines).toString('utf8'))
        program.stdout.write(f(JSON.parse(program.ultimate.json || '{}')))
    })
}))

/*

    ___ usage ___ en_US ___
    node highlight.bin.js <options> [sockets directory, sockets directory...]

    options:

        --help                          display help message
        -j, --json          <string>    optional json to feed to template

    ___ $ ___ en_US ___

        select is required:
            the `--select` argument is a required argument

        language is required:
            the `--language` argument is a required argument
    ___ . ___

 */
require('arguable')(module, require('cadence')(function (async, program) {
    var pug = require('pug')

    var delta = require('delta')

    program.helpIf(program.ultimate.help)

    async(function () {
        program.stdin.resume()
        delta(async()).ee(program.stdin).on('data', []).on('end')
    }, function (lines) {
        var f = pug.compile(Buffer.concat(lines).toString('utf8'))
        program.stdout.write(f(JSON.parse(program.ultimate.json || '{}')) + '\n')
    })
}))

Add newline to end of Pug generated HTML.


/* global App */

App.OperatorController = Ember.ObjectController.extend({
  fullType: function() {
    return this.get('package') + '::' + this.get('type');
  }.property('type', 'package'),

  statusLabel: function() {
    var status = this.get('model').get('status');

    if (status === 'none')
      return 'Not initialized';
    else if (status === 'initialized')
      return 'Initialized';
    else if (status === 'active')
      return 'Active';
    else
      return 'Not defined';
  }.property('status'),

  isEditingName: false,

  actions: {
    editName: function() {
      this.set('isEditingName', true);
    },
    saveName: function() {
      this.set('isEditingName', false);
      var model = this.get('model');
      model.save();
    },
    save: function() {
      var model = this.get('model');
      model.save();
    }
  }
});

/* global App */

App.OperatorController = Ember.ObjectController.extend({
  fullType: function() {
    return this.get('package') + '::' + this.get('type');
  }.property('type', 'package'),

  statusLabel: function() {
    var status = this.get('model').get('status');

    if (status === 'none')
      return 'Not initialized';
    else if (status === 'initialized')
      return 'Initialized';
    else if (status === 'active')
      return 'Active';
    else
      return 'Not defined';
  }.property('status'),

  isEditingName: false,

  actions: {
    editName: function() {
      this.set('isEditingName', true);
    },
    saveName: function() {
      this.set('isEditingName', false);
      var model = this.get('model');
      model.save();
    },
    save: function() {
      var model = this.get('model');
      var inputs = model.get('inputs');
      var outputs = model.get('outputs');
      Ember.RSVP.all([inputs, outputs]).then( function(values){
        model.set('inputs', values[0]);
        model.set('outputs', values[1]);
        model.save();
      })
    }
  }
});

Load connectors before saving operator


import PropTypes from 'prop-types';
import React from 'react';

import Icon from '../../Icon/Icon';

import TooltipEntity from '../decorators/TooltipEntity';

const documentIcon = <Icon name="doc-full" />;

const Document = props => {
  const { entityKey, contentState } = props;
  const { url } = contentState.getEntity(entityKey).getData();
  const filename = url.split('/')[3];

  return (
    <TooltipEntity
      {...props}
      icon={documentIcon}
      label={filename}
      url={url}
    />
  );
};

Document.propTypes = {
  entityKey: PropTypes.string.isRequired,
  contentState: PropTypes.object.isRequired,
};

export default Document;

import PropTypes from 'prop-types';
import React from 'react';

import Icon from '../../Icon/Icon';

import TooltipEntity from '../decorators/TooltipEntity';

const documentIcon = <Icon name="doc-full" />;

const getFilename = (path) => {
  const splitPath = path.split('/');

  return splitPath[splitPath.length - 1];
};

const Document = props => {
  const { entityKey, contentState } = props;
  const { url } = contentState.getEntity(entityKey).getData();

  return (
    <TooltipEntity
      {...props}
      icon={documentIcon}
      label={getFilename(url)}
      url={url}
    />
  );
};

Document.propTypes = {
  entityKey: PropTypes.string.isRequired,
  contentState: PropTypes.object.isRequired,
};

export default Document;

Make Draftail document rendering logic sturdier


var util         = require("util")
  , EventEmitter = require("events").EventEmitter

module.exports = (function() {
  var CustomEventEmitter = function(fct) {
    this.fct = fct;
    var self = this;
  }
  util.inherits(CustomEventEmitter, EventEmitter)

  CustomEventEmitter.prototype.run = function() {
    var self = this;

    process.nextTick(function() {
      if (self.fct) {
        self.fct.call(self, self)
      }
    }.bind(this));

    return this;
  }

  CustomEventEmitter.prototype.success =
  CustomEventEmitter.prototype.ok =
  function(fct) {
    this.on('success', fct)
    return this
  }

  CustomEventEmitter.prototype.failure =
  CustomEventEmitter.prototype.fail =
  CustomEventEmitter.prototype.error =
  function(fct) {
    this.on('error', fct)
    return this
  }

  CustomEventEmitter.prototype.done =
  CustomEventEmitter.prototype.complete =
  function(fct) {
    this.on('error', function(err) { fct(err, null) })
        .on('success', function(result) { fct(null, result) })
    return this
  }

  return CustomEventEmitter
})()

var util         = require("util")
  , EventEmitter = require("events").EventEmitter;

module.exports = (function() {
  var CustomEventEmitter = function(fct) {
    this.fct = fct;
    var self = this;
  }
  util.inherits(CustomEventEmitter, EventEmitter);

  CustomEventEmitter.prototype.run = function() {
    var self = this;

    process.nextTick(function() {
      if (self.fct) {
        self.fct.call(self, self)
      }
    }.bind(this));

    return this;
  }

  CustomEventEmitter.prototype.success =
  CustomEventEmitter.prototype.ok =
  function(fct) {
    this.on('success', fct);
    return this;
  }

  CustomEventEmitter.prototype.failure =
  CustomEventEmitter.prototype.fail =
  CustomEventEmitter.prototype.error =
  function(fct) {
    this.on('error', fct);
    return this;
  }

  CustomEventEmitter.prototype.done =
  CustomEventEmitter.prototype.complete =
  function(fct) {
    this.on('error', function(err) { fct(err, null) })
        .on('success', function(result) { fct(null, result) });
    return this;
  }

  return CustomEventEmitter;
})();

Make travis happy & make my need for semicolons happy ;)


#!/usr/bin/env node

const fs = require('fs');
const newConfig = require('./config.json');

const filename = '/code/dist/index.html';
const page = fs.readFileSync(filename, {encoding: 'utf8'});
const rawConfig = /<meta name=".+?\/config\/environment" content="(.+?)" \/>/.exec(page)[1];
const config = JSON.parse(unescape(rawConfig));

// Deep merge, overrides config with newConfig recursively
(function deepMerge(newObj, oldObj) {
    for (const [key, val] of Object.entries(newObj)) {
        if (val && typeof val === 'object' && !Array.isArray(val)) {
            deepMerge(val, oldObj[key]);
        } else {
            oldObj[key] = newObj[key];
        }
    }
})(newConfig, config);

// Stringify and escape the new config
const updatedConfig = escape(JSON.stringify(config));
// Replace the old config on the page with the new config
const updatedPage = page.replace(rawConfig, updatedConfig);

// Write out the file
fs.writeFileSync(filename, updatedPage);

#!/usr/bin/env node

const fs = require('fs');
const newConfig = require('./config.json');

const filename = '/code/dist/index.html';
const page = fs.readFileSync(filename, {encoding: 'utf8'});
const rawConfig = /<meta name=".+?\/config\/environment" content="(.+?)"\W*\/?>/.exec(page)[1];
const config = JSON.parse(unescape(rawConfig));

// Deep merge, overrides config with newConfig recursively
(function deepMerge(newObj, oldObj) {
    for (const [key, val] of Object.entries(newObj)) {
        if (val && typeof val === 'object' && !Array.isArray(val)) {
            deepMerge(val, oldObj[key]);
        } else {
            oldObj[key] = newObj[key];
        }
    }
})(newConfig, config);

// Stringify and escape the new config
const updatedConfig = escape(JSON.stringify(config));
// Replace the old config on the page with the new config
const updatedPage = page.replace(rawConfig, updatedConfig);

// Write out the file
fs.writeFileSync(filename, updatedPage);

Generalize regex for meta tag config replacement


$(document).ready(function() {
    $(document).keyup(function(e) {
        var tag = e.target.tagName.toLowerCase();
        if (tag != 'input' && tag != 'textarea' && tag != 'select' && !e.ctrlKey) {
            if (e.keyCode==78 || e.keyCode==77) {
                $('.nav-menu-icon').trigger('click');
            } else if (e.keyCode==65) {
                $('.search-menu-icon').trigger('click');
            } else if (e.keyCode==73 && e.shiftKey) {
                $( "#new-ip" ).click();
            } else if (e.keyCode==73) {
                $( "#new-indicator" ).click();
            } else if (e.keyCode==69 && e.shiftKey) {
                $( "#new-event" ).click();
            } else if (e.keyCode==69) {
                $( "#new-email-yaml" ).click();
            } else if (e.keyCode==68) {
                $( "#new-domain" ).click();
            } else if (e.keyCode==80) {
                $( "#new-pcap" ).click();
            } else if (e.keyCode==83) {
                $( "#new-sample" ).click();
            } else if (e.keyCode==83) {
                $( "#new-signature" ).click();
            } else if (e.keyCode==27) {
                $( ".mm-opened").trigger('close');
            } else if (e.shiftKey && e.keyCode==191) {
                $( "#shortcut-keys").click();
            }
        }
    });
});

$(document).ready(function() {
    $(document).keyup(function(e) {
        var tag = e.target.tagName.toLowerCase();
        if (tag != 'input' && tag != 'textarea' && tag != 'select' && !e.ctrlKey) {
            if (e.keyCode==78 || e.keyCode==77) {
                $('.nav-menu-icon').trigger('click');
            } else if (e.keyCode==65) {
                $('.search-menu-icon').trigger('click');
            } else if (e.keyCode==73 && e.shiftKey) {
                $( "#new-ip" ).click();
            } else if (e.keyCode==73) {
                $( "#new-indicator" ).click();
            } else if (e.keyCode==69 && e.shiftKey) {
                $( "#new-event" ).click();
            } else if (e.keyCode==69) {
                $( "#new-email-yaml" ).click();
            } else if (e.keyCode==68) {
                $( "#new-domain" ).click();
            } else if (e.keyCode==80) {
                $( "#new-pcap" ).click();
           } else if (e.keyCode==83 && e.shiftKey) {
                $( "#new-signature" ).click();
            } else if (e.keyCode==83) {
                $( "#new-sample" ).click();
            } else if (e.keyCode==27) {
                $( ".mm-opened").trigger('close');
            } else if (e.shiftKey && e.keyCode==191) {
                $( "#shortcut-keys").click();
            }
        }
    });
});

Update key shortcut for new signature


import Route from '@ember/routing/route'
import StaffRouteMixin from 'timed/mixins/staff-route'

export default Route.extend(StaffRouteMixin, {})

import Route from '@ember/routing/route'

export default Route.extend({})

Allow non staff users to see the users page


function Game(){
  this.$track = $('#racetrack');
}

function Player(track){
  this.$track = track;
  this.$player = $('.player');
  this.x = 10;
}

Player.prototype.move = function(){
  $player = this.$player;
  Mousetrap.bind('p', function(){
    // debugger
  $player.css('background-color', 'red');
  });
};

// $(document).ready(function(){

// });

Create js objects for game track and players. Test Mousetrap keyboard-binding functionality


/* app.js */

//= require OpenLayers

/*globals $,OpenLayers,otm*/
/*jslint indent: 4, white: true */

var app = (function ($,L,config) {
    "use strict";
    return {
        createBasemap: function (elmt) {
            var map = new L.Map({
                div: elmt,
                projection: 'EPSG:3857',
                layers: this.getBasemapLayers(config)
            });

            map.setCenter(config.instance.center, 10);

            return map;
        },

        getBasemapLayers: function (config) {
            var layer;
            if (config.instance.basemap.type === 'bing') {
                layer = new L.Layer.Bing({
                    name: 'Road',
                    key: config.instance.basemap.bing_api_key,
                    type: 'Road'
                });
            } else if (config.instance.basemap.type === 'tms') {
                layer = new L.Layer.XYZ(
                    'xyz',
                    config.instance.basemap.data);
            } else {
                layer = new L.Layer.Google(
                    "Google Streets",
                    {numZoomLevels: 20});
            }
            return [layer];
        },

        init: function () {
            app.createBasemap($("#map")[0]);
        }
    };
}($, OpenLayers, otm.settings));

$(app.init);

/* app.js */

//= require OpenLayers

/*globals $,OpenLayers,otm*/
/*jslint indent: 4, white: true */

var app = (function ($,L,config) {
    "use strict";
    return {
        createMap: function (elmt) {
            var map = new L.Map({
                div: elmt,
                projection: 'EPSG:3857',
                layers: this.getBasemapLayers(config)
            });

            map.setCenter(config.instance.center, 10);

            return map;
        },

        getBasemapLayers: function (config) {
            var layer;
            if (config.instance.basemap.type === 'bing') {
                layer = new L.Layer.Bing({
                    name: 'Road',
                    key: config.instance.basemap.bing_api_key,
                    type: 'Road'
                });
            } else if (config.instance.basemap.type === 'tms') {
                layer = new L.Layer.XYZ(
                    'xyz',
                    config.instance.basemap.data);
            } else {
                layer = new L.Layer.Google(
                    "Google Streets",
                    {numZoomLevels: 20});
            }
            return [layer];
        },

        createPlotTileLayer: function(config) {
            return new L.Layer.XYZ(
                'tiles',
                '/tile/' +
                    config.instance.rev +
                    '/database/otm/table/treemap_plot/${z}/${x}/${y}.png',
            { isBaseLayer: false });

        },

        init: function () {
            var map = app.createMap($("#map")[0]);
            map.addLayer(app.createPlotTileLayer(config));
        }
    };
}($, OpenLayers, otm.settings));

$(app.init);

Add XYZ layer tiling code for tiles


function ag() { var __await = {}; return _es6now.asyncGen(__await, function*() {

    (yield (__await.value = x, __await));
    yield y;
    yield (yield (__await.value = foo, __await));
}.apply(this, arguments)); }

function ag() { return _es6now.asyncGen(function*() {

    (yield { _es6now_await: (x) });
    yield y;
    yield (yield { _es6now_await: (foo) });
}.apply(this, arguments)); }

Fix failing async generator function test.


import React from "react"

function CategoryColumn(props) {
  const categoryToEmoticonUnicodeMap = {
    happy: "😊",
    sad: "😥",
    confused: "😕",
  }

  const emoticonUnicode = categoryToEmoticonUnicodeMap[props.category]
  const filteredIdeas = props.ideas.filter(idea => idea.category === props.category)

  return (

        { emoticonUnicode }

@{ props.category }

      <ul className={ `${props.category} ideas ui divided list` }>
        { filteredIdeas.map(idea =>
{idea.body}
) }

  )
}

CategoryColumn.propTypes = {
  ideas: React.PropTypes.array.isRequired,
  category: React.PropTypes.string.isRequired,
}

export default CategoryColumn

import React from "react"

function CategoryColumn(props) {
  const categoryToEmoticonUnicodeMap = {
    happy: "😊",
    sad: "😥",
    confused: "😕",
  }

  const emoticonUnicode = categoryToEmoticonUnicodeMap[props.category]
  const filteredIdeas = props.ideas.filter(idea => idea.category === props.category)

  return (

        { emoticonUnicode }

@{ props.category }

      <ul className={ `${props.category} ideas ui divided list` }>
        { filteredIdeas.map((idea, index) =>
{idea.body}
) }

  )
}

CategoryColumn.propTypes = {
  ideas: React.PropTypes.array.isRequired,
  category: React.PropTypes.string.isRequired,
}

export default CategoryColumn

Use index as unique key prop in category column's list items