/**
 * This file is provided by Facebook for testing and evaluation purposes
 * only. Facebook reserves all rights not expressly granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * @jsx React.DOM
 */

// This file bootstraps the entire application.

var ChatApp = require('./components/ChatApp.react');
var ChatExampleData = require('./ChatExampleData');
var ChatWebAPIUtils = require('./utils/ChatWebAPIUtils');
var React = require('react');

ChatExampleData.init(); // load example data into localstorage

ChatWebAPIUtils.getAllMessages();

React.renderComponent(
    <ChatApp />,
    document.getElementById('react')
);

/**
 * This file is provided by Facebook for testing and evaluation purposes
 * only. Facebook reserves all rights not expressly granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * @jsx React.DOM
 */

// This file bootstraps the entire application.

var ChatApp = require('./components/ChatApp.react');
var ChatExampleData = require('./ChatExampleData');
var ChatWebAPIUtils = require('./utils/ChatWebAPIUtils');
var React = require('react');
window.React = React; // export for http://fb.me/react-devtools

ChatExampleData.init(); // load example data into localstorage

ChatWebAPIUtils.getAllMessages();

React.renderComponent(
    <ChatApp />,
    document.getElementById('react')
);

Enable React devtools by exposing React (setting window.React)


import { connect } from 'react-redux'
import merge from 'lodash/merge'
import clone from 'lodash/clone'
import pickBy from 'lodash/pickBy'
import { encode } from 'querystring'
import TableHeadCell from '../components/TableHeadCell'

const mapStateToProps = (state, ownProps) => {
  const { params, field } = ownProps

  const currentDirection = params.sort_direction
  const isCurrentSortField = (
    params.sort_field == field.field && params.sort_model == field.model
  )

  let linkParams = merge(clone(params), {
    sort_field: field.field, sort_model: field.model
  })
  if (isCurrentSortField) {
    linkParams.sort_direction = currentDirection == 'ASC' ? 'DESC' : 'ASC'
  }
  let href = `/${ownProps.model}?${encode(pickBy(linkParams))}`

  const displayName = field.name.split('_').join(' ')

  return {
    href,
    isCurrentSortField,
    currentDirection,
    displayName,
  }
}

const mapDispatchToProps = (dispatch, ownProps) => ({})

export default connect(mapStateToProps, mapDispatchToProps)(TableHeadCell)

import { connect } from 'react-redux'
import merge from 'lodash/merge'
import clone from 'lodash/clone'
import pickBy from 'lodash/pickBy'
import { encode } from 'querystring'
import TableHeadCell from '../components/TableHeadCell'

const mapStateToProps = (state, ownProps) => {
  const { params, field } = ownProps

  const currentDirection = params.sort_direction
  const isCurrentSortField = (
    params.sort_field == field.field && (field.relation == 'own' || params.sort_model == field.model)
  )

  let linkParams = merge(clone(params), {
    sort_field: field.field, sort_model: (field.relation == 'own' ? null : field.model)
  })
  if (isCurrentSortField) {
    linkParams.sort_direction = currentDirection == 'ASC' ? 'DESC' : 'ASC'
  }
  let href = `/${ownProps.model}?${encode(pickBy(linkParams))}`

  const displayName = field.name.split('_').join(' ')

  return {
    href,
    isCurrentSortField,
    currentDirection,
    displayName,
  }
}

const mapDispatchToProps = (dispatch, ownProps) => ({})

export default connect(mapStateToProps, mapDispatchToProps)(TableHeadCell)

Fix for broken sorting on own fields: remove sort_model from params if the field relation is own


module.exports = {
  user: {
    actions: {
      create: 'User.create', // Use the User plugin's controller.
      update: 'User.update',
      destroy: 'User.destroy',
      deleteall: 'User.destroyAll',
    },
    attributes: {
      username: {
        className: 'col-md-6'
      },
      email: {
        className: 'col-md-6'
      },
      provider: {
        className: 'd-none'
      },
      resetPasswordToken: {
        className: 'd-none'
      },
      role: {
        className: 'd-none'
      }
    }
  }
};

module.exports = {
  user: {
    actions: {
      create: 'User.create', // Use the User plugin's controller.
      update: 'User.update',
      destroy: 'User.destroy',
      deleteall: 'User.destroyAll',
    },
    attributes: {
      username: {
        className: 'col-md-6'
      },
      email: {
        className: 'col-md-6'
      },
      resetPasswordToken: {
        className: 'd-none'
      },
      role: {
        className: 'd-none'
      }
    }
  }
};

Fix to allow provider to be shown in the content manager


'use strict';
var execFile = require('child_process').execFile;

module.exports = function (str, cb) {
	execFile('osascript', ['-e', str], function (err, stdout) {
		if (err) {
			cb(err);
			return;
		}

		cb(err, stdout.trim());
	});
};

'use strict';
var execFile = require('child_process').execFile;

module.exports = function (str, cb) {
	if (process.platform !== 'darwin') {
		throw new Error('Only OS X systems are supported');
	}

	execFile('osascript', ['-e', str], function (err, stdout) {
		if (err) {
			cb(err);
			return;
		}

		cb(err, stdout.trim());
	});
};

Throw error if used on another OS than OS X


"use strict";

var util = require('util');
var minimist = require('minimist');

/**
 * Parse arguments and return command object
 * @param  {array} 	argv Command line arguments
 * @param  {object} opts Argument parsing options and commands
 * @return {object}      Command object
 */
module.exports = function(argv, opts) {
	if (!argv) argv = process.argv.slice(2);

	opts = opts || {};
	opts.commands = opts.commands || {};
	opts.stopEarly = true;

	var global_args = minimist(argv, opts);
	var command = global_args._[0];

	var options = opts.commands[command] || {};
	var callback = options.callback || options.cb;
	if (opts.inheritCommon) {
		options = util._extend(opts, options);
	}

	var args = minimist(global_args._.slice(1), options);

	function execCommand() {
		if (typeof callback === 'function') {
			return callback.apply(null, [args].concat(arguments));
		}
		return false;
	};

	return {
		name: command,
		common: global_args,
		args: args,
		exec: execCommand,
	};
};

"use strict";

var util = require('util');
var minimist = require('minimist');

/**
 * Parse arguments and return command object
 * @param  {array} 	argv Command line arguments
 * @param  {object} opts Argument parsing options and commands
 * @return {object}      Command object
 */
module.exports = function(argv, opts) {
	if (!argv) argv = process.argv.slice(2);

	opts = opts || {};
	opts.commands = opts.commands || {};
	opts.stopEarly = true;

	var global_args = minimist(argv, opts);
	var command = global_args._[0];

	var options = opts.commands[command] || {};
	var callback = options.callback || options.cb;
	if (opts.inheritCommon) {
		options = util._extend(opts, options);
	}

	var args = minimist(global_args._.slice(1), options);

	return {
		name: command,
		common: global_args,
		args: args,
		exec: callback && callback.bind(null, args),
	};
};

Use bind instead of intermediate function


/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-cli-inject-asset-map',

  // Add asset map hash to asset-map controller
  postBuild: function (results) {
    console.log('Injecting asset map hash...');

    var fs       = require('fs'),
        path     = require('path'),
        assetMap = results['graph']['tree']['assetMap'],
        jsPath   = path.join(results.directory, assetMap['assets/art19.js']); // TODO: allow specifying name of js file

    // TODO: I'd love a cleaner way to do this, but I'm not sure sure how since this has to be done after build.
    var js          = fs.readFileSync(jsPath, 'utf-8'),
        assetMapKey = 'assetMapHash',
        hackedJs    = js.replace(new RegExp(assetMapKey + ': undefined'), assetMapKey + ': ' + JSON.stringify(assetMap)),
        hackedCompressed = js.replace(new RegExp(assetMapKey + ':void 0'), assetMapKey + ':' + JSON.stringify(assetMap));

    // Inject in temp
    fs.writeFileSync(jsPath, hackedJs, 'utf-8');

    // Inject in dist (this assumes dist is using JS compression.)
    fs.writeFileSync(path.join('./dist', assetMap['assets/art19.js']), hackedCompressed, 'utf-8');

    console.log('Done! Asset paths are available in all components, controllers, and routes via assetMap.assetMapHash.');
  }
};

/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-cli-inject-asset-map',

  // Add asset map hash to asset-map controller
  postBuild: function (results) {
    var fs          = require('fs'),
        path        = require('path'),
        colors      = require('colors'),
        tree        = results['graph']['tree'],
        assetMap    = tree._inputNodes[0].assetMap,
        jsPath      = path.join(results.directory, assetMap['assets/art19.js']), // TODO: allow specifying name of js file
        js          = fs.readFileSync(jsPath, 'utf-8'),
        assetMapKey = 'assetMapHash',
        expression  = new RegExp(assetMapKey + ':\\s?(void 0|undefined)'),
        injectedJs  = js.replace(expression, assetMapKey + ': ' + JSON.stringify(assetMap));

    console.log('\nInjecting asset map hash...'.rainbow);

    // Write to temp and dist
    fs.writeFileSync(jsPath, injectedJs, 'utf-8');
    fs.writeFileSync(path.join('./dist', assetMap['assets/art19.js']), injectedJs, 'utf-8');

    console.log('Done! Asset paths are available in all components, controllers, and routes via assetMap.assetMapHash.'.rainbow);
  }
};

Update to work with new versions of ember-cli


"use strict";

var Mail = require('./channels/Mail');
var Console = require('./channels/Console');

class SiteDownNotification {

	constructor(site)
	{
		this.site = site;

		this.message = site.getAttribute('url') + ' is down!';
	}

	toMail()
	{
		return new Mail().setBody(this.message);
	}

	toConsole()
	{
		return new Console().setBody(this.message);
	}

	via()
	{
		return ['mail', 'console'];
	}

}

module.exports = SiteDownNotification;

"use strict";

var Mail = require('./channels/Mail');
var Console = require('./channels/Console');

class SiteDownNotification {

	constructor(site)
	{
		this.site = site;

		this.message = site.getAttribute('url') + ' is down!';
	}

	toMail()
	{
		return new Mail().setBody(this.message);
	}

	toConsole()
	{
		return new Console().setBody(this.message);
	}

	via()
	{
		return (this.site.notifications) ? this.site.notifications : ['console'];
	}

}

module.exports = SiteDownNotification;

Send notification based on the sites settings


#!/usr/bin/env node

var cli     = require('cli').enable('version');
var fs      = require('fs');
var path    = require('path');
var cwd     = process.cwd();
var options = cli.parse({
  'append':            ['a', 'append to the given FILEs, do not overwrite'],
  'ignore-interrupts': ['i', 'ignore interrupt signals'],
  'suppress':          ['s', 'do NOT output to stdout']
});
var fsWriteFunc = options.append ? 'appendFile' : 'writeFile';

function writeToFiles (data, files) {
  if (!files.length) {
    return output(data);
  }

  fs[fsWriteFunc](path.resolve(cwd, files.shift()), data, function (err) {
    if (err) throw err;
    writeToFiles(data, files);
  });

}

function output (data) {
  if (!options.suppress) {
    cli.output(data);
  }
}

function interceptInt () {
  if (!options['ignore-interrupts']) {
    process.exit();
  }
}

process.on('SIGINT', interceptInt);

cli.withStdin(function (stdin) {
  writeToFiles(stdin, cli.args);
});

#!/usr/bin/env node

var cli     = require('cli').enable('version').setApp('./package.json');
var fs      = require('fs');
var path    = require('path');
var cwd     = process.cwd();
var options = cli.parse({
  'append':            ['a', 'append to the given FILEs, do not overwrite'],
  'ignore-interrupts': ['i', 'ignore interrupt signals'],
  'suppress':          ['s', 'do NOT output to stdout']
});
var fsWriteFunc = options.append ? 'appendFile' : 'writeFile';

function writeToFiles (data, files) {
  if (!files.length) {
    return output(data);
  }

  fs[fsWriteFunc](path.resolve(cwd, files.shift()), data, function (err) {
    if (err) throw err;
    writeToFiles(data, files);
  });

}

function output (data) {
  if (!options.suppress) {
    cli.output(data);
  }
}

function interceptInt () {
  if (!options['ignore-interrupts']) {
    process.exit();
  }
}

process.on('SIGINT', interceptInt);

cli.withStdin(function (stdin) {
  writeToFiles(stdin, cli.args);
});

Fix ntee -h/--help not showing right name and version and showing cli's ones instead


module.exports = Storage

function Storage () {
  if (!(this instanceof Storage)) return new Storage()
  this.chunks = []
}

Storage.prototype.put = function (index, buf, cb) {
  this.chunks[index] = buf
  if (cb) process.nextTick(cb)
}

function nextTick (cb, err, val) {
  process.nextTick(function () {
    cb(err, val)
  })
}

Storage.prototype.get = function (index, opts, cb) {
  if (typeof opts === 'function') return this.get(index, null, opts)
  var buf = this.chunks[index]
  if (!buf) return nextTick(cb, new Error('Chunk not found'))
  if (!opts) return nextTick(cb, null, buf)
  var offset = opts.offset || 0
  var len = opts.length || (buf.length - offset)
  nextTick(cb, null, buf.slice(offset, len + offset))
}

module.exports = Storage

function Storage (chunkLength) {
  if (!(this instanceof Storage)) return new Storage()
  this.chunks = []
  this.chunkLength = Number(chunkLength)
  this.closed = false
  if (!this.chunkLength) throw new Error('First argument must be a chunk length')
}

Storage.prototype.put = function (index, buf, cb) {
  if (this.closed) return nextTick(cb, new Error('Storage is closed'))
  if (buf.length !== this.chunkLength) {
    return nextTick(cb, new Error('Chunk length must be ' + this.chunkLength))
  }
  this.chunks[index] = buf
  if (cb) process.nextTick(cb)
}

Storage.prototype.get = function (index, opts, cb) {
  if (typeof opts === 'function') return this.get(index, null, opts)
  if (this.closed) return nextTick(cb, new Error('Storage is closed'))
  var buf = this.chunks[index]
  if (!buf) return nextTick(cb, new Error('Chunk not found'))
  if (!opts) return nextTick(cb, null, buf)
  var offset = opts.offset || 0
  var len = opts.length || (buf.length - offset)
  nextTick(cb, null, buf.slice(offset, len + offset))
}

Storage.prototype.close = Storage.prototype.destroy = function (cb) {
  if (this.closed) return nextTick(cb, new Error('Storage is closed'))
  this.closed = true
  this.chunks = null
  nextTick(cb, null)
}

function nextTick (cb, err, val) {
  process.nextTick(function () {
    if (cb) cb(err, val)
  })
}

Add close and destroy; force fixed chunk length


'use strict';

var consecutiveSlash = /(:)?\/+/g;
var endsWithExtension = /[^\/]*\.[^\/]+$/g;

var fn = function(match, c) {
  return c ? '://' : '/';
};

var pppath = function(parts, filename) {
  if (typeof parts === 'string') {
    parts = [parts];
  }
  if (filename && !endsWithExtension.test(parts[parts.length-1])) {
    parts.push(filename);
  }
  return parts.join('/').replace(consecutiveSlash, fn);
};

module.exports = exports = pppath;

'use strict';

var consecutiveSlash = /(:)?\/+/g;
var endsWithExtension = /[^\/]*\.[^\/]+$/g;

var fn = function(match, c) {
  return c ? '://' : '/';
};

var pppath = function(parts, filename) {
  if (typeof parts === 'string') {
    parts = [parts];
  }
  if (filename && parts[parts.length-1].search(endsWithExtension) === -1) {
    parts.push(filename);
  }
  return parts.join('/').replace(consecutiveSlash, fn);
};

module.exports = exports = pppath;

Use `String.search` instead of `RegExp.test`


var generatePairs = function(string) {
  var pairs = [];
  string = string.toLowerCase();
  for (var i = 0; i < string.length - 1; i++) {
    pair = string.substr(i, 2);
    if (!/\s/.test(pair)) {
      pairs.push(pair);
    }
  }
  return pairs;
}

var whiteSimilarity = function(string1, string2) {
  string1 = string1.toUpperCase()
    .replace(/[^A-Z]+/g, '');
  string2 = string1.toUpperCase()
    .replace(/[^A-Z]+/g, '');

  var pairs1 = generatePairs(string1);
  var pairs2 = generatePairs(string2);
  var union = pairs1.length + pairs2.length;
  var hitCount = 0;
  for (x in pairs1) {
    for (y in pairs2) {
      if (pairs1[x] == pairs2[y]) {
        hitCount++;
      }
    }
  }
  score = ((2.0 * hitCount) / union).toFixed(2);
  return score;
}

module.exports = whiteSimilarity;

var generatePairs = function(string) {
  superPairs = string.toUpperCase()
    .replace(/[^A-Z ]+/g, '')
    .split(/\s+/);

  superPairs = superPairs
    .map(function(word) {
      breaks = [];
      for (var i = 0; i < word.length - 1; i++) {
        breaks.push(word.slice(i, i + 2));
      }
      return breaks;
    });
  pairs = [].concat.apply([], superPairs);
  return pairs;
}

var whiteSimilarity = function(string1, string2) {
  var pairs1 = generatePairs(string1);
  var pairs2 = generatePairs(string2);
  var union = pairs1.length + pairs2.length;
  var hitCount = 0;
  for (x in pairs1) {
    for (y in pairs2) {
      if (pairs1[x] == pairs2[y]) {
        hitCount++;
        pairs2[y] = '';
      }
    }
  }
  score = ((2.0 * hitCount) / union).toFixed(2);
  return score;
}

module.exports = whiteSimilarity;

Make pair generation extensible to multiple words


module.exports = function (paths, ignores) {
  let result = []
  let edge = String.prototype

  for (let i = 0, ignoresLength = ignores.length; i < ignoresLength; i++) {
    let ignore = ignores[i]

    if (ignore.lastIndexOf('.') > ignore.lastIndexOf('/')) {
      edge = edge.endsWith
    } else {
      edge = edge.startsWith
    }

    for (let j = 0, pathsLength = paths.length; j < pathsLength; j++) {
      let path = paths[j]

      if (!edge.call(path, ignore)) {
        result[result.length] = path
      }
    }
  }

  return result
}

function startsWith (value, start) {
  return value.slice(0, start.length) === start
}

function endsWith (value, end) {
  return value.slice(value.length - end.length) === end
}

module.exports = function (paths, ignores) {
  let result = []
  let edge

  for (let i = 0, ignoresLength = ignores.length; i < ignoresLength; i++) {
    let ignore = ignores[i]

    if (ignore.lastIndexOf('.') > ignore.lastIndexOf('/')) {
      edge = endsWith
    } else {
      edge = startsWith
    }

    for (let j = 0, pathsLength = paths.length; j < pathsLength; j++) {
      let path = paths[j]

      if (!edge(path, ignore)) {
        result[result.length] = path
      }
    }
  }

  return result
}

Use startsWith and endsWith functions


import {TemplateDirective, View, ViewPort, ViewFactory, InitAttrs} from 'templating';
import {Injector, Inject} from 'di';

@TemplateDirective({selector: 'router-view-port'})
export class RouterViewPort {
  @Inject(ViewFactory, ViewPort, 'executionContext', Injector, InitAttrs)
  constructor(viewFactory, viewPort, executionContext, attrs) {
    this.viewFactory = viewFactory;
    this.viewPort = viewPort;
    this.executionContext = executionContext;
    this.view = null;

    if ('router' in this.executionContext) {
      this.executionContext.router.registerViewPort(this, attrs.name);
    }
  }

  createComponentView(directive, providers){
    return this.viewFactory.createComponentView({
      component: directive,
      providers: providers,
      viewPort: this.viewPort
    });
  }

  process(viewPortInstruction) {
    this.tryRemoveView();
    this.view = viewPortInstruction.component;
    this.viewPort.append(this.view);
  }

  tryRemoveView() {
    if (this.view) {
      this.view.remove();
      this.view = null;
    }
  }
}

import {TemplateDirective, View, ViewPort, ViewFactory, InitAttrs} from 'templating';
import {Injector, Inject} from 'di';

@TemplateDirective({selector: 'router-view-port'})
export class RouterViewPort {
  @Inject(ViewFactory, ViewPort, 'executionContext', Injector, InitAttrs)
  constructor(viewFactory, viewPort, executionContext, attrs) {
    this.viewFactory = viewFactory;
    this.viewPort = viewPort;
    this.executionContext = executionContext;
    this.view = null;

    if ('router' in this.executionContext) {
      this.executionContext.router.registerViewPort(this, attrs.name);
    }
  }

  createComponentView(directive, providers){
    return this.viewFactory.createComponentView({
      component: directive,
      providers: providers,
      viewPort: this.viewPort
    });
  }

  process(viewPortInstruction) {
    this.tryRemoveView();
    this.view = viewPortInstruction.component;
    this.view.appendTo(this.viewPort);
  }

  tryRemoveView() {
    if (this.view) {
      this.view.remove();
      this.view = null;
    }
  }
}

Update the newest templating API


var path = require('path'),
    servestatic = require('serve-static');

var basedir = path.dirname(require.resolve('govuk_template_mustache/package.json'));

module.exports = {
    setup: function (app, options) {

        options = options || {};
        options.path = options.path || '/govuk-assets';

        app.use(options.path, servestatic(path.join(basedir, './assets'), options));
        app.use(function (req, res, next) {
            res.locals.govukAssetPath = options.path + '/';
            res.locals.partials = res.locals.partials || {};
            res.locals.partials['govuk-template'] = path.resolve(__dirname, './govuk_template');
            next();
        });

    }
};

var path = require('path'),
    servestatic = require('serve-static');

var basedir = path.dirname(require.resolve('govuk_template_mustache/package.json'));

module.exports = {
    setup: function (app, options) {

        options = options || {};
        options.path = options.path || '/govuk-assets';

        app.use(options.path, servestatic(path.join(basedir, './assets'), options));
        app.use(function (req, res, next) {
            res.locals.govukAssetPath = req.baseUrl + options.path + '/';
            res.locals.partials = res.locals.partials || {};
            res.locals.partials['govuk-template'] = path.resolve(__dirname, './govuk_template');
            next();
        });

    }
};

Include req.baseUrl is asset path


/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-power-select'
};

/* jshint node: true */
'use strict';

module.exports = {
  name: 'ember-power-select',
  contentFor: function(type /*, config */) {
    if (type === 'body-footer') {
      return `<div id="ember-power-select-wormhole"></div>`
    }
  }
};

Add the wormhole destination in the {{content-for “body-footer”}}


'use strict';

/*
 * Dependencies..
 */

var Ware;

Ware = require('ware');

/*
 * Components.
 */

var parse,
    stringify;

parse = require('./lib/parse.js');
stringify = require('./lib/stringify.js');

/**
 * Construct an MDAST instance.
 *
 * @constructor {MDAST}
 */
function MDAST() {
    this.parser = new Ware();
}

/**
 * Parse a value and apply plugins.
 *
 * @return {Root}
 */
function runParse(_, options) {
    var node;

    node = parse.apply(parse, arguments);

    this.parser.run(node, options);

    return node;
}

/**
 * Construct an MDAST instance and use a plugin.
 *
 * @return {MDAST}
 */
function use(plugin) {
    var self;

    self = this;

    if (!(self instanceof MDAST)) {
        self = new MDAST();
    }

    self.parser.use(plugin);

    return self;
}

/*
 * Prototype.
 */

MDAST.prototype.parse = runParse;
MDAST.prototype.stringify = stringify;
MDAST.prototype.use = use;

/*
 * Expose `mdast`.
 */

module.exports = {
    'parse': parse,
    'stringify': stringify,
    'use': use
};

'use strict';

/*
 * Dependencies..
 */

var Ware;

Ware = require('ware');

/*
 * Components.
 */

var parse,
    stringify;

parse = require('./lib/parse.js');
stringify = require('./lib/stringify.js');

/**
 * Construct an MDAST instance.
 *
 * @constructor {MDAST}
 */
function MDAST() {
    this.ware = new Ware();
}

/**
 * Parse a value and apply plugins.
 *
 * @return {Root}
 */
function runParse(_, options) {
    var node;

    node = parse.apply(parse, arguments);

    this.ware.run(node, options);

    return node;
}

/**
 * Construct an MDAST instance and use a plugin.
 *
 * @return {MDAST}
 */
function use(plugin) {
    var self;

    self = this;

    if (!(self instanceof MDAST)) {
        self = new MDAST();
    }

    self.ware.use(plugin);

    return self;
}

/*
 * Prototype.
 */

MDAST.prototype.parse = runParse;
MDAST.prototype.stringify = stringify;
MDAST.prototype.use = use;

/*
 * Expose `mdast`.
 */

module.exports = {
    'parse': parse,
    'stringify': stringify,
    'use': use
};

Rename `ware` internally from `parser` to `ware`


'use strict';
var cheerio = require('cheerio');
var _ = require('underscore');
var multiline = require('multiline');

var template = _.template(multiline(function() {
  /*
     <a href="<%= url %>" title="<%= title %>" class="fancybox">
       <img src="<%= url %>" alt="<%= title %>">

   */
}));

module.exports = {
  book: {
    assets: './assets',
    js: [
      'jquery.min.js',
      'jquery.fancybox.pack.js',
      'jquery.fancybox-buttons.js',
      'plugin.js'
    ],
    css: [
      'jquery.fancybox.css',
      'jquery.fancybox-buttons.css'
    ]
  },
  hooks: {
    page: function(page) {
      var $ = cheerio.load(page.content);

      $('img').each(function(index, img) {
        var $img = $(img);
        $img.replaceWith(template({
          url: $img.attr('src'),
          title: $img.attr('alt')
        }));
      });

      page.content = $.html();

      return page;
    }
  }
};

'use strict';
var cheerio = require('cheerio');
var _ = require('underscore');
var multiline = require('multiline');

var template = _.template(multiline(function() {
  /*
     <a href="<%= url %>" title="<%= title %>" target="_self" class="fancybox">
       <img src="<%= url %>" alt="<%= title %>">

   */
}));

module.exports = {
  book: {
    assets: './assets',
    js: [
      'jquery.min.js',
      'jquery.fancybox.pack.js',
      'jquery.fancybox-buttons.js',
      'plugin.js'
    ],
    css: [
      'jquery.fancybox.css',
      'jquery.fancybox-buttons.css'
    ]
  },
  hooks: {
    page: function(page) {
      var $ = cheerio.load(page.content);

      $('img').each(function(index, img) {
        var $img = $(img);
        $img.replaceWith(template({
          url: $img.attr('src'),
          title: $img.attr('alt')
        }));
      });

      page.content = $.html();

      return page;
    }
  }
};

Add target attribute to a.fancybox to prevent default theme's links following


'use strict';

const got = require('got');

const awaitUrl = (url, option) => {
    const config = Object.assign({}, option, {
        interval : 1000,
        tries    : 60
    });

    return new Promise((resolve, reject) => {
        const attempt = async (tries) => {
            const res = await got(url, {
                followRedirect : false,
                timeout        : 5000
            });
            if (res.statusCode === 200) {
                resolve();
            }
            else if (Math.max(1, tries) > 1) {
                setTimeout(attempt, config.interval, tries - 1);
            }
            else {
                reject(new RangeError(`Expected 200 response but got ${res.statusCode}`));
            }
        };
        attempt(config.tries).catch(reject);
    });
};

module.exports = awaitUrl;

'use strict';

const got = require('got');

const awaitUrl = (url, option) => {
    const config = Object.assign({}, option, {
        interval : 1000,
        tries    : 60
    });

    return new Promise((resolve, reject) => {
        const attempt = async (tries) => {
            const res = await got(url, {
                followRedirect : false,
                timeout        : {
                    connect : 10000,
                    socket  : 10000,
                    request : 10000
                }
            });
            if (res.statusCode === 200) {
                resolve();
            }
            else if (Math.max(1, tries) > 1) {
                setTimeout(attempt, config.interval, tries - 1);
            }
            else {
                reject(new RangeError(`Expected 200 response but got ${res.statusCode}`));
            }
        };
        attempt(config.tries).catch(reject);
    });
};

module.exports = awaitUrl;

Increase timeouts for very slow servers


var es6tr = require("es6-transpiler");

var createES6TranspilerPreprocessor = function(args, config, logger, helper) {
  config = config || {};
  var log = logger.create('preprocessor.es6-transpiler');
  var defaultOptions = {
  };
  var options = helper.merge(defaultOptions, args.options || {}, config.options || {});

  var transformPath = args.transformPath || config.transformPath || function(filepath) {
    return filepath.replace(/\.es6.js$/, '.js').replace(/\.es6$/, '.js');
  };

  return function(content, file, done) {
    log.info('Processing "%s".', file.originalPath);
    file.path = transformPath(file.originalPath);
    options.filename = file.originalPath;

    var result = es6tr.run({
      filename: options.filename
    });
    var transpiledContent = result.src;

    result.errors.forEach(function(err) {
      log.error(err);
    });

    if (result.errors.length) {
      return done(new Error('ES6-TRANSPILER COMPILE ERRORS\n' + result.errors.join('\n')));
    }

    // TODO: add sourceMap to transpiledContent

    return done(null, transpiledContent);
  };
};

createES6TranspilerPreprocessor.$inject = ['args', 'config.es6TranspilerPreprocessor', 'logger', 'helper'];

// export es6-transpiler preprocessor
module.exports = {
  'preprocessor:es6-transpiler': ['factory', createES6TranspilerPreprocessor]
};

var es6tr = require("es6-transpiler");

var createES6TranspilerPreprocessor = function(args, config, logger, helper) {
  config = config || {};
  var log = logger.create('preprocessor.es6-transpiler');
  var defaultOptions = {
  };
  var options = helper.merge(defaultOptions, args.options || {}, config.options || {});

  var transformPath = args.transformPath || config.transformPath || function(filepath) {
    return filepath.replace(/\.es6.js$/, '.js').replace(/\.es6$/, '.js');
  };

  return function(content, file, done) {
    log.info('Processing "%s".', file.originalPath);
    file.path = transformPath(file.originalPath);
    options.filename = file.originalPath;

    var result = es6tr.run(options);
    var transpiledContent = result.src;

    result.errors.forEach(function(err) {
      log.error(err);
    });

    if (result.errors.length) {
      return done(new Error('ES6-TRANSPILER COMPILE ERRORS\n' + result.errors.join('\n')));
    }

    // TODO: add sourceMap to transpiledContent

    return done(null, transpiledContent);
  };
};

createES6TranspilerPreprocessor.$inject = ['args', 'config.es6TranspilerPreprocessor', 'logger', 'helper'];

// export es6-transpiler preprocessor
module.exports = {
  'preprocessor:es6-transpiler': ['factory', createES6TranspilerPreprocessor]
};

Fix options passed to es6-transpiler


'use strict';

var EventEmitter = require('events').EventEmitter;
var Promise      = require('bluebird');

var emitThen = function (event) {
  var args = Array.prototype.slice.call(arguments, 1);
  return Promise
    .bind(this)
    .return(this)
    .call('listeners', event)
    .map(function (listener) {
      var a1 = args[0], a2 = args[1];
      switch (args.length) {
        case 0: return listener.call(this);
        case 1: return listener.call(this, a1)
        case 2: return listener.call(this, a1, a2);
        default: return listener.apply(this, args);
      }
    })
    .return(null);
};

emitThen.register = function () {
  EventEmitter.prototype.emitThen = emitThen;
};

module.exports = emitThen;

'use strict';

var EventEmitter = require('events').EventEmitter;
var Promise      = require('bluebird');

function emitThen (event) {
  var args = Array.prototype.slice.call(arguments, 1);
  /* jshint validthis:true */
  return Promise
    .bind(this)
    .return(this)
    .call('listeners', event)
    .map(function (listener) {
      var a1 = args[0], a2 = args[1];
      switch (args.length) {
        case 0: return listener.call(this);
        case 1: return listener.call(this, a1)
        case 2: return listener.call(this, a1, a2);
        default: return listener.apply(this, args);
      }
    })
    .return(null);
}

emitThen.register = function () {
  EventEmitter.prototype.emitThen = emitThen;
};

module.exports = emitThen;

Use a named function instead of anon


var httpProxy = require('http-proxy');
var http = require('http');

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

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

var httpProxy = require('http-proxy');
var http = require('http');

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

var proxy = httpProxy.createProxyServer();
// Add CORS headers to every other request also.
proxy.on('proxyRes', function(proxyRes, req, res) {
  for (var key in CORS_HEADERS) {
    proxyRes.headers[key] = CORS_HEADERS[key];
  }
});
proxy.on('error', function(err, req, res) {
  console.log(err);
  var json = { error: 'proxy_error', reason: err.message };
  if (!res.headersSent) {
    res.writeHead(500, {'content-type': 'application/json'});
  }
  res.end(JSON.stringify(json));
});
http.createServer(function(req, res) {
  if (req.method === 'OPTIONS') {
    // Respond to OPTIONS requests advertising we support full CORS for *
    res.writeHead(200, CORS_HEADERS);
    res.end();
    return
  }
  // Remove our original host so it doesn't mess up Google's header parsing.
  delete req.headers.host;
  proxy.web(req, res, {
    target: 'https://spreadsheets.google.com:443',
    xfwd: false
  });
}).listen(process.env.PORT || 5000);

Move proxyRes out of request handler; trap errors


'use strict';
var execFile = require('child_process').execFile;
var wifiName = require('wifi-name');

function getPassword(ssid, cb) {
	var cmd = 'sudo';
	var args = ['cat', '/etc/NetworkManager/system-connections/' + ssid];
	var ret;

	execFile(cmd, args, function (err, stdout) {
		if (err) {
			cb(err);
			return;
		}

		ret = /^\s*psk=(.+)\s*$/gm.exec(stdout);
		ret = ret && ret.length ? ret[1] : null;

		if (!ret) {
			cb(new Error('Could not get password'));
			return;
		}

		cb(null, ret);
	});
}

module.exports = function (ssid, cb) {
	if (process.platform !== 'linux') {
		throw new Error('Only Linux systems are supported');
	}

	if (ssid && typeof ssid !== 'function') {
		getPassword(ssid, cb);
		return;
	} else if (ssid && !cb) {
		cb = ssid;
	}

	wifiName(function (err, name) {
		if (err) {
			cb(err);
			return;
		}

		getPassword(name, cb);
	});
};

'use strict';
var execFile = require('child_process').execFile;
var wifiName = require('wifi-name');

function getPassword(ssid, cb) {
	var cmd = 'sudo';
	var args = ['cat', '/etc/NetworkManager/system-connections/' + ssid];
	var ret;

	execFile(cmd, args, function (err, stdout) {
		if (err) {
			cb(err);
			return;
		}

		ret = /^\s*(?:psk|password)=(.+)\s*$/gm.exec(stdout);
		ret = ret && ret.length ? ret[1] : null;

		if (!ret) {
			cb(new Error('Could not get password'));
			return;
		}

		cb(null, ret);
	});
}

module.exports = function (ssid, cb) {
	if (process.platform !== 'linux') {
		throw new Error('Only Linux systems are supported');
	}

	if (ssid && typeof ssid !== 'function') {
		getPassword(ssid, cb);
		return;
	} else if (ssid && !cb) {
		cb = ssid;
	}

	wifiName(function (err, name) {
		if (err) {
			cb(err);
			return;
		}

		getPassword(name, cb);
	});
};

Add support for WPA2 Enterprise


'use strict';

const EventEmitter = require('events');

const devtools = require('./lib/devtools.js');
const Chrome = require('./lib/chrome.js');

function CDP(options, callback) {
    if (typeof options === 'function') {
        callback = options;
        options = undefined;
    }
    const notifier = new EventEmitter();
    if (typeof callback === 'function') {
        // allow to register the error callback later
        process.nextTick(() => {
            new Chrome(options, notifier);
        });
        return notifier.once('connect', callback);
    } else {
        return new Promise((fulfill, reject) => {
            notifier.once('connect', fulfill);
            notifier.once('error', reject);
            new Chrome(options, notifier);
        });
    }
}

module.exports = CDP;
module.exports.Protocol = devtools.Protocol;
module.exports.List = devtools.List;
module.exports.New = devtools.New;
module.exports.Activate = devtools.Activate;
module.exports.Close = devtools.Close;
module.exports.Version = devtools.Version;

'use strict';

const EventEmitter = require('events');
const dns = require('dns');

const devtools = require('./lib/devtools.js');
const Chrome = require('./lib/chrome.js');

// XXX reset the default that has been changed in
// (https://github.com/nodejs/node/pull/39987) to prefer IPv4. since
// implementations alway bind on 127.0.0.1 this solution should be fairly safe
// (see #467)
dns.setDefaultResultOrder('ipv4first');

function CDP(options, callback) {
    if (typeof options === 'function') {
        callback = options;
        options = undefined;
    }
    const notifier = new EventEmitter();
    if (typeof callback === 'function') {
        // allow to register the error callback later
        process.nextTick(() => {
            new Chrome(options, notifier);
        });
        return notifier.once('connect', callback);
    } else {
        return new Promise((fulfill, reject) => {
            notifier.once('connect', fulfill);
            notifier.once('error', reject);
            new Chrome(options, notifier);
        });
    }
}

module.exports = CDP;
module.exports.Protocol = devtools.Protocol;
module.exports.List = devtools.List;
module.exports.New = devtools.New;
module.exports.Activate = devtools.Activate;
module.exports.Close = devtools.Close;
module.exports.Version = devtools.Version;

Revert the default DNS lookup order to IPv4-first


'use strict'

var postcss = require('postcss')
var isVendorPrefixed = require('is-vendor-prefixed')

module.exports = postcss.plugin('postcss-remove-prefixes', function (options) {
  if (!options) {
    options = {};
  }

  var ignore = options.ignore ? Array.isArray(options.ignore) ? options.ignore : false : [];

  if (ignore === false) {
    throw TypeError("options.ignore must be an array")
  }

  for (var i = 0; i < ignore.length; ++i) {
    var value = ignore[i];

    if (typeof value === "string") {
      value = new RegExp(value + "$", "i")
    } else if (value instanceof RegExp) {

    } else {
      throw TypeError("options.ignore values can either be a string or a regular expression")
    }

    ignore[i] = value;
  }

  return function removePrefixes(root, result) {
    root.walkDecls(function (declaration) {
      if (isVendorPrefixed(declaration.prop) || isVendorPrefixed(declaration.value)) {
        var isIgnored = false;

        for (var i = 0; i < ignore.length; ++i) {
          var value = ignore[i];

          if (value.test(declaration.prop)) {
            isIgnored = true;
            break;
          }
        }

        if (!isIgnored) {
          declaration.remove()
        }
      }
    })
  }
})

'use strict'

var postcss = require('postcss')
var isVendorPrefixed = require('is-vendor-prefixed')

module.exports = postcss.plugin('postcss-remove-prefixes', function (options) {
  if (!options) {
    options = {
      ignore: []
    }
  }

  if (!Array.isArray(options.ignore)) {
    throw TypeError("options.ignore must be an array")
  }

  var ignore = options.ignore.map(function (value) {
    if (typeof value === 'string') {
      return new RegExp(value + '$', 'i')
    } else if (value instanceof RegExp) {
      return value
    } else {
      throw TypeError('options.ignore values can either be a string or a regular expression')
    }
  })

  return function removePrefixes(root, result) {
    root.walkDecls(function (declaration) {
      if (isVendorPrefixed(declaration.prop) || isVendorPrefixed(declaration.value)) {
        var isIgnored = false;

        for (var i = 0; i < ignore.length; ++i) {
          var value = ignore[i];

          if (value.test(declaration.prop)) {
            isIgnored = true;
            break;
          }
        }

        if (!isIgnored) {
          declaration.remove()
        }
      }
    })
  }
})

Change code as per @johnotander's suggestion


/* jshint node: true */
'use strict';

var path = require('path');
var filterInitializers = require('fastboot-filter-initializers');
var VersionChecker = require('ember-cli-version-checker');
var mergeTrees = require('broccoli-merge-trees');

module.exports = {
  name: 'ember-cli-head',

  treeForApp: function(defaultTree) {
    var checker = new VersionChecker(this);
    var emberVersion = checker.for('ember', 'bower');

    var trees = [defaultTree];

    // 2.9.0-beta.1 - 2.9.0-beta.5 used glimmer2 (but 2.9.0 did not)
    // 2.10.0-beta.1+ includes glimmer2
    if (!(emberVersion.gt('2.9.0-beta') && emberVersion.lt('2.9.0')) && !emberVersion.gt('2.10.0-beta')) {
      trees.push(this.treeGenerator(path.resolve(this.root, 'app-lt-2-10')));
    }

    var tree = mergeTrees(trees, { overwrite: true });

    return filterInitializers(tree);
  }
};

/* jshint node: true */
'use strict';

var path = require('path');
var filterInitializers = require('fastboot-filter-initializers');
var VersionChecker = require('ember-cli-version-checker');
var mergeTrees = require('broccoli-merge-trees');

module.exports = {
  name: 'ember-cli-head',

  treeForApp: function(defaultTree) {
    var checker = new VersionChecker(this);
    var emberVersion = checker.for('ember-source', 'npm');

    if (!emberVersion.version) {
      emberVersion = checker.for('ember', 'bower');
    }

    var trees = [defaultTree];

    // 2.9.0-beta.1 - 2.9.0-beta.5 used glimmer2 (but 2.9.0 did not)
    // 2.10.0-beta.1+ includes glimmer2
    if (!(emberVersion.gt('2.9.0-beta') && emberVersion.lt('2.9.0')) && !emberVersion.gt('2.10.0-beta')) {
      trees.push(this.treeGenerator(path.resolve(this.root, 'app-lt-2-10')));
    }

    var tree = mergeTrees(trees, { overwrite: true });

    return filterInitializers(tree);
  }
};

Check ember-source version from NPM, if not found use ember from bower


module.exports = function (path) {
  var req = require;
  return function (module_name) {
    try {
      return req(module_name);
    } catch (err) {
      var resolve = null;
      req.main.paths.some(function (item) {
        if (resolve) return true;
        item = item.replace('node_modules', path);
        try {
          var main = req(item + '/' + module_name + '/package.json').main;
          main = item + '/' + module_name + '/' + main;
          req(main);
          resolve = main;
        } catch (e) {} // do nothing
      });
      if (!resolve) throw err;
      return req(resolve)
    }
  };
};

var path = require('path');
module.exports = function (pathname) {
  var req = require;
  return function (module_name) {
    try {
      return req(module_name);
    } catch (err) {
      var resolve = null;
      req.main.paths.some(function (item) {
        if (resolve) return true;
        item = item.replace('node_modules', pathname);
        try {
          var main = path.join(item, module_name, 'package.json');
          main = req(main).main;
          main = path.join(item, module_name, main);
          req(main);
          resolve = main;
        } catch (e) {} // do nothing
      });
      if (!resolve) throw err;
      return req(resolve)
    }
  };
};

Add path for supporting Windows


import bluebird from 'bluebird'
import consoleStamp from 'console-stamp'
import 'newrelic';

import { getSingleton as initApp } from './app/app'

global.Promise = bluebird
global.Promise.onPossiblyUnhandledRejection((e) => { throw e; });

consoleStamp(console, 'yyyy/mm/dd HH:MM:ss.l')

initApp()
  .then((app) => {
    app.logger.info(`Server initialization is complete`)
  })
  .catch((e) => {
    process.stderr.write(`FATAL ERROR\n`)
    process.stderr.write(`${e.message}\n`)
    process.stderr.write(`${e.stack}\n`)
    process.exit(1)
  })

import { statSync } from 'fs';

import bluebird from 'bluebird'
import consoleStamp from 'console-stamp'

import { getSingleton as initApp } from './app/app'

try {
  statSync(`${__dirname}/newrelic.js`);
  require('newrelic');
} catch (e) {
  // No newrelic's config found. Won't report stats to them
}

global.Promise = bluebird
global.Promise.onPossiblyUnhandledRejection((e) => { throw e; });

consoleStamp(console, 'yyyy/mm/dd HH:MM:ss.l')

initApp()
  .then((app) => {
    app.logger.info(`Server initialization is complete`)
  })
  .catch((e) => {
    process.stderr.write(`FATAL ERROR\n`)
    process.stderr.write(`${e.message}\n`)
    process.stderr.write(`${e.stack}\n`)
    process.exit(1)
  })

Enable newrelic only if config exists


var loaderUtils = require('loader-utils');
var postcss     = require('postcss');

module.exports = function (source) {
    if ( this.cacheable ) this.cacheable();

    var file    = loaderUtils.getRemainingRequest(this);
    var params  = loaderUtils.parseQuery(this.query);

    var opts = { from: file, to: file };
    if ( params.safe ) opts.safe = true;

    var processors = this.options.postcss;
    if ( params.pack ) {
        processors = processors[params.pack];
    } else if ( !Array.isArray(processors) ) {
        processors = processors.defaults;
    }

    var processed = postcss.apply(postcss, processors).process(source, opts);
    this.callback(null, processed.css, processed.map);
};

var loaderUtils = require('loader-utils');
var postcss     = require('postcss');

module.exports = function (source, map) {
    if ( this.cacheable ) this.cacheable();

    var file    = loaderUtils.getRemainingRequest(this);
    var params  = loaderUtils.parseQuery(this.query);

    var opts = { from: file, to: file, map: { prev: map, inline: false } };
    if ( params.safe ) opts.safe = true;

    var processors = this.options.postcss;
    if ( params.pack ) {
        processors = processors[params.pack];
    } else if ( !Array.isArray(processors) ) {
        processors = processors.defaults;
    }

    var processed = postcss.apply(postcss, processors).process(source, opts);
    this.callback(null, processed.css, processed.map);
};

Use previous source map and don't inline the source maps.


var toc = require('markdown-toc');

module.exports = {
    book: {},
    hooks: {
        "page:before": function (page) {
            page.content = toc.insert(page.content, {
                slugify: function (str) {
                    return encodeURI(str.toLowerCase()).replace(/%20/g, '-').replace(/[\.,\-\(\)]/g,'');
                }
            });
            if (this.options.pluginsConfig.atoc.addClass) {
                var className = this.options.pluginsConfig.atoc.className || 'atoc';
                page.content = page.content + '\n\n\n<script type="text/javascript">var targetUl = document.getElementsByClassName(\'page-inner\')[0].getElementsByTagName(\'ul\')[0];if(targetUl&&targetUl.getElementsByTagName(\'a\').length>0){targetUl.className=\'' + className + '\';}</script>';
            }
            return page;
        }
    }
};

var toc = require('markdown-toc');

module.exports = {
    book: {},
    hooks: {
        "page:before": function (page) {
            page.content = toc.insert(page.content, {
                slugify: function (str) {
                    return encodeURI(str.toLowerCase().replace(/[\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-]/g,'')).replace(/%20/g, '-');
                }
            });
            if (this.options.pluginsConfig.atoc.addClass) {
                var className = this.options.pluginsConfig.atoc.className || 'atoc';
                page.content = page.content + '\n\n\n<script type="text/javascript">var targetUl = document.getElementsByClassName(\'page-inner\')[0].getElementsByTagName(\'ul\')[0];if(targetUl&&targetUl.getElementsByTagName(\'a\').length>0){targetUl.className=\'' + className + '\';}</script>';
            }
            return page;
        }
    }
};

Fix every case a special character is suppressed


const createUrl = require('./lib/create-url');
const downloadAndSave = require('./lib/download-and-save');
const parsePage = require('./lib/parse-page');

module.exports = save;

/**
 * @param  {string} urlOrMediaId
 * @return {Promise}
 */
function save(urlOrMediaId, dir) {
  return new Promise((resolve, reject) => {
    const url = createUrl(urlOrMediaId);

    parsePage(url)
      .then(post => {
        const downloadUrl = post.downloadUrl;
        const filename = post.filename;
        const isVideo = post.isVideo;
        const mimeType = post.mimeType;
        const file = `${dir}/${filename}`;

        downloadAndSave(downloadUrl, filename).then(() => {
          return resolve({
            file,
            mimeType,
            url,
            label: isVideo ? 'video' : 'photo',
            source: downloadUrl
          });
        });
      })
      .catch(err => {
        return reject({
          url,
          error: err,
          message: `Download failed`
        });
      });
  });
}

const createUrl = require('./lib/create-url');
const downloadAndSave = require('./lib/download-and-save');
const parsePage = require('./lib/parse-page');

module.exports = save;

/**
 * @param  {string} urlOrMediaId
 * @return {Promise}
 */
function save(urlOrMediaId, dir) {
  return new Promise((resolve, reject) => {
    const url = createUrl(urlOrMediaId);

    parsePage(url)
      .then(post => {
        const downloadUrl = post.downloadUrl;
        const filename = post.filename;
        const isVideo = post.isVideo;
        const mimeType = post.mimeType;
        const file = `${dir}/${filename}`;

        downloadAndSave(downloadUrl, file).then(() => {
          return resolve({
            file,
            mimeType,
            url,
            label: isVideo ? 'video' : 'photo',
            source: downloadUrl
          });
        });
      })
      .catch(err => {
        return reject({
          url,
          error: err,
          message: `Download failed`
        });
      });
  });
}

Fix for dir being ignored when supplied and files always saved to cwd.


var DtsCreator = require('typed-css-modules');
var loaderUtils = require('loader-utils');
var objectAssign = require('object-assign');

module.exports = function(source, map) {
  this.cacheable && this.cacheable();
  var callback = this.async();

  // Pass on query parameters as an options object to the DtsCreator. This lets
  // you change the default options of the DtsCreator and e.g. use a different
  // output folder.
  var queryOptions = loaderUtils.parseQuery(this.query);
  var options;
  if (queryOptions) {
    options = objectAssign({}, queryOptions);
  }

  var creator = new DtsCreator(options);

  // creator.create(..., source) tells the module to operate on the
  // source variable. Check API for more details.
  creator.create(this.resourcePath, source).then(content => {
    // Emit the created content as well
    this.emitFile(this.resourcePath + '.d.ts', content.contents || ['']);
    content.writeFile().then(_ => {
      callback(null, source, map);
    });
  });
};

var DtsCreator = require('typed-css-modules');
var loaderUtils = require('loader-utils');
var objectAssign = require('object-assign');

module.exports = function(source, map) {
  this.cacheable && this.cacheable();
  var callback = this.async();

  // Pass on query parameters as an options object to the DtsCreator. This lets
  // you change the default options of the DtsCreator and e.g. use a different
  // output folder.
  var queryOptions = loaderUtils.parseQuery(this.query);
  var options;
  if (queryOptions) {
    options = objectAssign({}, queryOptions);
  }

  var creator = new DtsCreator(options);

  // creator.create(..., source) tells the module to operate on the
  // source variable. Check API for more details.
  creator.create(this.resourcePath, source).then(content => {
    // Emit the created content as well
    this.emitFile(content.outputFilePath, content.contents || [''], map);
    content.writeFile().then(_ => {
      callback(null, source, map);
    });
  });
};

Use content.outputFilePath and use pass sourcemap


'use strict'
var express = require('express'),
    app = express(),
    bodyParser = require('body-parser'),
    config = require('./libs/config'),
    email = require('./libs/email')

app.use(bodyParser.json())
app.post('/subscribe', email.subscribe)

app.listen(config.port)

'use strict'
var express = require('express'),
    app = express(),
    bodyParser = require('body-parser'),
    config = require('./libs/config'),
    email = require('./libs/email')

app.use(bodyParser.json())
app.post('/subscribe', email.subscribe)

app.listen(process.env.PORT || config.port)

Allow PORT to be set from cli


/* Uses the slack button feature to offer a real time bot to multiple teams */
var Botkit = require('botkit');

if (!process.env.TOKEN || !process.env.PORT) {
  console.log('Error: Specify token and port in environment');
  process.exit(1);
}

var config = {}
if(process.env.MONGOLAB_URI) {
  var BotkitStorage = require('botkit-storage-mongo');
  config = {
    storage:  BotkitStorage({mongoUri: process.env.MONGOLAB_URI}),
  };
} else {
  config = {
    json_file_store: './db_slackbutton_bot/',
  };
}

var controller = Botkit.slackbot(config);

controller.spawn({
  token: process.env.TOKEN
}).startRTM(function(err) {
  if (err) {
    throw new Error(err);
  }
});

// BEGIN EDITING HERE!

controller.hears('hello','direct_message',function(bot,message) {
  bot.reply(message,'Hello!');
});

controller.hears('^stop','direct_message',function(bot,message) {
  bot.reply(message,'Goodbye');
  bot.rtm.close();
});

controller.on('direct_message,mention,direct_mention',function(bot,message) {
  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'robot_face',
  },function(err) {
    if (err) { console.log(err) }
    bot.reply(message,'I heard you loud and clear boss.');
  });
});

/* Uses the slack button feature to offer a real time bot to multiple teams */
var Botkit = require('botkit');

if (!process.env.TOKEN) {
  console.log('Error: Missing environment variable TOKEN. Please Specify your Slack token in environment');
  process.exit(1);
}

var config = {}
if(process.env.MONGOLAB_URI) {
  var BotkitStorage = require('botkit-storage-mongo');
  config = {
    storage:  BotkitStorage({mongoUri: process.env.MONGOLAB_URI}),
  };
} else {
  config = {
    json_file_store: './db_slackbutton_bot/',
  };
}

var controller = Botkit.slackbot(config);

controller.spawn({
  token: process.env.TOKEN
}).startRTM(function(err) {
  if (err) {
    throw new Error(err);
  }
});

// BEGIN EDITING HERE!

controller.hears('hello','direct_message',function(bot,message) {
  bot.reply(message,'Hello!');
});

// An example of what could be...
//
//controller.on('direct_message,mention,direct_mention',function(bot,message) {
//  bot.api.reactions.add({
//    timestamp: message.ts,
//    channel: message.channel,
//    name: 'robot_face',
//  },function(err) {
//    if (err) { console.log(err) }
//    bot.reply(message,'I heard you loud and clear boss.');
//  });
//});

Tidy things up, remove requirement for PORT env var


var AWS = require('aws-sdk');
var s3 = new AWS.S3();
var yaml = require('js-yaml');

// const s3EnvVars = require('s3-env-vars');
// var doc = s3EnvVars("mybucketname", "folderpathinbucket", "filename", function(err, data) {
//   if(err) console.log(err);
//   else console.log(data);
// });
module.exports = function(bucket, path, filename, callback) {
    var s3Params = {
        Bucket: bucket,
        Key: path + "/" + filename
    };
    s3.getObject(s3Params, function(err, data) {
        if (err) callback(err, err.stack); // an error occurred
        else {
            try {
                console.log('info: ', "Retrieved s3 object.");
                var doc = yaml.safeLoad(data.Body);
                console.log('data: ', "yml file contents: ", doc);
                callback(null, data);
            } catch (e) {
                callback(err, err.stack); // an error occurred reading the yml file
            }
        }
    });

};

var AWS = require('aws-sdk');
var s3 = new AWS.S3();
var yaml = require('js-yaml');

// const s3EnvVars = require('s3-env-vars');
// var doc = s3EnvVars("mybucketname", "folderpathinbucket", "filename", function(err, data) {
//   if(err) console.log(err);
//   else console.log(data);
// });
module.exports = function(bucket, path, filename, callback) {
    var s3Params = {
        Bucket: bucket,
        Key: path + "/" + filename
    };
    s3.getObject(s3Params, function(err, data) {
        if (err) callback(err, err.stack); // an error occurred
        else {
            try {
                console.log('info: ', "Retrieved s3 object.");
                var doc = yaml.safeLoad(data.Body);
                console.log('data: ', "yml file contents: ", doc);
                callback(null, doc);
            } catch (e) {
                callback(err, err.stack); // an error occurred reading the yml file
            }
        }
    });

};

Send back the doc not the s3 object


import dataComplete from './actions/dataComplete';
import preprocessData from './actions/preprocessData';
import readFile from '../functions/file/readFile';
import preprocessFile from '../functions/file/preprocessFile';

import { PREPROCESSDATA, READDATA } from './constants';

const middleware = store => next => action => {
  const state = store.getState();

  switch (action.type) {
  case READDATA:
    if (!state.coordIn || !state.fileIn) {
      console.error('Input fields not filled properly!');
      break;
    }
    next(action);
    readFile(state.fileInList)
      .then(data => {
        store.dispatch(preprocessData(data));
      }).catch(error => {
        console.error(error.message);
      });
    break;
  case PREPROCESSDATA:
    preprocessFile(action.payload)
      .then(data => {
        store.dispatch(dataComplete(data));
      }).catch(error => {
        console.error(error.message);
      });
    break;
  default:
    next(action);
  }
};

export default middleware;

import dataComplete from './actions/dataComplete';
import preprocessData from './actions/preprocessData';
import readFile from '../functions/file/readFile';
import preprocessFile from '../functions/file/preprocessFile';
import parseCoordinates from '../functions/parseCoordinates';
import issetCoordinates from '../functions/issetCoordinates';

import { PREPROCESSDATA, READDATA } from './constants';

const checkCoordinates = coordinates => issetCoordinates(parseCoordinates(coordinates));

const middleware = store => next => action => {
  const state = store.getState();

  switch (action.type) {
  case READDATA:
    if (!state.coordIn || !state.fileIn || !checkCoordinates(state.coordIn)) {
      console.error('Input fields not filled properly!');
      break;
    }
    next(action);
    readFile(state.fileInList)
      .then(data => {
        store.dispatch(preprocessData(data));
      }).catch(error => {
        console.error(error.message);
      });
    break;
  case PREPROCESSDATA:
    preprocessFile(action.payload)
      .then(data => {
        store.dispatch(dataComplete(data));
      }).catch(error => {
        console.error(error.message);
      });
    break;
  default:
    next(action);
  }
};

export default middleware;

Check passed coordinates to be correct


'use strict';

const Campaigns = require('../../app/models/Campaign');

module.exports = function getCampaignForKeyword() {
  return (req, res, next) => {
    if (req.reply.template) {
      return next();
    }

    return Campaigns.findByKeyword(req.userCommand)
      .then((campaign) => {
        if (! campaign) {
          return next();
        }

        req.campaign = campaign;
        req.keyword = req.userCommand;

        return next();
      });
  };
};

'use strict';

const Campaigns = require('../../app/models/Campaign');

module.exports = function getCampaignForKeyword() {
  return (req, res, next) => {
    if (req.reply.template) {
      return next();
    }

    // Did User send a Campaign keyword?
    return Campaigns.findByKeyword(req.userCommand)
      .then((campaign) => {
        if (! campaign) {
          return next();
        }

        req.campaign = campaign;
        req.keyword = req.userCommand;
        // Gambit to handle the Confirmation/Continue reply.
        req.reply.template = 'gambit';

        return next();
      });
  };
};

Fix Campaign keyword, send Gambit reply


({
  mainConfigFile: './requirejs.conf.js',
  paths: {
    jquery: 'lib/jquery/jquery.min',
    almond: 'lib/almond/almond'
  },
  baseUrl: '.',
  name: "streamhub-map",
  exclude: ['streamhub-sdk', 'almond'],
  stubModules: ['text', 'hgn', 'json'],
  out: "./dist/streamhub-map.min.js",
  namespace: 'Livefyre',
  pragmasOnSave: {
    excludeHogan: true
  },
  optimize: "uglify2",
  uglify2: {
    compress: {
      unsafe: true
    },
    mangle: true
  },
  onBuildRead: function(moduleName, path, contents) {
    if (moduleName == "jquery") {
      contents = "define([], function(require, exports, module) {" + contents + "});";
    }
    return contents;
  }
})

({
  mainConfigFile: './requirejs.conf.js',
  paths: {
    jquery: 'lib/jquery/jquery.min',
    almond: 'lib/almond/almond'
  },
  baseUrl: '.',
  name: "streamhub-map",
  exclude: ['streamhub-sdk', 'almond'],
  stubModules: ['text', 'hgn', 'json'],
  out: "./dist/streamhub-map.min.js",
  namespace: 'Livefyre',
  pragmasOnSave: {
    excludeHogan: true
  },
  cjsTranslate: true,
  optimize: "uglify2",
  uglify2: {
    compress: {
      unsafe: true
    },
    mangle: true
  },
  onBuildRead: function(moduleName, path, contents) {
    if (moduleName == "jquery") {
      contents = "define([], function(require, exports, module) {" + contents + "});";
    }
    return contents;
  }
})

Add 'cjsTranslate' config option to build profile


/** @license MIT License (c) copyright 2014 original authors */
/** @author Brian Cavalier */
/** @author John Hann */

define(['curl/_privileged'], function (priv) {
	var loadScript = priv['core'].loadScript;

	priv['core'].loadScript = function (def, success, failure) {
		var urlArgs = priv['config']()['urlArgs'];

		if (urlArgs) {
			def.url += (def.url.indexOf('?') >= 0 ? '&' : '?') + urlArgs;
		}

		return loadScript(def, success, failure);
	};
});

/** @license MIT License (c) copyright 2014 original authors */
/** @author John Hann */

define(/*==='curl-cache-bust/cache-bust',===*/ ['curl/_privileged'], function (priv) {
	var loadScript = priv['core'].loadScript;

	priv['core'].loadScript = function (def, success, failure) {
		var urlArgs = priv['config']()['urlArgs'];

		if (urlArgs) {
			def.url += (def.url.indexOf('?') >= 0 ? '&' : '?') + urlArgs;
		}

		return loadScript(def, success, failure);
	};
});

Add replaceable module id for curl's make utility.


import React from 'react';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import { Provider } from 'react-redux';
import store from 'lib/store';
import App from 'components/app';
import AdminDashboard from 'components/admin-dashboard';
import ImportPanel from 'components/import';
import ExportPanel from 'components/export';
import LoggedIn from 'components/logged-in';

export default (
  <Provider store={ store }>
    <Router history={ browserHistory }>
      <Route path="/" component={ App }>
        <IndexRoute component={ LoggedIn } />
        <Route path="/admin" component={ AdminDashboard } />
        <Route path="/import" component={ ImportPanel } />
        <Route path="/export" component={ ExportPanel } />
      </Route>
    </Router>
  </Provider>
);

import React from 'react';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import { Provider } from 'react-redux';
import store from 'lib/store';
import App from 'components/app';
import ImportPanel from 'components/import';
import ExportPanel from 'components/export';
import LoggedIn from 'components/logged-in';

export default (
  <Provider store={ store }>
    <Router history={ browserHistory }>
      <Route path="/" component={ App }>
        <IndexRoute component={ LoggedIn } />
        <Route path="/import" component={ ImportPanel } />
        <Route path="/export" component={ ExportPanel } />
      </Route>
    </Router>
  </Provider>
);

Remove admin dashboard for now


import * as types from '../actions/connections';

export default function(state = {}, action) {
  switch (action.type) {
  case types.CONNECTION_REQUEST: {
    const { server, database } = action;
    return { connected: false, connecting: true, server, database };
  }
  case types.CONNECTION_SUCCESS: {
    if (!_isSameConnection(state, action)) return state;
    return { ...state, connected: true, connecting: false };
  }
  case types.CONNECTION_FAILURE: {
    if (!_isSameConnection(state, action)) return state;
    return { ...state, connected: false, connecting: false, error: action.error };
  }
  default : return state;
  }
}

function _isSameConnection (state, action) {
  return state.server === action.server
    && state.database === action.database;
}

import * as types from '../actions/connections';

const INITIAL_STATE = {};

export default function(state = INITIAL_STATE, action) {
  switch (action.type) {
  case types.CONNECTION_REQUEST: {
    const { server, database } = action;
    return { connected: false, connecting: true, server, database };
  }
  case types.CONNECTION_SUCCESS: {
    if (!_isSameConnection(state, action)) return state;
    return { ...state, connected: true, connecting: false };
  }
  case types.CONNECTION_FAILURE: {
    if (!_isSameConnection(state, action)) return state;
    return { ...state, connected: false, connecting: false, error: action.error };
  }
  default : return state;
  }
}

function _isSameConnection (state, action) {
  return state.server === action.server
    && state.database === action.database;
}

Move connection initial state to variable


export default {
  isDarwin: process.platform === 'darwin',
  isNonDarwin: process.platform !== 'darwin',
  isWindows: process.platform === 'win32',
  isLinux: process.platform === 'linux',
  isWindows7: process.platform === 'win32' &&
    navigator && !!navigator.userAgent.match(/(Windows 7|Windows NT 6\.1)/)
};

export default {
  isDarwin: process.platform === 'darwin',
  isNonDarwin: process.platform !== 'darwin',
  isWindows: process.platform === 'win32',
  isLinux: process.platform === 'linux',
  isWindows7: process.platform === 'win32' && window.navigator &&
    !!window.navigator.userAgent.match(/(Windows 7|Windows NT 6\.1)/)
};

Fix detection of Windows 7


const _ = require("lodash");
const express = require("express");
const router = express.Router();
const session = require("express-session");
const connect = require("../../utils/database.js");
const restrict = require("../../utils/middlewares/restrict.js");
const auth = require("../../utils/auth.js");
const jwt = require('jsonwebtoken');
const CharError = require("../../utils/charError.js");
const Promise = require("bluebird");
Promise.promisifyAll(jwt);
require('dotenv').config();

const secret = "secret_key_PLEASE_CHANGE";

// Catch all for authentication (temporary)
router.use(function(req, res, next){
	// Anonymous access to API
	if(typeof req.token == "undefined" && process.env.ALLOW_ANNONYMOUS_TOKENS == "true"){
		req.user = {
			username: "Anonymous",
			role: "anonymous"
		};
		next();
		return;
	}

	// Authenticate here and also set the logged in users role accordingly
	// Verify auth token
	jwt.verifyAsync(req.token, secret).then(function(payload){
		req.user = {
			username: payload.username,
			role: payload.role
		};
		next();
	}).catch(function(err){
		next(new CharError("Auth Token Invalid", err.message, 403));
	});
});

module.exports = router;

const _ = require("lodash");
const express = require("express");
const router = express.Router();
const session = require("express-session");
const connect = require("../../utils/database.js");
const restrict = require("../../utils/middlewares/restrict.js");
const auth = require("../../utils/auth.js");
const jwt = require('jsonwebtoken');
const CharError = require("../../utils/charError.js");
const Promise = require("bluebird");
Promise.promisifyAll(jwt);
require('dotenv').config();

const secret = process.env.JWT_SECRET;

// Catch all for authentication (temporary)
router.use(function(req, res, next){
	// Anonymous access to API
	if(typeof req.token == "undefined" && process.env.ALLOW_ANNONYMOUS_TOKENS == "true"){
		req.user = {
			username: "Anonymous",
			role: "anonymous"
		};
		next();
		return;
	}

	// Authenticate here and also set the logged in users role accordingly
	// Verify auth token
	jwt.verifyAsync(req.token, secret).then(function(payload){
		req.user = {
			username: payload.username,
			role: payload.role
		};
		next();
	}).catch(function(err){
		next(new CharError("Auth Token Invalid", err.message, 403));
	});
});

module.exports = router;

Use .env to store secret


'use strict';

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

const nodePaths = (process.env.NODE_PATH || '')
  .split(process.platform === 'win32' ? ';' : ':')
  .filter(Boolean)
  .filter(folder => !path.isAbsolute(folder))
  .map(resolveApp);

function ensureSlash(path, needsSlash) {
  const hasSlash = path.endsWith('/');
  if (hasSlash && !needsSlash) {
    return path.substr(path, path.length - 1);
  } else if (!hasSlash && needsSlash) {
    return `${path}/`;
  } else {
    return path;
  }
}

function resolveApp(relativePath) {
  return path.resolve(fs.realpathSync(process.cwd()), relativePath);
}

function resolveOwn(relativePath) {
  return path.resolve(__dirname, '..', relativePath);
}

module.exports = {
  appPath: resolveApp('.'),
  appBuild: resolveApp('build'),
  appBuildPublic: resolveApp('build/public'),
  appManifest: resolveApp('build/assets.json'),
  appPublic: resolveApp('public'),
  appNodeModules: resolveApp('node_modules'),
  appSrc: resolveApp('src'),
  appServerIndexJs: resolveApp('src/index.js'),
  appClientIndexJs: resolveApp('src/client'),
  appBabelRc: resolveApp('.babelrc'),
  appRazzleConfig: resolveApp('razzle.config.js'),
  nodePaths: nodePaths,
  ownPath: resolveOwn('.'),
  ownNodeModules: resolveOwn('node_modules'),
};

'use strict';

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

const nodePaths = (process.env.NODE_PATH || '')
  .split(process.platform === 'win32' ? ';' : ':')
  .filter(Boolean)
  .filter(folder => !path.isAbsolute(folder))
  .map(resolveApp);

function ensureSlash(path, needsSlash) {
  const hasSlash = path.endsWith('/');
  if (hasSlash && !needsSlash) {
    return path.substr(path, path.length - 1);
  } else if (!hasSlash && needsSlash) {
    return `${path}/`;
  } else {
    return path;
  }
}

function resolveApp(relativePath) {
  return path.resolve(fs.realpathSync(process.cwd()), relativePath);
}

function resolveOwn(relativePath) {
  return path.resolve(__dirname, '..', relativePath);
}

module.exports = {
  appPath: resolveApp('.'),
  appBuild: resolveApp('build'),
  appBuildPublic: resolveApp('build/public'),
  appManifest: resolveApp('build/assets.json'),
  appPublic: resolveApp('public'),
  appNodeModules: resolveApp('node_modules'),
  appSrc: resolveApp('src'),
  appServerIndexJs: resolveApp('src'),
  appClientIndexJs: resolveApp('src/client'),
  appBabelRc: resolveApp('.babelrc'),
  appRazzleConfig: resolveApp('razzle.config.js'),
  nodePaths: nodePaths,
  ownPath: resolveOwn('.'),
  ownNodeModules: resolveOwn('node_modules'),
};

Make path to server more TS friendly by removing strict file type


import React from 'react';
import RaisedButton from 'material-ui/RaisedButton';
import ActionAndroid from 'material-ui/svg-icons/action/android';
import FontIcon from 'material-ui/FontIcon';

const styles = {
  button: {
    margin: 12,
  },
  exampleImageInput: {
    cursor: 'pointer',
    position: 'absolute',
    top: 0,
    bottom: 0,
    right: 0,
    left: 0,
    width: '100%',
    opacity: 0,
  },
};

const RaisedButtonExampleComplex = () => (
  <div>
    <RaisedButton
      label="Choose an Image"
      labelPosition="before"
      style={styles.button}
    >
      <input type="file" style={styles.exampleImageInput} />
    </RaisedButton>
    <RaisedButton
      label="Label before"
      labelPosition="before"
      primary={true}
      icon={<ActionAndroid />}
      style={styles.button}
    />
    <RaisedButton
      label="Github Link"
      href="https://github.com/callemall/material-ui"
      secondary={true}
      style={styles.button}
      icon={<FontIcon className="muidocs-icon-custom-github" />}
    />
  </div>
);

export default RaisedButtonExampleComplex;

import React from 'react';
import RaisedButton from 'material-ui/RaisedButton';
import ActionAndroid from 'material-ui/svg-icons/action/android';
import FontIcon from 'material-ui/FontIcon';

const styles = {
  button: {
    margin: 12,
  },
  exampleImageInput: {
    cursor: 'pointer',
    position: 'absolute',
    top: 0,
    bottom: 0,
    right: 0,
    left: 0,
    width: '100%',
    opacity: 0,
  },
};

const RaisedButtonExampleComplex = () => (
  <div>
    <RaisedButton
      label="Choose an Image"
      labelPosition="before"
      style={styles.button}
      containerElement="label"
    >
      <input type="file" style={styles.exampleImageInput} />
    </RaisedButton>
    <RaisedButton
      label="Label before"
      labelPosition="before"
      primary={true}
      icon={<ActionAndroid />}
      style={styles.button}
    />
    <RaisedButton
      label="Github Link"
      href="https://github.com/callemall/material-ui"
      secondary={true}
      style={styles.button}
      icon={<FontIcon className="muidocs-icon-custom-github" />}
    />
  </div>
);

export default RaisedButtonExampleComplex;

Update file input RaisedButton example


module.exports = {
  collectCoverageFrom: [
    "**/src/**/*.{js,jsx}",
    "!**/index.js",
  ],
  coverageDirectory: "<rootDir>/packages/storybook/coverage",
  coveragePathIgnorePatterns: [
    "node_modules",
    "packages\/vanilla",
    "src\/playground",
    "examples\/redux",
    "__stories__",
    "__gemini__"
  ],
  coverageThreshold: {
    global: {
      branches: 60,
      functions: 60,
      lines: 60,
      statements: 60
    }
  },
  moduleNameMapper: {
    "\\.(css|scss|svg)$": "<rootDir>/packages/storybook/support/jest/fileMock.js"
  },
  modulePaths: ["node_modules"],
  moduleFileExtensions: ["js", "jsx", "json"],
  rootDir: "../../",
  setupFiles: ["raf/polyfill"],
  setupTestFrameworkScriptFile: "<rootDir>/packages/storybook/support/jest/setupTests.js",
  testPathIgnorePatterns: ["<rootDir>/packages/vanilla"],
  unmockedModulePathPatterns: ["node_modules"]
};

module.exports = {
  collectCoverageFrom: [
    "**/src/**/*.{js,jsx}"
  ],
  coverageDirectory: "<rootDir>/packages/storybook/coverage",
  coveragePathIgnorePatterns: [
    "node_modules",
    "packages\/vanilla",
    "src\/playground",
    "examples\/redux",
    "__stories__",
    "__gemini__"
  ],
  coverageThreshold: {
    global: {
      branches: 60,
      functions: 60,
      lines: 60,
      statements: 60
    }
  },
  moduleNameMapper: {
    "\\.(css|scss|svg)$": "<rootDir>/packages/storybook/support/jest/fileMock.js"
  },
  modulePaths: ["node_modules"],
  moduleFileExtensions: ["js", "jsx", "json"],
  rootDir: "../../",
  setupFiles: ["raf/polyfill"],
  setupTestFrameworkScriptFile: "<rootDir>/packages/storybook/support/jest/setupTests.js",
  testPathIgnorePatterns: ["<rootDir>/packages/vanilla"],
  unmockedModulePathPatterns: ["node_modules"]
};

Include coverage for index files


const createLogger = require('redux-logger');
const enableBatching = require('redux-batched-actions').enableBatching;
const promiseMiddleware = require('redux-promise-middleware').default;
const redux = require('redux');
const thunk = require('redux-thunk').default;

const createReducer = require('@state/reducers');

const {
  createStore,
  compose,
  applyMiddleware
} = redux;

module.exports = (state = Object.freeze({})) => {
  return createStore(
    enableBatching(createReducer()),
    state,
    compose(
      applyMiddleware(
        createLogger(),
        promiseMiddleware(),
        thunk
      )
    )
  );
};

const createLogger = require('redux-logger');
const enableBatching = require('redux-batched-actions').enableBatching;
const promiseMiddleware = require('redux-promise-middleware').default;
const redux = require('redux');
const thunk = require('redux-thunk').default;

const createReducer = require('@state/reducers');

const {
  createStore,
  compose,
  applyMiddleware
} = redux;

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

module.exports = (state = Object.freeze({})) => {
  return createStore(
    enableBatching(createReducer()),
    state,
    composeEnhancers(
      applyMiddleware(
        createLogger(),
        promiseMiddleware(),
        thunk
      )
    )
  );
};

Add Redux devtool extension connection - will need to only be available in dev in the future


ProjectsController.$inject = [ 'TbUtils', 'projects', '$rootScope' ];

function ProjectsController(TbUtils, projects, $rootScope) {
    const vm = this;

    vm.searchObj = term => { return { Name: term }; };
    vm.searchResults = [];

    vm.pageSize = 9;
    vm.get = projects.getProjectsWithPagination;
    vm.getAll = projects.getProjects;
    vm.hideLoadBtn = () => vm.projects.length !== vm.searchResults.length;

    vm.projects = [];

    vm.goToProject = project => { TbUtils.go('main.project', { projectId: project.Id }); };
    vm.goToNewProject = project => { TbUtils.go('main.addproject'); };
    vm.goToEdit = project => { TbUtils.go('main.editproject', { project: JSON.stringify(project) }); };

    vm.loading = true;

    vm.removeProjectClicked = removeProjectClicked;
    vm.toTitleCase = TbUtils.toTitleCase;

    TbUtils.getAndLoad(vm.get, vm.projects, () => { vm.loading = false; }, 0, vm.pageSize);

    function removeProjectClicked(project) {
        TbUtils.confirm('Eliminar Proyecto', `Esta seguro de eliminar ${project.Name}?`,
            resolve => {
                if (resolve) {
                    vm.loading = true;
                    TbUtils.deleteAndNotify(projects.deleteProject, project, vm.projects,
                        () => { vm.loading = false; });
                }
            });
    }

}

module.exports = {
    name: 'ProjectsController',
    ctrl: ProjectsController
};

ProjectsController.$inject = [ 'TbUtils', 'projects', '$rootScope' ];

function ProjectsController(TbUtils, projects, $rootScope) {
    const vm = this;

    vm.searchObj = term => { return { Name: term }; };
    vm.searchResults = [];

    vm.pageSize = 9;
    vm.get = projects.getProjectsWithPagination;
    vm.getAll = projects.getProjects;
    vm.hideLoadBtn = () => vm.projects.length !== vm.searchResults.length;

    vm.projects = [];

    vm.goToProject = project => { TbUtils.go('main.project', { projectId: project.Id }); };
    vm.goToNewProject = project => { TbUtils.go('main.new-project'); };
    vm.goToEdit = project => { TbUtils.go('main.edit-project', { project: btoa(JSON.stringify(project)) }); };

    vm.loading = true;

    vm.removeProjectClicked = removeProjectClicked;
    vm.toTitleCase = TbUtils.toTitleCase;

    TbUtils.getAndLoad(vm.get, vm.projects, () => { vm.loading = false; }, 0, vm.pageSize);

    function removeProjectClicked(project) {
        TbUtils.confirm('Eliminar Proyecto', `Esta seguro de eliminar ${project.Name}?`,
            resolve => {
                if (resolve) {
                    vm.loading = true;
                    TbUtils.deleteAndNotify(projects.deleteProject, project, vm.projects,
                        () => { vm.loading = false; });
                }
            });
    }

}

module.exports = { name: 'ProjectsController', ctrl: ProjectsController };

Change redirects to project form


var mysql = require('mysql');

exports.connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  database: 'uncovery'
});

exports.initialize = function(callback) {
  exports.connection.connect();
};

var mysql = require('mysql');

exports.connection = mysql.createConnection({
  host: 'localhost',
  user: 'tony',
  database: 'uncovery'
});

exports.initialize = function(callback) {
  exports.connection.connect();
};

Update Schema to change userIds to userTokens


$(document).ready(function() {
  if (window.location.href.search(/query=/) == -1) {
    $('#query').one('click, focus', function() {
      $(this).val('');
    });
  }

  $(document).bind('keyup', function(event) {
    if ($(event.target).is(':input')) {
      return;
    }

    if (event.which == 83) {
      $('#query').focus();
    }
  });

  $('#version_for_stats').change(function() {
    window.location.href = $(this).val();
  });

});

$(document).ready(function() {
  $('#version_for_stats').change(function() {
    window.location.href = $(this).val();
  });
});

Remove JS that handled not-quite-placeholder.


defaultScope(4);
intRange(-8, 7);

c10_Car = Clafer("c10_Car").withCard(4, 4);
c11_owner = c10_Car.addChild("c11_owner").withCard(1, 1);
c21_Person = Clafer("c21_Person").withCard(4, 4);
c11_owner.refToUnique(c21_Person);
Constraint(all([disjDecl([c1 = local("c1"), c2 = local("c2")], global(c10_Car))], notEqual(join(c1, c11_owner), join(c2, c11_owner))));

defaultScope(4);
intRange(-8, 7);

c10_Car = Clafer("c10_Car").withCard(4, 4);
c11_owner = c10_Car.addChild("c11_owner").withCard(1, 1);
c21_Person = Clafer("c21_Person").withCard(4, 4);
c11_owner.refToUnique(c21_Person);
Constraint(all([disjDecl([c1 = local("c1"), c2 = local("c2")], global(c10_Car))], notEqual(joinRef(join(c1, c11_owner)), joinRef(join(c2, c11_owner)))));

Add explicit refs to test case.


import React, { PropTypes } from 'react'
import {LineChart} from 'react-d3-basic'

import classes from './RoomChart.scss'

class RoomChart extends React.Component {
  static propTypes = {
    data: PropTypes.object
  };
  render () {
    const {data} = this.props
    let activity = []
    if (data && data.activity) {
      activity = data.activity
    }
    const chartData = activity.map((chunk) => {
      return {
        timestamp: new Date(chunk[0] * 1000),
        messages: chunk[1]
      }
    })
    const width = 550
    return (
      <LineChart
        data={chartData}
        width={width}
        height={300}
        margins={{
          top: 25,
          bottom: 60,
          right: 25,
          left: 50
        }}
        chartSeries={[
          {
            field: 'messages',
            name: 'Messages',
            color: '#ff7600',
            style: {
              'stroke-width': 2.5
            }
          }
        ]}
        x={(d) => d.timestamp}
        xScale='time'
        innerTickSize={20}
      />
    )
  }
}

export default RoomChart

import React, { PropTypes } from 'react'
import {LineChart} from 'react-d3-basic'

class RoomChart extends React.Component {
  static propTypes = {
    data: PropTypes.object
  };
  render () {
    const {data} = this.props
    let activity = []
    if (data && data.activity) {
      activity = data.activity
    }
    const chartData = activity.map((chunk) => {
      return {
        timestamp: new Date(chunk[0] * 1000),
        messages: chunk[1]
      }
    })
    const width = 550
    return (
      <LineChart
        data={chartData}
        width={width}
        height={300}
        margins={{
          top: 25,
          bottom: 60,
          right: 25,
          left: 50
        }}
        chartSeries={[
          {
            field: 'messages',
            name: 'Messages',
            color: '#ff7600',
            style: {
              'stroke-width': 2.5
            }
          }
        ]}
        x={(d) => d.timestamp}
        xScale='time'
        innerTickSize={20}
      />
    )
  }
}

export default RoomChart

Remove unused var to fix lint error


var path = require("path");
var fs = require("fs-extra");
var assert = require("assert");

var Box = require("../");

var TRUFFLE_BOX_DEFAULT = "git@github.com:trufflesuite/truffle-init-default.git";

describe("Unbox", function() {
  var destination = path.join(__dirname, ".truffle_test_tmp");

  before("mkdir", function(done) {
    fs.ensureDir(destination, done);
  });

  before("remove tmp dir", function(done) {
    fs.remove(destination, done);
  });

  it("unboxes truffle box from github", function() {
    this.timeout(5000);

    return Box.unbox(TRUFFLE_BOX_DEFAULT, destination)
      .then(function (truffleConfig) {
        assert.ok(truffleConfig);

        assert(
          fs.existsSync(path.join(destination, "truffle.js")),
          "Unboxed project should have truffle config."
        );
      });
  });
});

var path = require("path");
var fs = require("fs-extra");
var assert = require("assert");

var Box = require("../");

var TRUFFLE_BOX_DEFAULT = "git@github.com:trufflesuite/truffle-init-default.git";

describe("Unbox", function() {
  var destination = path.join(__dirname, ".truffle_test_tmp");

  before("mkdir", function(done) {
    fs.ensureDir(destination, done);
  });

  after("remove tmp dir", function(done) {
    fs.remove(destination, done);
  });

  it("unboxes truffle box from github", function() {
    this.timeout(5000);

    return Box.unbox(TRUFFLE_BOX_DEFAULT, destination)
      .then(function (truffleConfig) {
        assert.ok(truffleConfig);

        assert(
          fs.existsSync(path.join(destination, "truffle.js")),
          "Unboxed project should have truffle config."
        );
      });
  });

  it("won't re-init if truffle.js file exists", function(done) {
    this.timeout(5000);

    var contracts_directory = path.join(destination, "contracts");

    // Assert our precondition
    assert(fs.existsSync(contracts_directory), "contracts directory should exist for this test to be meaningful");

    fs.remove(contracts_directory, function(err) {
      if (err) return done(err);

      Box.unbox(TRUFFLE_BOX_DEFAULT, destination)
        .then(function(boxConfig) {
          assert(
            fs.existsSync(contracts_directory) == false,
            "Contracts directory got recreated when it shouldn't have"
          );
          done();
        })
        .catch(function(e) {
          if (e.message.indexOf("A Truffle project already exists at the destination.") >= 0) {
            done();
          } else {
            done(new Error("Unknown error received: " + e.stack));
          }
        });
    });
  });
});

Add project collision test from truffle-init


Ext.define('Densa.overrides.HasMany', {
    override: 'Ext.data.association.HasMany',
    /**
     * Allow filters in storeConfig
     *
     * Original overrides filters with filter
     */
    createStore: function() {
        var that            = this,
            associatedModel = that.associatedModel,
            storeName       = that.storeName,
            foreignKey      = that.foreignKey,
            primaryKey      = that.primaryKey,
            filterProperty  = that.filterProperty,
            autoLoad        = that.autoLoad,
            storeConfig     = that.storeConfig || {};

        return function() {
            var me = this,
                config, filter,
                modelDefaults = {};

            if (me[storeName] === undefined) {
                if (filterProperty) {
                    filter = {
                        property  : filterProperty,
                        value     : me.get(filterProperty),
                        exactMatch: true
                    };
                } else {
                    filter = {
                        property  : foreignKey,
                        value     : me.get(primaryKey),
                        exactMatch: true
                    };
                }
                if (!storeConfig.filters) storeConfig.filters = [];
                storeConfig.filters.push(filter);

                modelDefaults[foreignKey] = me.get(primaryKey);

                config = Ext.apply({}, storeConfig, {
                    model        : associatedModel,
                    remoteFilter : false,
                    modelDefaults: modelDefaults,
                    disableMetaChangeEvent: true
                });

                me[storeName] = Ext.data.AbstractStore.create(config);
                if (autoLoad) {
                    me[storeName].load();
                }
            }

            return me[storeName];
        };
    }
});

Ext.define('Densa.overrides.HasMany', {
    override: 'Ext.data.association.HasMany',
    /**
     * Allow filters in storeConfig
     *
     * Original overrides filters with filter
     */
    createStore: function() {
        var that            = this,
            associatedModel = that.associatedModel,
            storeName       = that.storeName,
            foreignKey      = that.foreignKey,
            primaryKey      = that.primaryKey,
            filterProperty  = that.filterProperty,
            autoLoad        = that.autoLoad,
            storeConfig     = that.storeConfig || {};

        return function() {
            var me = this,
                config, filter,
                modelDefaults = {};

            if (me[storeName] === undefined) {
                if (filterProperty) {
                    filter = {
                        property  : filterProperty,
                        value     : me.get(filterProperty),
                        exactMatch: true
                    };
                } else {
                    filter = {
                        property  : foreignKey,
                        value     : me.get(primaryKey),
                        exactMatch: true
                    };
                }

                var localStoreConfig = Ext.clone(storeConfig);
                if (!localStoreConfig.filters) localStoreConfig.filters = [];
                localStoreConfig.filters.push(filter);

                modelDefaults[foreignKey] = me.get(primaryKey);

                config = Ext.apply({}, localStoreConfig, {
                    model        : associatedModel,
                    remoteFilter : false,
                    modelDefaults: modelDefaults,
                    disableMetaChangeEvent: true
                });

                me[storeName] = Ext.data.AbstractStore.create(config);
                if (autoLoad) {
                    me[storeName].load();
                }
            }

            return me[storeName];
        };
    }
});

Fix filters in storeConfig: they where shared across multiple stores


"use strict";

var autoload = require('auto-load');
var kue = require('kue');
var async = require('async');
var debug = require('debug')('kue:boot');
var jobs = autoload(__dirname);

module.exports = function(app) {
  var queue = app.get('queue');
  var store = app.get('keyValueStore');

  delete jobs.index;
  for(var job in jobs) {
    debug('wait for job type', job);
    // create new job processor
    queue.process(job, app.get('concurrency'), jobs[job](app));
  }

  queue.on('job complete', function(id, result) {
    var afToken;
    async.waterfall([
      function getJob(cb) {
        kue.Job.get(id, cb);
      },
      function setCursor(job, cb) {
        afToken = job.anyfetchToken;

        store.hset('cursor', afToken, result, cb);
      },
      function setLastUpdate(status, cb) {
        store.hset('lastUpdate', afToken, Date.now().toString(), cb);
      },
      function unlockUpdate(status, cb) {
        store.hdel('status', afToken, cb);
      }
    ], function throwErrs(err) {
      if(err) {
        throw err;
      }
    });
  });
};

"use strict";

var autoload = require('auto-load');
var kue = require('kue');
var async = require('async');
var rarity = require('rarity');
var debug = require('debug')('kue:boot');
var jobs = autoload(__dirname);

module.exports = function(app) {
  var queue = app.get('queue');
  var store = app.get('keyValueStore');

  delete jobs.index;
  for(var job in jobs) {
    debug('wait for job type', job);
    // create new job processor
    queue.process(job, app.get('concurrency'), jobs[job](app));
  }

  queue.on('job complete', function(id, result) {
    async.waterfall([
      function getJob(cb) {
        kue.Job.get(id, cb);
      },
      function removeJob(job, cb) {
        var anyfetchToken = job.data.anyfetchToken;
        job.remove(rarity.carry([anyfetchToken], cb));
      },
      function setCursor(anyfetchToken, cb) {
        if(!anyfetchToken) {
          return cb(null, null, null);
        }
        store.hset('cursor', anyfetchToken, result, rarity.carry([anyfetchToken], cb));
      },
      function setLastUpdate(anyfetchToken, status, cb) {
        if(!anyfetchToken) {
          return cb(null, null, null);
        }
        store.hset('lastUpdate', anyfetchToken, Date.now().toString(), rarity.carry([anyfetchToken], cb));
      },
      function unlockUpdate(anyfetchToken, status, cb) {
        if(!anyfetchToken) {
          return cb(null, null, null);
        }
        store.hdel('status', anyfetchToken, cb);
      }
    ], function throwErrs(err) {
      if(err) {
        throw err;
      }
    });
  });
};

Clean redis after succeeded jobs


var _ = require('lodash');
var logger = require('winston');
var request = require('superagent');

function SlackGateway(incomingURL, channelMapping) {
  this.incomingURL = incomingURL;
  this.invertedMapping = _.invert(channelMapping);
}

SlackGateway.prototype.sendToSlack = function(author, ircChannel, message) {
  var payload = {
    username: author,
    icon_url: 'https://github.com/identicons/' + author + '.png',
    channel: this.invertedMapping[ircChannel],
    text: message
  };

  request
    .post(this.incomingURL)
    .send(payload)
    .set('Accept', 'application/json')
    .end(function(err, res) {
      if (err) return logger.error('Couldn\'t post message to Slack', err);
      logger.debug('Posted message to Slack', res.body, res.statusCode);
    });
};

module.exports = SlackGateway;

var _ = require('lodash');
var logger = require('winston');
var request = require('superagent');

function SlackGateway(incomingURL, channelMapping) {
  this.incomingURL = incomingURL;
  this.invertedMapping = _.invert(channelMapping);
}

SlackGateway.prototype.sendToSlack = function(author, ircChannel, message) {
  var payload = {
    username: author,
    icon_url: 'http://api.adorable.io/avatars/48/' + author + '.png',
    channel: this.invertedMapping[ircChannel],
    text: message
  };

  request
    .post(this.incomingURL)
    .send(payload)
    .set('Accept', 'application/json')
    .end(function(err, res) {
      if (err) return logger.error('Couldn\'t post message to Slack', err);
      logger.debug('Posted message to Slack', res.body, res.statusCode);
    });
};

module.exports = SlackGateway;

Change icon_url to use adorable.io


var pingPongOutput = function(inputNumber) {
  if(inputNumber % 3 === 0) {
    return "ping";
  } else {
    return inputNumber;
  }
};

var pingPongOutput = function(inputNumber) {
  if(inputNumber % 3 === 0) {
    return "ping";
  } else if (inputNumber % 5 === 0) {
    return "pong";
  } else {
    return inputNumber;
  }
};

Implement numbers divisible by 5


var pingPong = function(i) {
  if (isPingPong(i)) {
    return pingPongType(i)
  } else {
    return false;
  }
}

var pingPongType = function(i) {
  if ((i % 3 === 0) && (i % 5 != 0)) {
      return "ping";
    } else if ((i % 5 === 0) && (i % 3 !=0)) {
      return "pong";
    } else if (i % 15 === 0){
      return "pingpong";
    }
  }

var isPingPong = function(i) {
  if ((i % 5 === 0) || (i % 3 === 0)){
    return true;
  } else {
    return false;
  }
}

$(function() {
  $("#game").submit(function(event) {
    $('#outputList').empty();

    var number = parseInt($("#userNumber").val());
    var whichPingPong = pingPongType(i)

    for (var i = 1; i <= number; i += 1) {
      if (pingPong(i)) {
        $('#outputList').append("
" + whichPingPong + "
");
      } else {
        $('#outputList').append("
" + i + "
");
      }
    }
    event.preventDefault();
  });
});

var pingPongType = function(i) {
  if (i % 15 === 0) {
      return "pingpong";
  } else if (i % 5 === 0) {
      return "pong";
  } else {
      return "ping";
  }
}

var isPingPong = function(i) {
  if ((i % 5 === 0) || (i % 3 === 0) || (i % 15 === 0)) {
    return pingPongType(i);
  } else {
    return false;
  }
}

$(function() {
  $("#game").submit(function(event) {
    $('#outputList').empty();

    var number = parseInt($("#userNumber").val());
    var whichPingPong = pingPongType(i)

    for (var i = 1; i <= number; i += 1) {
      if (isPingPong(i)) {
        $('#outputList').append("
" + whichPingPong + "
");
      } else {
        $('#outputList').append("
" + i + "
");
      }
    }
    event.preventDefault();
  });
});

Remove code for pingPong, leaving pingPongType and isPingPong as functions