<commit_before>var elf = require ( "../runtime/runtime" );

var Matchers = elf.Object.clone({
  clone: function () {
    var obj = elf.Object.clone();
    for (var prop in this) {
      if (this.hasOwnProperty(prop)) {
        obj[prop] = typeof this[prop] === "object" ? Object.create(this[prop]) : this[prop];
      }
    }

    return obj;
  }
});

var Walker = elf.Object.clone(function () {
  this.childNames = ["first", "second", "third"];

  this.init = function () {
    this.matchers = (this.matchers || Matchers.clone());
    this.matchers.extend(this.matchers.clone());
    this.childNames = Object.create(this.childNames);
  }

  // this.cloned = function (clonee) {
  //   clonee.init();
  // }

  this.extended = function (extendee) {
    extendee.matchers.extend(this.matchers);
  }

  this.extend = function (obj) {
    var walkers = [].slice.call(arguments);
    walkers.forEach(function (walker) {
      this.matchers.extend(walker.matchers.clone())
    }, this);
    // this.matchers.extend(obj.matchers.clone())
    return this;
  }

  this.default = function (env, node) {
    var childNodes = Array.prototype.slice.call(arguments, 2);
    this.walk(childNodes, env);

    return node;
  }

  this.error = function (env, node) {
    return node.error("No rule found for the " + (node.type === "error" ? 'token' : node.type) + " '" + node.value + "'.");
  };

  this.match = function (type) {
    if (!this.matchers[type]) this.matchers[type] = {specific: [], default: { handler: this.error }}

    if (arguments.length === 3) {
      this.matchers[type].specific.push({
        pattern : arguments[1],
        handler : arguments[2] || this.default
      })
    } else {
      this.matchers[type].default = { handler: arguments[1] || this.default }
    }
  }

  this.patternLength = function (pattern) {
    var self = this;
    return pattern.reduce(function (acc, el) {
      if (elf.helpers.isArray(el)) return acc + self.patternLength(el);
      return acc + 1
    }, 0);
  }

  this.validate = function (node, pattern) {
    return node && (typeof pattern === "undefined" || (pattern === node.value || pattern === node.type || pattern === node.arity));
  }

  this.process = function (node, patterns) {
    var self = this;

    var matches = patterns.filter(function (pattern, idx) {
      var child = node[self.childNames[idx]];
      if (elf.helpers.isArray(pattern))
        return self.validate(child, pattern[0]) && self.process(child, pattern.slice(1))
      else
        return self.validate(child, pattern);
    });

    return matches.length === patterns.length;
  };

  this.visit = function (node, env) {
    if (!node) return;

    var matcher    = this.matchers[node.value] || this.matchers[node.type] || this.matchers[node.arity] || this.matchers[undefined] || {specific: [], default: { handler: this.error }}
      , childNames = this.childNames.filter(function (name) { return node[name]; })
      , self       = this;

    var match = matcher.specific.reduce(function (acc, el) {
      var patternLen = self.patternLength(el.pattern);
      return (self.process(node, el.pattern) && (patternLen >= childNames.length)) ? el.handler : acc;
    }, null);

    var args = childNames.map(function (name) { return node[name]; });
    return (match || matcher.default.handler).apply(this, [env, node].concat(args));
  };

  this.walk = function (nodeList, env) {
    if (!nodeList) return;
    env = env || elf.Object.clone();
    var visit = function (node) { return this.visit(node, env); };

    if (nodeList.nodes || Array.isArray(nodeList)) {
      return (nodeList.nodes || nodeList).map(visit, this);
    } else {
      return this.visit(nodeList, env);
    }
  };

});

module.exports = Walker;<commit_msg>removed commented code<commit_after>var elf = require ( "../runtime/runtime" );

var Matchers = elf.Object.clone({
  clone: function () {
    var obj = elf.Object.clone();
    for (var prop in this) {
      if (this.hasOwnProperty(prop)) {
        obj[prop] = typeof this[prop] === "object" ? Object.create(this[prop]) : this[prop];
      }
    }

    return obj;
  }
});

var Walker = elf.Object.clone(function () {
  this.childNames = ["first", "second", "third"];

  this.init = function () {
    this.matchers = (this.matchers || Matchers.clone());
    this.matchers.extend(this.matchers.clone());
    this.childNames = Object.create(this.childNames);
  }

  this.extended = function (extendee) {
    extendee.matchers.extend(this.matchers);
  }

  this.extend = function (obj) {
    var walkers = [].slice.call(arguments);
    walkers.forEach(function (walker) {
      this.matchers.extend(walker.matchers.clone())
    }, this);
    return this;
  }

  this.default = function (env, node) {
    var childNodes = Array.prototype.slice.call(arguments, 2);
    this.walk(childNodes, env);

    return node;
  }

  this.error = function (env, node) {
    return node.error("No rule found for the " + (node.type === "error" ? 'token' : node.type) + " '" + node.value + "'.");
  };

  this.match = function (type) {
    if (!this.matchers[type]) this.matchers[type] = {specific: [], default: { handler: this.error }}

    if (arguments.length === 3) {
      this.matchers[type].specific.push({
        pattern : arguments[1],
        handler : arguments[2] || this.default
      })
    } else {
      this.matchers[type].default = { handler: arguments[1] || this.default }
    }
  }

  this.patternLength = function (pattern) {
    var self = this;
    return pattern.reduce(function (acc, el) {
      if (elf.helpers.isArray(el)) return acc + self.patternLength(el);
      return acc + 1
    }, 0);
  }

  this.validate = function (node, pattern) {
    return node && (typeof pattern === "undefined" || (pattern === node.value || pattern === node.type || pattern === node.arity));
  }

  this.process = function (node, patterns) {
    var self = this;

    var matches = patterns.filter(function (pattern, idx) {
      var child = node[self.childNames[idx]];
      if (elf.helpers.isArray(pattern))
        return self.validate(child, pattern[0]) && self.process(child, pattern.slice(1))
      else
        return self.validate(child, pattern);
    });

    return matches.length === patterns.length;
  };

  this.visit = function (node, env) {
    if (!node) return;

    var matcher    = this.matchers[node.value] || this.matchers[node.type] || this.matchers[node.arity] || this.matchers[undefined] || {specific: [], default: { handler: this.error }}
      , childNames = this.childNames.filter(function (name) { return node[name]; })
      , self       = this;

    var match = matcher.specific.reduce(function (acc, el) {
      var patternLen = self.patternLength(el.pattern);
      return (self.process(node, el.pattern) && (patternLen >= childNames.length)) ? el.handler : acc;
    }, null);

    var args = childNames.map(function (name) { return node[name]; });
    return (match || matcher.default.handler).apply(this, [env, node].concat(args));
  };

  this.walk = function (nodeList, env) {
    if (!nodeList) return;
    env = env || elf.Object.clone();
    var visit = function (node) { return this.visit(node, env); };

    if (nodeList.nodes || Array.isArray(nodeList)) {
      return (nodeList.nodes || nodeList).map(visit, this);
    } else {
      return this.visit(nodeList, env);
    }
  };

});

module.exports = Walker;<|endoftext|>


<commit_before>/**
 * Gets the current date in ISO format
 * @return {String} The current date string in ISO format
 */
export const currentDateISOString = () => {
  const date = new Date();

  return date.toISOString();
};

/**
 * Converts a Date to ISO string date
 * @param  {Date} date The date that we wanna convert
 * @return {String}    A date string in ISO format
 */
export const dateToISOString = (date) => {
  if (date instanceof Date) return date.toISOString();

  return null;
};

/**
 * Converts a ISO string date to Date
 * @param  {[type]} isoString A date string in ISO format that we wanna convert
 * @return {[type]}           A date object
 */
export const isoStringToDate = (isoString) => {
  if (typeof isoString === 'undefined' || isoString === null) {
    return null;
  }

  const date = new Date(isoString);

  return date;
};
<commit_msg>Changing DateFormatter functions names<commit_after>/**
 * Gets the current date in ISO format
 * @return {String} The current date string in ISO format
 */
export const getCurrentISOStringDate = () => {
  const date = new Date();

  return date.toISOString();
};

/**
 * Converts a Date to ISO string date
 * @param  {Date} date The date that we wanna convert
 * @return {String}    A date string in ISO format
 */
export const getISOStringFromDate = (date) => {
  if (date instanceof Date) return date.toISOString();

  return null;
};

/**
 * Converts a ISO string date to Date
 * @param  {[type]} isoString A date string in ISO format that we wanna convert
 * @return {[type]}           A date object
 */
export const getDateFromISOString = (isoString) => {
  if (typeof isoString === 'undefined' || isoString === null) {
    return null;
  }

  const date = new Date(isoString);

  return date;
};
<|endoftext|>


<commit_before>/*global Porthole*/
'use strict';

/*@ngInject*/
module.exports = function ($scope, $state, portholeProxy) {
  var windowProxy = new Porthole.WindowProxy(portholeProxy);
  var postObj = {
    action: 'activity_complete',
  };

  if ($state.params.student) {
    postObj.id = $state.params.student;
  }

  windowProxy.post(postObj);
};
<commit_msg>redirect to results page after successfully saving.<commit_after>/*global Porthole*/
'use strict';

/*@ngInject*/
module.exports = function ($scope, $state, portholeProxy) {
  var windowProxy = new Porthole.WindowProxy(portholeProxy);
  var postObj = {
    action: 'activity_complete',
  };

  if ($state.params.student) {
    postObj.id = $state.params.student;
  }
  window.location.href = "http://localhost:3000/activity_sessions/" + $state.params.student

  windowProxy.post(postObj);
};
<|endoftext|>


<commit_before>/*!
 * Snakeskin
 * https://github.com/SnakeskinTpl/Snakeskin
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/Snakeskin/blob/master/LICENSE
 */

var
	$C = require('collection.js').$C,
	snakeskin = global.Snakeskin = require('../snakeskin');

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

var
	glob = require('glob'),
	mkdirp = require('mkdirp');

var
	from = path.join(__dirname, 'tests'),
	to = path.join(__dirname, 'tmp'),
	error = path.join(__dirname, '../error.tmp');

exports.from = from;
exports.to = to;
exports.error = error;

var
	asserts = [],
	prfx = -1;

exports.run = function (params) {
	var
		options = JSON.stringify(params, null, 2),
		debug = params.debug = {};

	prfx++;
	$C(glob.sync(path.join(from, '*/*.ss'))).forEach(exec);

	function exec(file) {
		try {
			var txt = $C(fs.readFileSync(file, 'utf8').replace(/^\/\*![\s\S]*?\*\//, '').split(/^===.*/m))
				.map(function (el) {
					return el.trim();
				});

			var
				fileName = path.basename(file),
				cat = path.basename(path.dirname(file)),
				chunkSrc = path.join(to, fileName + '_' + prfx + '.' + cat + '.js'),
				relativeSrc = path.relative(process.cwd(), file),
				nms = [cat, path.basename(file, '.ss')];

			console.log('\n###### ' + nms.join('.') + '\n');

			var
				testRgxp = /^\[\[(.*)]]=*$/gm,
				tests = [],
				results = txt[0].split(/^\[\[.*]]=*$/m).slice(1);

			while (testRgxp.exec(txt[0])) {
				tests.push(RegExp.$1);
			}

		} catch (err) {
			log('File: ' + (relativeSrc || file) + '\nError: ' + err.message, 'error');
			return;
		}

		var obj = {
			tpl: txt[1],
			id: path.basename(file, '.ss'),
			js: []
		};

		try {
			var
				start = Date.now(),
				res = snakeskin.compile(txt[1], params, {file: file});

			if (!prfx) {
				log(relativeSrc + ' ' + (Date.now() - start) + 'ms');
			}

			fs.writeFileSync(chunkSrc, res);

			var
				tpl = $C(require(chunkSrc)).get(nms);

		} catch (err) {
			fs.writeFileSync(
				error,
				'File: ' + file + '\n\n' + err.message + (debug['code'] ? '\n\nCode:\n\n' + debug['code'] : '')
			);

			throw err;
		}

		$C(tests).forEach(function (el, i) {
			var
				p = String(el).split(' ; '),
				res = '';

			try {
				results[i] = (results[i] || '').trim();
				obj.js.push(
					'equal(' + p[0] + '(' + p.slice(1) + ').trim(), \'' + results[i].replace(/(\\|')/g, '\\$1') + '\');'
				);

				res = eval('tpl["' + p[0] + '"](' + p.slice(1) + ')');
				res = res != null ? res.trim() : '';

				assert.equal(
					res,
					results[i]
				);

			} catch (err) {
				var
					header =
						'File: ' + relativeSrc + ' (' + prfx + ')' +
						'\nOptions:\n\n' + options +
						'\n\nTpl: ' + p[0];

				log(header, 'error');

				var report =
					header +
					'\n\n' + line() +
					'\n\nResult:\n' + res +
					'\n\nExpected:\n' + results[i] +
					'\n\n' + line() +
					'\n\nTest:\n' + txt[1] +
					'\n\nCode:\n' + debug['code'];

				fs.writeFileSync(error, report);
				throw err;
			}
		});
	}

	function log(message, type) {
		type = type || 'log';
		console[type](new Date().toString());
		console[type](message);
		console[type](line());
	}

	function line() {
		return new Array(80).join('~');
	}
};

exports.exists = function (src) {
	try {
		fs.statSync(src);
		return true;

	} catch (err) {
		if (err.code === 'ENOENT') {
			return false;
		}

		throw err;
	}
};
<commit_msg>:wrench:<commit_after>/*!
 * Snakeskin
 * https://github.com/SnakeskinTpl/Snakeskin
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/Snakeskin/blob/master/LICENSE
 */

var
	$C = require('collection.js').$C,
	snakeskin = global.Snakeskin = require('../snakeskin');

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

var
	glob = require('glob'),
	mkdirp = require('mkdirp');

var
	from = path.join(__dirname, 'tests'),
	to = path.join(__dirname, 'tmp'),
	error = path.join(__dirname, '../error.tmp');

exports.from = from;
exports.to = to;
exports.error = error;

var
	asserts = [],
	prfx = -1;

exports.run = function (params) {
	var
		options = JSON.stringify(params, null, 2),
		debug = params.debug = {};

	prfx++;
	$C(glob.sync(path.join(from, '*/*.ss'))).forEach(exec);

	function exec(file) {
		try {
			var txt = $C(fs.readFileSync(file, 'utf8').replace(/^\/\*![\s\S]*?\*\//, '').split(/^===.*/m))
				.map(function (el) {
					return el.trim();
				});

			var
				fileName = path.basename(file),
				cat = path.basename(path.dirname(file)),
				chunkSrc = path.join(to, fileName + '_' + prfx + '.' + cat + '.js'),
				relativeSrc = path.relative(process.cwd(), file),
				nms = [cat, path.basename(file, '.ss')];

			console.log('\n###### ' + nms.join('.') + '\n');

			var
				testRgxp = /^\[\[(.*)]]===+$/gm,
				tests = [],
				results = txt[0].split(/^\[\[.*]]===+$/m).slice(1);

			while (testRgxp.exec(txt[0])) {
				tests.push(RegExp.$1);
			}

		} catch (err) {
			log('File: ' + (relativeSrc || file) + '\nError: ' + err.message, 'error');
			return;
		}

		var obj = {
			tpl: txt[1],
			id: path.basename(file, '.ss'),
			js: []
		};

		try {
			var
				start = Date.now(),
				res = snakeskin.compile(txt[1], params, {file: file});

			if (!prfx) {
				log(relativeSrc + ' ' + (Date.now() - start) + 'ms');
			}

			fs.writeFileSync(chunkSrc, res);

			var
				tpl = $C(require(chunkSrc)).get(nms);

		} catch (err) {
			fs.writeFileSync(
				error,
				'File: ' + file + '\n\n' + err.message + (debug['code'] ? '\n\nCode:\n\n' + debug['code'] : '')
			);

			throw err;
		}

		$C(tests).forEach(function (el, i) {
			var
				p = String(el).split(' ; '),
				res = '';

			try {
				results[i] = (results[i] || '').trim();
				obj.js.push(
					'equal(' + p[0] + '(' + p.slice(1) + ').trim(), \'' + results[i].replace(/(\\|')/g, '\\$1') + '\');'
				);

				res = eval('tpl["' + p[0] + '"](' + p.slice(1) + ')');
				res = res != null ? res.trim() : '';

				assert.equal(
					res,
					results[i]
				);

			} catch (err) {
				var
					header =
						'File: ' + relativeSrc + ' (' + prfx + ')' +
						'\nOptions:\n\n' + options +
						'\n\nTpl: ' + p[0];

				log(header, 'error');

				var report =
					header +
					'\n\n' + line() +
					'\n\nResult:\n' + res +
					'\n\nExpected:\n' + results[i] +
					'\n\n' + line() +
					'\n\nTest:\n' + txt[1] +
					'\n\nCode:\n' + debug['code'];

				fs.writeFileSync(error, report);
				throw err;
			}
		});
	}

	function log(message, type) {
		type = type || 'log';
		console[type](new Date().toString());
		console[type](message);
		console[type](line());
	}

	function line() {
		return new Array(80).join('~');
	}
};

exports.exists = function (src) {
	try {
		fs.statSync(src);
		return true;

	} catch (err) {
		if (err.code === 'ENOENT') {
			return false;
		}

		throw err;
	}
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';

class PostsShow extends Component {
	render() {
		return(

				Post Show!

		);
	};
}

export default PostsShow;<commit_msg>Added fetchPost<commit_after>import React, { Component } from 'react';
import {  connect } from 'react-redux';
import { fetchPost } from '../actions';

class PostsShow extends Component {
	componentDidMount() {
		const { id } = this.props.match.param.id;
		this,props.fetchPost(id);
	}

	render() {
		return(

				Post Show!

		);
	}
}

function mapStateToProps({ posts }, ownProps) {
	return { post: posts[ownProps.match.params.id] };
}

export default connect(mapStateToProps, { fetchPost}) (PostsShow);<|endoftext|>


<commit_before>/**
 *  class BabelFish
 *
 *  Internalization and localization library that makes i18n and l10n fun again.
 *
 *  ##### Example
 *
 *      var BabelFish = require('babelfish'),
 *          i18n = new BabelFish();
 **/

'use strict';

var Underscore = require('underscore');
var Parser = require('./babelfish/parser');
var Rules = require('./babelfish/rules');

// helpers
////////////////////////////////////////////////////////////////////////////////

// Last resort locale, that exists for sure
var GENERIC_LOCALE = 'en';

function trim(str) {
  return (str || '').toString().trimLeft().trimRight();
}

// similar to Underscore.filter, but preserves keys of object
function filterObject(obj, iterator) {
  var data = {};

  Underscore.each(obj, function (val, key) {
    if (iterator(val, key)) {
      data[key] = val;
    }
  });

  return data;
}

function parseScope(scope) {
  var chunks, parts = {key: null, chunks: []};

  chunks = scope.split('.');

  // get key and make sure we are not dealing with empty key, e.g. `foo.`
  while (!parts.key && !!chunks.length) {
    parts.key = trim(chunks.pop());
  }

  // empty scope given `` or `.`, or `..` etc.
  if (!parts.key) {
    throw new TypeError('Invalid scope');
  }

  // filter chunks that left
  chunks.forEach(function (chunk) {
    chunk = trim(chunk);
    if (!!chunk) {
      parts.chunks.push(chunk);
    }
  });

  return parts;
}

//  flattenParams(obj) -> Object
//
//  Flattens object into one-level distionary.
//
//  ##### Example
//
//      var obj = {
//        abc: { def: 'foo' },
//        hij: 'bar'
//      };
//
//      flattenParams(obj);
//      // -> { 'abc.def': 'foo', 'hij': 'bar' };
function flattenParams(obj) {
  var params = {};

  Underscore.each(obj || {}, function (val, key) {
    if ('object' === typeof val) {
      Underscore.each(flattenParams(val), function (sub_val, sub_key) {
        params[key + '.' + sub_key] = sub_val;
      });
      return;
    }

    params[key] = val.toString();
  });

  return params;
}

// Compiles given string into translator function. Used to compile phrases,
// which contains `plurals`, `variables`, etc.
function compile(str) {
  var nodes = Parser.parse(str);

  if (1 === nodes.length && 'text' === nodes[0].type) {
    return nodes[0].value;
  }

  return function translator(params) {
    var self = this, str = '';

    params = flattenParams(params || {});

    nodes.forEach(function (node) {
      if ('text' === node.type) {
        str += node.value;
        return;
      }

      if ('variable' === node.type) {
        str += (params[node.anchor] || '<undefined>').toString();
        return;
      }

      if ('plural' === node.type) {
        str += self.pluralize(+params[node.anchor], node.forms);
        return;
      }

      // never should happen
      throw new Error('Unknown node type');
    });

    return str;
  };
}

// Iterator for Underscore.filter to leave non-scopes only
function flatStorageFilter(val) {
  return 'object' !== val.type;
}

// Returns locale storage. Creates one if needed
function getLocaleStorage(self, locale) {
  if (undefined === self._storage[locale]) {
    self._storage[locale] = {};
  }

  return self._storage[locale];
}

function mergeTranslations(receiver, transmitter, locale) {
  Underscore.each(transmitter, function (data, key) {
    // go deeper
    if ('object' === data.type) {
      if (!receiver[key] || 'object' !== receiver[key].type) {
        receiver[key] = {
          type:   'object',
          locale: null,
          value:  {}
        };
      }
      mergeTranslations(receiver[key].value, data.value, locale);
      return;
    }

    // propose translation. make a copy
    if (data.locale === locale) {
      receiver[key] = Underscore.extend({}, data);
    }
  });

  return receiver;
}

// recompiles phrases for locale
function recompile(self, locale) {
  var fallbacks, fb_locale, old_storage, new_storage;

  fallbacks   = (self._fallbacks[locale] || []).slice();
  old_storage = getLocaleStorage(self, locale);
  new_storage = mergeTranslations({}, getLocaleStorage(self, self.defaultLocale), self.defaultLocale);

  // mix-in fallbacks
  while (fallbacks.length) {
    fb_locale = fallbacks.pop();
    mergeTranslations(new_storage, getLocaleStorage(self, fb_locale), fb_locale);
  }

  // mix-in locale overrides
  self._storage[locale] = mergeTranslations(new_storage, old_storage, locale);
}

// public api (module)
////////////////////////////////////////////////////////////////////////////////

/**
 *  new BabelFish([defaultLocale = 'en'])
 *
 *  Initiates new instance of BabelFish. It can't be used as function (without
 *  `new` keyword. Use [[BabelFish.create]] for this purpose.
 **/
function BabelFish(defaultLocale) {
  /** read-only
   *  BabelFish#defaultLocale -> String
   *
   *  Default locale, tht will be used if requested locale has no translation,
   *  and have no fallacks or none of its fallbacks have translation as well.
   **/
  Object.defineProperty(this, 'defaultLocale', {
    value: trim(defaultLocale) || GENERIC_LOCALE
  });

  // hash of locale => [ fallback1, fallback2, ... ] pairs
  this._fallbacks = {};

  // hash of fallback => [ locale1, locale2, ... ] pairs
  this._fallbacksReverse = {};

  // states of compilation per each locale locale => bool pairs
  this._compiled = {};

  // storage of compiled translations
  this._storage = {};
}

/** chainable
 *  BabelFish.create([defaultLocale = 'en']) -> BabelFish
 *
 *  Syntax sugar for constructor:
 *
 *      new BabelFish('ru')
 *      // equals to:
 *      BabelFish.create('ru');
 **/
BabelFish.create = function create(defaultLocale) {
  return new BabelFish(defaultLocale);
};

// public api (instance)
////////////////////////////////////////////////////////////////////////////////

/** chainable
 *  BabelFish#addPhrase(locale, scope, value) -> BabelFish
 *  - locale (String): Locale of translation
 *  - scope (String|Null): Scope of value, e.g. `apps.forum`
 *  - value (String|Object): Value or nested scopes with values.
 *
 *  ##### Errors
 *
 *  - **TypeError** when `value` is neither _String_ nor _Object_.
 *
 *  ##### Example
 *
 *      i18n.addPhrase('ru-RU',
 *        'apps.forums.replies_count',
 *        '#{count} %{ответ|ответа|ответов}:count в теме');
 *
 *      // equals to:
 *      i18n.addPhrase('ru-RU',
 *        'apps.forums',
 *        { replies_count: '#{count} %{ответ|ответа|ответов}:count в теме' });
 **/
BabelFish.prototype.addPhrase = function addPhrase(locale, scope, value) {
  var self = this, t = typeof value, parts, storage, data;

  if ('string' !== t && 'object' !== t && value !== (value || '').toString()) {
    throw new TypeError('Invalid value. String or Object expected');
  } else if ('object' === t) {
    // recursive recursion
    Underscore.each(value, function (value, key) {
      self.addPhrase(locale, scope + '.' + key, value);
    });
    return;
  }

  storage = getLocaleStorage(this, locale);
  parts = parseScope(scope);

  // process inner scope
  parts.chunks.forEach(function (scope_key) {
    if (!storage[scope_key] || 'object' !== storage[scope_key].type) {
      storage[scope_key] = {
        type:   'object',
        locale: null,
        value:  {}
      };
    }

    storage = storage[scope_key].value;
  });

  // prepare data object
  data = storage[parts.key] = {
    type:   null, // will set it below
    locale: locale,
    value:  compile(value)
  };

  // set data type
  data.type = ('function' === typeof data.value) ? 'function' : 'string';

  // mark all "dependant" locales for recompilation
  (self._fallbacksReverse[locale] || []).forEach(function (locale) {
    // we need to recompile non-default locales only
    if (locale !== self.defaultLocale) {
      self._compiled[locale] = false;
    }
  });

  return this;
};

/** chainable
 *  BabelFish#setFallback(locale, fallbacks) -> BabelFish
 *  - locale (String): Target locale
 *  - fallbacks (Array): List of fallback locales
 *
 *  Set fallbacks for given locale.
 *
 *  When `locale` has no translation for the phrase, `fallbacks[0]` will be
 *  tried, if translation still not found, then `fallbacks[1]` will be tried
 *  and so on. If none of fallbacks have translation,
 *  [[BabelFish#defaultLocale]] will be tried as last resort.
 *
 *  ##### Errors
 *
 *  - throws `Error`, when `locale` equals [[BabelFish#defaultLocale]]
 *
 *  ##### Example
 *
 *      i18n.setFallback('ua-UK', ['ua', 'ru']);
 **/
BabelFish.prototype.setFallback = function setFallback(locale, fallbacks) {
  var self = this;

  if (self.defaultLocale === locale) {
    throw new Error("Default locale can't have fallbacks");
  }

  // clear out current fallbacks
  if (!!self._fallbacks[locale]) {
    self._fallbacks[locale].forEach(function (fallback) {
      var idx = self._fallbacksReverse[fallback].indexOf(locale);
      if (-1 !== idx) {
        delete self._fallbacksReverse[fallback][idx];
      }
    });
  }

  // set new empty stack of fallbacks
  self._fallbacks[locale] = [];

  // fill in new fallbacks. defaultLocale is appended as last fallback
  fallbacks.forEach(function (fallback) {
    if (!self._fallbacksReverse[fallback]) {
      self._fallbacksReverse[fallback] = [];
    }

    if (-1 === self._fallbacksReverse[fallback].indexOf(locale)) {
      self._fallbacksReverse[fallback].push(locale);
    }

    self._fallbacks[locale].push(fallback);
  });

  // mark locale for recompilation
  self._compiled[locale] = false;

  return this;
};

/**
 *  BabelFish#translate(locale, scope[, params]) -> String
 *  - locale (String): Locale of translation
 *  - scope (String): Full phrase path, e.g. `app.forums.replies_count`
 *  - params (Object): Params for translation
 *
 *  ##### Example
 *
 *      i18n.addPhrase('ru-RU',
 *        'apps.forums.replies_count',
 *        '#{count} %{ответ|ответа|ответов}:count в теме');
 *
 *      // ...
 *
 *      i18n.translate('ru-RU', 'app.forums.replies_count', {count: 1});
 *      // -> '1 ответ'
 *
 *      i18n.translate('ru-RU', 'app.forums.replies_count', {count: 2});
 *      // -> '2 ответa'
 **/
BabelFish.prototype.translate = function translate(locale, scope, params) {
  var translator = this.getCompiledData(locale, scope);

  if (!translator) {
    return locale + ': No translation for <' + scope + '>';
  }

  switch (translator.type) {
  case 'string':    return translator.value;
  case 'function':  return translator.value.call(this.getRules(locale), params);
  default:          return 'Invalid scope usage: ' + scope;
  }
};

/** alias of: BabelFish#translate
 *  BabelFish#t(locale, scope[, params]) -> String
 **/
BabelFish.prototype.t = BabelFish.prototype.translate;

//  internal
//  BabelFish#getRules(locale) -> Object
//
//  Returns object with pluralizer and other localizators for given locale.
BabelFish.prototype.getRules = function getRules(locale) {
  // TODO: respect given locale fallbacks while choosing rules
  return Rules[locale] || Rules[this.defaultLocale] || Rules[GENERIC_LOCALE];
};

//  internal
//  BabelFish#getCompiledData(locale, scope[, options]) -> Object
//  - locale (String): Locale of translation
//  - scope (String): Full phrase path, e.g. `app.forums.replies_count`
//  - options (Object): Params for translation
//
//  Returns compiled "translator" (if `scope` points phrase) or nested scope
//  of translators. Each value of hash is an object with fields:
//
//  - **type** _(String)_
//    - _string_:     Simple translation (contains no substitutions)
//    - _function_:   Translation with macroses
//    - _object_:     Nested scope of translations
//
//  - **locale** _(String|Null)_
//    Locale of translation. It can differ from requested locale in case when
//    translation was taken from fallback locale.
//    `Null`, when `type` is `object`.
//
//  - **value** _(String|Function|Object)_
//
//
//  ##### Options
//
//  - **deep** _(Boolean, Default: true)_
//    Whenever return nested translations.
BabelFish.prototype.getCompiledData = function getCompiledData(locale, scope, options) {
  var storage, parts;

  // force recompilation if needed
  if (!this._compiled[locale]) {
    recompile(this, locale);
    this._compiled[locale] = true;
  }

  options = options || {};
  storage = getLocaleStorage(this, locale);
  parts = parseScope(scope);

  parts.chunks.forEach(function (scope_key) {
    if (storage && storage[scope_key] && 'object' === storage[scope_key].type) {
      storage = storage[scope_key].value;
      return;
    }

    // skip any further searchings
    storage = null;
  });

  // unknown translation
  if (!storage || !storage[parts.key]) {
    return null;
  }

  // if we got translation, or scope and deep copy requested,
  // return copy of the object from storage
  if ('object' !== storage[parts.key].type || false !== options.deep) {
    return Underscore.extend({}, storage[parts.key]);
  }

  // we got scope and return flat copy of storage is requested
  return {
    type: 'object',
    locale: null,
    value: filterObject(storage[parts.key].value, flatStorageFilter)
  };
};

// export module
module.exports = BabelFish;
<commit_msg>Made compiled function serializable<commit_after>/**
 *  class BabelFish
 *
 *  Internalization and localization library that makes i18n and l10n fun again.
 *
 *  ##### Example
 *
 *      var BabelFish = require('babelfish'),
 *          i18n = new BabelFish();
 **/

'use strict';

var Underscore = require('underscore');
var Parser = require('./babelfish/parser');
var Rules = require('./babelfish/rules');

// helpers
////////////////////////////////////////////////////////////////////////////////

// Last resort locale, that exists for sure
var GENERIC_LOCALE = 'en';

function trim(str) {
  return (str || '').toString().trimLeft().trimRight();
}

// similar to Underscore.filter, but preserves keys of object
function filterObject(obj, iterator) {
  var data = {};

  Underscore.each(obj, function (val, key) {
    if (iterator(val, key)) {
      data[key] = val;
    }
  });

  return data;
}

function parseScope(scope) {
  var chunks, parts = {key: null, chunks: []};

  chunks = scope.split('.');

  // get key and make sure we are not dealing with empty key, e.g. `foo.`
  while (!parts.key && !!chunks.length) {
    parts.key = trim(chunks.pop());
  }

  // empty scope given `` or `.`, or `..` etc.
  if (!parts.key) {
    throw new TypeError('Invalid scope');
  }

  // filter chunks that left
  chunks.forEach(function (chunk) {
    chunk = trim(chunk);
    if (!!chunk) {
      parts.chunks.push(chunk);
    }
  });

  return parts;
}

//  flattenParams(obj) -> Object
//
//  Flattens object into one-level distionary.
//
//  ##### Example
//
//      var obj = {
//        abc: { def: 'foo' },
//        hij: 'bar'
//      };
//
//      flattenParams(obj);
//      // -> { 'abc.def': 'foo', 'hij': 'bar' };
function flattenParams(obj) {
  var params = {};

  Underscore.each(obj || {}, function (val, key) {
    if ('object' === typeof val) {
      Underscore.each(flattenParams(val), function (sub_val, sub_key) {
        params[key + '.' + sub_key] = sub_val;
      });
      return;
    }

    params[key] = val.toString();
  });

  return params;
}

// Compiles given string into translator function. Used to compile phrases,
// which contains `plurals`, `variables`, etc.
function compile(str) {
  var nodes = Parser.parse(str), translator;

  if (1 === nodes.length && 'text' === nodes[0].type) {
    return nodes[0].value;
  }

  translator = ["var ctx = this, str = '', nodes;"];
  translator.push("nodes = " + JSON.stringify(nodes) + ";");
  translator.push("params = ctx.flattenParams(params);");
  translator.push("ctx.each(nodes, function (node) {");
  translator.push("  if ('text' === node.type) {");
  translator.push("    str += node.value;");
  translator.push("    return; }");
  translator.push("  if ('variable' === node.type) {");
  translator.push("    str += (params[node.anchor] || '<undefined>').toString();");
  translator.push("    return; }");
  translator.push("  if ('plural' === node.type) {");
  translator.push("    str += ctx.pluralize(+params[node.anchor], node.forms);");
  translator.push("    return; }");
  translator.push("  throw new Error('Unknown node type'); });");
  translator.push("return str;");

  /*jslint evil:true*/
  return new Function('params', translator.join('\n'));
}

// Iterator for Underscore.filter to leave non-scopes only
function flatStorageFilter(val) {
  return 'object' !== val.type;
}

// Returns locale storage. Creates one if needed
function getLocaleStorage(self, locale) {
  if (undefined === self._storage[locale]) {
    self._storage[locale] = {};
  }

  return self._storage[locale];
}

function mergeTranslations(receiver, transmitter, locale) {
  Underscore.each(transmitter, function (data, key) {
    // go deeper
    if ('object' === data.type) {
      if (!receiver[key] || 'object' !== receiver[key].type) {
        receiver[key] = {
          type:   'object',
          locale: null,
          value:  {}
        };
      }
      mergeTranslations(receiver[key].value, data.value, locale);
      return;
    }

    // propose translation. make a copy
    if (data.locale === locale) {
      receiver[key] = Underscore.extend({}, data);
    }
  });

  return receiver;
}

// recompiles phrases for locale
function recompile(self, locale) {
  var fallbacks, fb_locale, old_storage, new_storage;

  fallbacks   = (self._fallbacks[locale] || []).slice();
  old_storage = getLocaleStorage(self, locale);
  new_storage = mergeTranslations({}, getLocaleStorage(self, self.defaultLocale), self.defaultLocale);

  // mix-in fallbacks
  while (fallbacks.length) {
    fb_locale = fallbacks.pop();
    mergeTranslations(new_storage, getLocaleStorage(self, fb_locale), fb_locale);
  }

  // mix-in locale overrides
  self._storage[locale] = mergeTranslations(new_storage, old_storage, locale);
}

// public api (module)
////////////////////////////////////////////////////////////////////////////////

/**
 *  new BabelFish([defaultLocale = 'en'])
 *
 *  Initiates new instance of BabelFish. It can't be used as function (without
 *  `new` keyword. Use [[BabelFish.create]] for this purpose.
 **/
function BabelFish(defaultLocale) {
  /** read-only
   *  BabelFish#defaultLocale -> String
   *
   *  Default locale, tht will be used if requested locale has no translation,
   *  and have no fallacks or none of its fallbacks have translation as well.
   **/
  Object.defineProperty(this, 'defaultLocale', {
    value: trim(defaultLocale) || GENERIC_LOCALE
  });

  // hash of locale => [ fallback1, fallback2, ... ] pairs
  this._fallbacks = {};

  // hash of fallback => [ locale1, locale2, ... ] pairs
  this._fallbacksReverse = {};

  // states of compilation per each locale locale => bool pairs
  this._compiled = {};

  // storage of compiled translations
  this._storage = {};
}

/** chainable
 *  BabelFish.create([defaultLocale = 'en']) -> BabelFish
 *
 *  Syntax sugar for constructor:
 *
 *      new BabelFish('ru')
 *      // equals to:
 *      BabelFish.create('ru');
 **/
BabelFish.create = function create(defaultLocale) {
  return new BabelFish(defaultLocale);
};

// public api (instance)
////////////////////////////////////////////////////////////////////////////////

/** chainable
 *  BabelFish#addPhrase(locale, scope, value) -> BabelFish
 *  - locale (String): Locale of translation
 *  - scope (String|Null): Scope of value, e.g. `apps.forum`
 *  - value (String|Object): Value or nested scopes with values.
 *
 *  ##### Errors
 *
 *  - **TypeError** when `value` is neither _String_ nor _Object_.
 *
 *  ##### Example
 *
 *      i18n.addPhrase('ru-RU',
 *        'apps.forums.replies_count',
 *        '#{count} %{ответ|ответа|ответов}:count в теме');
 *
 *      // equals to:
 *      i18n.addPhrase('ru-RU',
 *        'apps.forums',
 *        { replies_count: '#{count} %{ответ|ответа|ответов}:count в теме' });
 **/
BabelFish.prototype.addPhrase = function addPhrase(locale, scope, value) {
  var self = this, t = typeof value, parts, storage, data;

  if ('string' !== t && 'object' !== t && value !== (value || '').toString()) {
    throw new TypeError('Invalid value. String or Object expected');
  } else if ('object' === t) {
    // recursive recursion
    Underscore.each(value, function (value, key) {
      self.addPhrase(locale, scope + '.' + key, value);
    });
    return;
  }

  storage = getLocaleStorage(this, locale);
  parts = parseScope(scope);

  // process inner scope
  parts.chunks.forEach(function (scope_key) {
    if (!storage[scope_key] || 'object' !== storage[scope_key].type) {
      storage[scope_key] = {
        type:   'object',
        locale: null,
        value:  {}
      };
    }

    storage = storage[scope_key].value;
  });

  // prepare data object
  data = storage[parts.key] = {
    type:   null, // will set it below
    locale: locale,
    value:  compile(value)
  };

  // set data type
  data.type = ('function' === typeof data.value) ? 'function' : 'string';

  // mark all "dependant" locales for recompilation
  (self._fallbacksReverse[locale] || []).forEach(function (locale) {
    // we need to recompile non-default locales only
    if (locale !== self.defaultLocale) {
      self._compiled[locale] = false;
    }
  });

  return this;
};

/** chainable
 *  BabelFish#setFallback(locale, fallbacks) -> BabelFish
 *  - locale (String): Target locale
 *  - fallbacks (Array): List of fallback locales
 *
 *  Set fallbacks for given locale.
 *
 *  When `locale` has no translation for the phrase, `fallbacks[0]` will be
 *  tried, if translation still not found, then `fallbacks[1]` will be tried
 *  and so on. If none of fallbacks have translation,
 *  [[BabelFish#defaultLocale]] will be tried as last resort.
 *
 *  ##### Errors
 *
 *  - throws `Error`, when `locale` equals [[BabelFish#defaultLocale]]
 *
 *  ##### Example
 *
 *      i18n.setFallback('ua-UK', ['ua', 'ru']);
 **/
BabelFish.prototype.setFallback = function setFallback(locale, fallbacks) {
  var self = this;

  if (self.defaultLocale === locale) {
    throw new Error("Default locale can't have fallbacks");
  }

  // clear out current fallbacks
  if (!!self._fallbacks[locale]) {
    self._fallbacks[locale].forEach(function (fallback) {
      var idx = self._fallbacksReverse[fallback].indexOf(locale);
      if (-1 !== idx) {
        delete self._fallbacksReverse[fallback][idx];
      }
    });
  }

  // set new empty stack of fallbacks
  self._fallbacks[locale] = [];

  // fill in new fallbacks. defaultLocale is appended as last fallback
  fallbacks.forEach(function (fallback) {
    if (!self._fallbacksReverse[fallback]) {
      self._fallbacksReverse[fallback] = [];
    }

    if (-1 === self._fallbacksReverse[fallback].indexOf(locale)) {
      self._fallbacksReverse[fallback].push(locale);
    }

    self._fallbacks[locale].push(fallback);
  });

  // mark locale for recompilation
  self._compiled[locale] = false;

  return this;
};

/**
 *  BabelFish#translate(locale, scope[, params]) -> String
 *  - locale (String): Locale of translation
 *  - scope (String): Full phrase path, e.g. `app.forums.replies_count`
 *  - params (Object): Params for translation
 *
 *  ##### Example
 *
 *      i18n.addPhrase('ru-RU',
 *        'apps.forums.replies_count',
 *        '#{count} %{ответ|ответа|ответов}:count в теме');
 *
 *      // ...
 *
 *      i18n.translate('ru-RU', 'app.forums.replies_count', {count: 1});
 *      // -> '1 ответ'
 *
 *      i18n.translate('ru-RU', 'app.forums.replies_count', {count: 2});
 *      // -> '2 ответa'
 **/
BabelFish.prototype.translate = function translate(locale, scope, params) {
  var translator = this.getCompiledData(locale, scope);

  if (!translator) {
    return locale + ': No translation for <' + scope + '>';
  }

  switch (translator.type) {
  case 'string':    return translator.value;
  case 'function':  return translator.value.call(this.getContext(locale), params);
  default:          return 'Invalid scope usage: ' + scope;
  }
};

/** alias of: BabelFish#translate
 *  BabelFish#t(locale, scope[, params]) -> String
 **/
BabelFish.prototype.t = BabelFish.prototype.translate;

//  internal
//  BabelFish#getContext(locale) -> Object
//
//  Returns object with pluralize, flattenParams, and each methods.
//  Client-side should call compled function with similar object.
BabelFish.prototype.getContext = function getContext(locale) {
  return {
    each: Underscore.each,
    flattenParams: flattenParams,
    pluralize: this.getPluralizer(locale)
  };
};

BabelFish.prototype.getPluralizer = function getPluralizer(locale) {
  // TODO: respect given locale fallbacks while choosing pluralizer
  return (Rules[locale] || Rules[this.defaultLocale] || Rules[GENERIC_LOCALE]).pluralize;
};

//  internal
//  BabelFish#getCompiledData(locale, scope[, options]) -> Object
//  - locale (String): Locale of translation
//  - scope (String): Full phrase path, e.g. `app.forums.replies_count`
//  - options (Object): Params for translation
//
//  Returns compiled "translator" (if `scope` points phrase) or nested scope
//  of translators. Each value of hash is an object with fields:
//
//  - **type** _(String)_
//    - _string_:     Simple translation (contains no substitutions)
//    - _function_:   Translation with macroses
//    - _object_:     Nested scope of translations
//
//  - **locale** _(String|Null)_
//    Locale of translation. It can differ from requested locale in case when
//    translation was taken from fallback locale.
//    `Null`, when `type` is `object`.
//
//  - **value** _(String|Function|Object)_
//
//
//  ##### Options
//
//  - **deep** _(Boolean, Default: true)_
//    Whenever return nested translations.
BabelFish.prototype.getCompiledData = function getCompiledData(locale, scope, options) {
  var storage, parts;

  // force recompilation if needed
  if (!this._compiled[locale]) {
    recompile(this, locale);
    this._compiled[locale] = true;
  }

  options = options || {};
  storage = getLocaleStorage(this, locale);
  parts = parseScope(scope);

  parts.chunks.forEach(function (scope_key) {
    if (storage && storage[scope_key] && 'object' === storage[scope_key].type) {
      storage = storage[scope_key].value;
      return;
    }

    // skip any further searchings
    storage = null;
  });

  // unknown translation
  if (!storage || !storage[parts.key]) {
    return null;
  }

  // if we got translation, or scope and deep copy requested,
  // return copy of the object from storage
  if ('object' !== storage[parts.key].type || false !== options.deep) {
    return Underscore.extend({}, storage[parts.key]);
  }

  // we got scope and return flat copy of storage is requested
  return {
    type: 'object',
    locale: null,
    value: filterObject(storage[parts.key].value, flatStorageFilter)
  };
};

// export module
module.exports = BabelFish;
<|endoftext|>


<commit_before>Meteor.publish(null, function() {
  if(this.userId) {
    var self = this;
    var query = Meteor.users.find(
      {_id: this.userId},
      {fields: {
                  emails: 1,
                  'services.facebook.email': 1,
                  'services.google.email': 1,
                  'services.github.email': 1 }});

    Mongo.Collection._publishCursor(query, self, 'analyticsusers');
    return self.ready();

  } else {
    this.ready();
  }
});
<commit_msg>added eslint global to publications.js<commit_after>/* global Meteor */
/* global Mongo */

Meteor.publish(null, function() {
  if(this.userId) {
    var self = this;
    var query = Meteor.users.find(
      {_id: this.userId},
      {fields: {
                  emails: 1,
                  'services.facebook.email': 1,
                  'services.google.email': 1,
                  'services.github.email': 1 }});

    Mongo.Collection._publishCursor(query, self, 'analyticsusers');
    return self.ready();

  } else {
    this.ready();
  }
});
<|endoftext|>


<commit_before>var EntityService;
(function ($, _, Backbone, Marionette, App, EntityLayoutView, headerTemplate, EventAggregator) {
    EntityService = Marionette.EntityService = (function () {

        var ctor = function () {

        };

        ctor.initialize = function (options) {
            _.extend(this, options);

            this._entityLayoutView = null;
            var self = this;

            if (!_.isUndefined(options.allowableOperations)) {
                this.allowableOperations = options.allowableOperations;
            } else {
                this.allowableOperations = ['create', 'delete', 'edit', 'delete-all', 'publish-all', 'view-live'];
            }

            if (_.isUndefined(options.routing)) {
                this.routing = true;
            }

            if (_.isUndefined(this.entityLayoutViewType)) {
                this.entityLayoutViewType = EntityLayoutView;
            }

            if (_.isUndefined(this.baseClassIds)) {
                this.baseClassIds = [];
            }

            if (_.isUndefined(this.track)) {
                this.track = true;
            }

            if (!_.isUndefined(this.header)) {
                this.getHeader = function () {
                    return this.header;
                }
            }

            EventAggregator.on(this.route + '.create', function () {
                self.create();
            });

            EventAggregator.on(this.route + '.edit', function (id) {
                self.edit(id);
            });

            EventAggregator.on(this.route + '.delete', function (id) {
                self.delete(id);
            });

            EventAggregator.on(this.route + '.getAll', function (page, force) {
                self.getAll(page, force);
            });

            EventAggregator.on(this.route + '.getType', function (page, force) {
                self.getType(page, force);
            });

            EventAggregator.on(this.route + '.textSearch', function (startsWith, field) {
                self.textSearch(startsWith, field);
            });

            EventAggregator.on(this.route + '.destroy', function () {
                self.destroy();
            });
        };

        ctor.destroy = function () {
            EventAggregator.off(this.route + '.create');
            EventAggregator.off(this.route + '.edit');
            EventAggregator.off(this.route + '.delete');
            EventAggregator.off(this.route + '.getAll');
            EventAggregator.off(this.route + '.getType');
            EventAggregator.off(this.route + '.textSearch');
            EventAggregator.off(this.route + '.destroy');
        };

        ctor.entityLayoutView =
            function (entities) {
                if (_.isNull(this._entityLayoutView) || this._entityLayoutView.isDestroyed()) {
                    this._entityLayoutView = this.getEntityLayoutView(entities);
                }

                return this._entityLayoutView;
            };

        ctor.getEntityLayoutView = function (entities) {
            var listView =
                new this.listView
                ({
                    collection: entities === undefined ? this.collection : entities,
                    baseClassIds: this.baseClassIds
                });

            listView.currentPage = entities === undefined ? 1 : entities.currentPage;

            return new this.entityLayoutViewType
            ({
                allowableOperations: this.allowableOperations,
                route: this.route,
                listView: listView,
                header: this.getHeader(),
                model: new Backbone.Model(),
                btnClass: this.getBtnClass(),
                routing: this.routing
            });
        };

        ctor.getHeader = function () {
            return {params: {title: this.title}, template: headerTemplate};
        };

        ctor.getBtnClass = function () {
            return '';
        };

        ctor.getNewModel = function () {
            return new this.model();
        };

        ctor.getFormOptions = function () {
            return {};
        };

        ctor.create = function () {
            var entity = this.getNewModel();
            App.currentRoute = 'create';

            if (this.region.currentView !== this.entityLayoutView()) {
                this.region.show(this.entityLayoutView());
            }

            var form = new this.formView
            ({
                model: entity,
                collection: this._entityLayoutView.listView.collection,
                parentViewCid: this.entityLayoutView().cid,
                btnClass: this.getBtnClass(),
                formOptions: this.getFormOptions()
            });

            this.entityLayoutView().showChildView('entityRegion', form);
        };

        ctor.edit = function (id) {
            App.currentRoute = 'edit';

            if (this.region.currentView !== this.entityLayoutView()) {
                this.region.show(this.entityLayoutView());
            }

            this.collection.getById(id)
                .done(_.bind(function (entity) {
                    var form = new this.formView
                    ({
                        model: entity,
                        collection: this._entityLayoutView.listView.collection,
                        parentViewCid: this.entityLayoutView().cid,
                        btnClass: this.getBtnClass(),
                        formOptions: this.getFormOptions()
                    });

                    this.entityLayoutView().showChildView('entityRegion', form);
                }, this));
        };

        ctor.delete = function (id) {
            var self = this;

            if (this.region.currentView !== this.entityLayoutView()) {
                this.region.show(this.entityLayoutView());
            }

            this.collection.getById(id)
                .done(function (entityToDelete) {
                    entityToDelete.destroy({
                        type: "DELETE",
                        contentType: "application/json; charset=utf-8",
                        dataType: "json",
                        url: entityToDelete.url + '/' + id,
                        success: function (response) {
                            console.log("Inside success");
                            console.log(response);

                            var currentCollection = self.entityLayoutView().listView.collection;
                            currentCollection.remove(id);

                            self.entityLayoutView().triggerMethod("ShowPager", currentCollection);
                        },
                        error: function (errorResponse) {
                            console.log("Inside Failure");
                            console.log(errorResponse.responseText);
                        }
                    });
                });
        };

        ctor.textSearch = function (startsWith, field) {
            var data = {
                    conditions: [
                        {
                            searchType: 'like',
                            field: field,
                            value: startsWith
                        }
                    ],
                    page: 1,
                    pageSize: window.pageSize
                },
                self = this;

            this.collection.query(this.track, data)
                .done(_.bind(function (entities, key) {
                    var models = null;

                    if (_.isUndefined(entities.child)) {
                        models = entities;
                    } else {
                        models = entities.child;
                    }

                    var listView =
                        new this.listView
                        ({
                            collection: models,
                            parentViewCid: this.entityLayoutView().cid,
                            baseClassIds: this.baseClassIds
                        });

                    listView.route = this.route;
                    listView.allowableOperations = this.allowableOperations;

                    this.entityLayoutView().key = key;
                    EventAggregator.trigger(self.route + '.subcollection', models);
                    this.entityLayoutView().showChildView('entityRegion', listView);
                }, this));
        };

        ctor.getAll = function (page, force) {
            var self = this;

            if (isNaN(page)) {
                page = 0;
            }

            var data = this.getData(page);

            this.collection.query(this.track, data, force)
                .done(function (entities, key) {
                    var models = null;

                    if (_.isUndefined(entities.child)) {
                        models = entities;
                    } else {
                        models = entities.child;
                    }

                    var listView =
                        new self.listView
                        ({
                            collection: models,
                            parentViewCid: self.entityLayoutView().cid,
                            baseClassIds: self.baseClassIds
                        });

                    listView.currentPage = page;
                    listView.route = self.route;
                    listView.allowableOperations = self.allowableOperations;

                    self.entityLayoutView().key = key;
                    self.entityLayoutView().listView = listView;

                    EventAggregator.trigger(self.route + '.subcollection', models);
                    self.entityLayoutView().showChildView('entityRegion', listView);
                });
        };

        ctor.getType = function (page, force) {
            var self = this;

            if (isNaN(page)) {
                page = 0;
            }

            if (this.region.currentView === this._entityLayoutView) {
                this.getAll(page);
                return;
            }

            var data = this.getData(page);

            this.collection.query(this.track, data, force)
                .done(function (entities, key) {
                    var models = null;

                    if (_.isUndefined(entities.child)) {
                        models = entities;
                    } else {
                        models = entities.child;
                    }

                    self.region.reset();
                    models.currentPage = page;

                    EventAggregator.trigger(self.route + '.subcollection', models);
                    var entityLayoutView = self.entityLayoutView(models);
                    entityLayoutView.key = key;

                    self.region.show(entityLayoutView);
                });
        };

        ctor.getData = function (page) {
            return {
                page: parseInt(page),
                pageSize: parseInt(window.pageSize)
            };
        };

        //set the context for all of the functions
        for (var key in ctor) {
            if (typeof(ctor[key]) === "function") {
                _.bind(ctor[key], ctor);
            }
        }

        return ctor;
    });
})(jQuery, _, Backbone, Marionette, App, EntityLayoutView, this['EntityView']['Templates']['./templates/headerTemplate.html'], EventAggregator);
<commit_msg>changing service definition to marionette object<commit_after>var EntityService;
(function ($, _, Backbone, Marionette, App, EntityLayoutView, headerTemplate, EventAggregator) {
    EntityService = Marionette.EntityService = Marionette.Object.extend({
        initialize: function (options) {
            _.extend(this, options);

            this._entityLayoutView = null;
            var self = this;

            if (!_.isUndefined(options.allowableOperations)) {
                this.allowableOperations = options.allowableOperations;
            } else {
                this.allowableOperations = ['create', 'delete', 'edit', 'delete-all', 'publish-all', 'view-live'];
            }

            if (_.isUndefined(options.routing)) {
                this.routing = true;
            }

            if (_.isUndefined(this.entityLayoutViewType)) {
                this.entityLayoutViewType = EntityLayoutView;
            }

            if (_.isUndefined(this.baseClassIds)) {
                this.baseClassIds = [];
            }

            if (_.isUndefined(this.track)) {
                this.track = true;
            }

            if (!_.isUndefined(this.header)) {
                this.getHeader = function () {
                    return this.header;
                }
            }

            EventAggregator.on(this.route + '.create', function () {
                self.create();
            });

            EventAggregator.on(this.route + '.edit', function (id) {
                self.edit(id);
            });

            EventAggregator.on(this.route + '.delete', function (id) {
                self.delete(id);
            });

            EventAggregator.on(this.route + '.getAll', function (page, force) {
                self.getAll(page, force);
            });

            EventAggregator.on(this.route + '.getType', function (page, force) {
                self.getType(page, force);
            });

            EventAggregator.on(this.route + '.textSearch', function (startsWith, field) {
                self.textSearch(startsWith, field);
            });

            EventAggregator.on(this.route + '.destroy', function () {
                self.destroy();
            });
        },
        destroy: function () {
            EventAggregator.off(this.route + '.create');
            EventAggregator.off(this.route + '.edit');
            EventAggregator.off(this.route + '.delete');
            EventAggregator.off(this.route + '.getAll');
            EventAggregator.off(this.route + '.getType');
            EventAggregator.off(this.route + '.textSearch');
            EventAggregator.off(this.route + '.destroy');
        },
        entityLayoutView: function (entities) {
            if (_.isNull(this._entityLayoutView) || this._entityLayoutView.isDestroyed()) {
                this._entityLayoutView = this.getEntityLayoutView(entities);
            }

            return this._entityLayoutView;
        },
        getEntityLayoutView: function (entities) {
            var listView =
                new this.listView
                ({
                    collection: entities === undefined ? this.collection : entities,
                    baseClassIds: this.baseClassIds
                });

            listView.currentPage = entities === undefined ? 1 : entities.currentPage;

            return new this.entityLayoutViewType
            ({
                allowableOperations: this.allowableOperations,
                route: this.route,
                listView: listView,
                header: this.getHeader(),
                model: new Backbone.Model(),
                btnClass: this.getBtnClass(),
                routing: this.routing
            });
        },
        getHeader: function () {
            return {params: {title: this.title}, template: headerTemplate};
        },
        getBtnClass: function () {
            return '';
        },
        getNewModel: function () {
            return new this.model();
        },
        getFormOptions: function () {
            return {};
        },
        create: function () {
            var entity = this.getNewModel();
            App.currentRoute = 'create';

            if (this.region.currentView !== this.entityLayoutView()) {
                this.region.show(this.entityLayoutView());
            }

            var form = new this.formView
            ({
                model: entity,
                collection: this._entityLayoutView.listView.collection,
                parentViewCid: this.entityLayoutView().cid,
                btnClass: this.getBtnClass(),
                formOptions: this.getFormOptions()
            });

            this.entityLayoutView().showChildView('entityRegion', form);
        },
        edit: function () {
            App.currentRoute = 'edit';

            if (this.region.currentView !== this.entityLayoutView()) {
                this.region.show(this.entityLayoutView());
            }

            this.collection.getById(id)
                .done(_.bind(function (entity) {
                    var form = new this.formView
                    ({
                        model: entity,
                        collection: this._entityLayoutView.listView.collection,
                        parentViewCid: this.entityLayoutView().cid,
                        btnClass: this.getBtnClass(),
                        formOptions: this.getFormOptions()
                    });

                    this.entityLayoutView().showChildView('entityRegion', form);
                }, this));
        },
        delete: function () {
            var self = this;

            if (this.region.currentView !== this.entityLayoutView()) {
                this.region.show(this.entityLayoutView());
            }

            this.collection.getById(id)
                .done(function (entityToDelete) {
                    entityToDelete.destroy({
                        type: "DELETE",
                        contentType: "application/json; charset=utf-8",
                        dataType: "json",
                        url: entityToDelete.url + '/' + id,
                        success: function (response) {
                            console.log("Inside success");
                            console.log(response);

                            var currentCollection = self.entityLayoutView().listView.collection;
                            currentCollection.remove(id);

                            self.entityLayoutView().triggerMethod("ShowPager", currentCollection);
                        },
                        error: function (errorResponse) {
                            console.log("Inside Failure");
                            console.log(errorResponse.responseText);
                        }
                    });
                });
        },
        textSearch: function (startsWith, field) {
            var data = {
                    conditions: [
                        {
                            searchType: 'like',
                            field: field,
                            value: startsWith
                        }
                    ],
                    page: 1,
                    pageSize: window.pageSize
                },
                self = this;

            this.collection.query(this.track, data)
                .done(_.bind(function (entities, key) {
                    var models = null;

                    if (_.isUndefined(entities.child)) {
                        models = entities;
                    } else {
                        models = entities.child;
                    }

                    var listView =
                        new this.listView
                        ({
                            collection: models,
                            parentViewCid: this.entityLayoutView().cid,
                            baseClassIds: this.baseClassIds
                        });

                    listView.route = this.route;
                    listView.allowableOperations = this.allowableOperations;

                    this.entityLayoutView().key = key;
                    EventAggregator.trigger(self.route + '.subcollection', models);
                    this.entityLayoutView().showChildView('entityRegion', listView);
                }, this));
        },
        getAll: function (page, force) {
            var self = this;

            if (isNaN(page)) {
                page = 0;
            }

            var data = this.getData(page);

            this.collection.query(this.track, data, force)
                .done(function (entities, key) {
                    var models = null;

                    if (_.isUndefined(entities.child)) {
                        models = entities;
                    } else {
                        models = entities.child;
                    }

                    var listView =
                        new self.listView
                        ({
                            collection: models,
                            parentViewCid: self.entityLayoutView().cid,
                            baseClassIds: self.baseClassIds
                        });

                    listView.currentPage = page;
                    listView.route = self.route;
                    listView.allowableOperations = self.allowableOperations;

                    self.entityLayoutView().key = key;
                    self.entityLayoutView().listView = listView;

                    EventAggregator.trigger(self.route + '.subcollection', models);
                    self.entityLayoutView().showChildView('entityRegion', listView);
                });
        },
        getType: function (page, force) {
            var self = this;

            if (isNaN(page)) {
                page = 0;
            }

            if (this.region.currentView === this._entityLayoutView) {
                this.getAll(page);
                return;
            }

            var data = this.getData(page);

            this.collection.query(this.track, data, force)
                .done(function (entities, key) {
                    var models = null;

                    if (_.isUndefined(entities.child)) {
                        models = entities;
                    } else {
                        models = entities.child;
                    }

                    self.region.reset();
                    models.currentPage = page;

                    EventAggregator.trigger(self.route + '.subcollection', models);
                    var entityLayoutView = self.entityLayoutView(models);
                    entityLayoutView.key = key;

                    self.region.show(entityLayoutView);
                });
        },
        getData: function (page) {
            return {
                page: parseInt(page),
                pageSize: parseInt(window.pageSize)
            };
        }
    });
})(jQuery, _, Backbone, Marionette, App, EntityLayoutView, this['Templates']['headerTemplate'], EventAggregator);
<|endoftext|>


<commit_before>describe("SwappingRouter", function() {
  var historyStarted = false;

  var redView = Backbone.View.extend({
    render: function() {
      $(this.el).text("Red!");
    }
  });

  var blueView = Backbone.View.extend({
    render: function() {
      $(this.el).text("Blue!");
    }
  });

  var leaveView = Backbone.View.extend({
    leave: function() {
    }
  });
  var leaveViewInstance = new leaveView();

  var routerSubclass = Support.SwappingRouter.extend({
    routes: {
      "test": "index",
      "red": "red",
      "blue": "blue",
      "leave": "leave"
    },

    index: function() {
    },

    red: function() {
      this.swap(new redView());
    },

    blue: function() {
      this.swap(new blueView());
    },

    leave: function() {
      this.swap(leaveViewInstance);
    }
  });
  var router = new routerSubclass({});

  beforeEach(function() {
    Helpers.setup();

    if(!historyStarted) {
      historyStarted = true;
      Backbone.history.start();
    }
    router.el = "#test";
  });

  afterEach(function() {
    Helpers.teardown();
  });

  it("should be a backbone router", function() {
    var spy = sinon.spy();
    router.bind("route:index", spy);

    runs(function() {
      window.location.hash = "#test"
    });

    Helpers.sleep();

    runs(function() {
      expect(spy.called).toBeTruthy();
    });
  });

  it("renders and swaps backbone views", function() {
    runs(function() {
      window.location.hash = "#red"
    });

    Helpers.sleep();

    runs(function() {
      expect($("#test").text()).toEqual("Red!");
    });

    Helpers.sleep();

    runs(function() {
      window.location.hash = "#blue"
    });

    Helpers.sleep();

    runs(function() {
      expect($("#test").text()).toEqual("Blue!");
    });
  });

  it("calls leave if it exists on a view", function() {
    var spy = sinon.spy(leaveViewInstance, "leave");

    runs(function() {
      window.location.hash = "#leave"
    });

    Helpers.sleep();

    runs(function() {
      window.location.hash = "#red"
    });

    Helpers.sleep();

    runs(function() {
      expect($("#test").text()).toEqual("Red!");
      expect(spy.called).toBeTruthy();
    });
  });
});
<commit_msg>name router describe properly<commit_after>describe("Support.SwappingRouter", function() {
  var historyStarted = false;

  var redView = Backbone.View.extend({
    render: function() {
      $(this.el).text("Red!");
    }
  });

  var blueView = Backbone.View.extend({
    render: function() {
      $(this.el).text("Blue!");
    }
  });

  var leaveView = Backbone.View.extend({
    leave: function() {
    }
  });
  var leaveViewInstance = new leaveView();

  var routerSubclass = Support.SwappingRouter.extend({
    routes: {
      "test": "index",
      "red": "red",
      "blue": "blue",
      "leave": "leave"
    },

    index: function() {
    },

    red: function() {
      this.swap(new redView());
    },

    blue: function() {
      this.swap(new blueView());
    },

    leave: function() {
      this.swap(leaveViewInstance);
    }
  });
  var router = new routerSubclass({});

  beforeEach(function() {
    Helpers.setup();

    if(!historyStarted) {
      historyStarted = true;
      Backbone.history.start();
    }
    router.el = "#test";
  });

  afterEach(function() {
    Helpers.teardown();
  });

  it("should be a backbone router", function() {
    var spy = sinon.spy();
    router.bind("route:index", spy);

    runs(function() {
      window.location.hash = "#test"
    });

    Helpers.sleep();

    runs(function() {
      expect(spy.called).toBeTruthy();
    });
  });

  it("renders and swaps backbone views", function() {
    runs(function() {
      window.location.hash = "#red"
    });

    Helpers.sleep();

    runs(function() {
      expect($("#test").text()).toEqual("Red!");
    });

    Helpers.sleep();

    runs(function() {
      window.location.hash = "#blue"
    });

    Helpers.sleep();

    runs(function() {
      expect($("#test").text()).toEqual("Blue!");
    });
  });

  it("calls leave if it exists on a view", function() {
    var spy = sinon.spy(leaveViewInstance, "leave");

    runs(function() {
      window.location.hash = "#leave"
    });

    Helpers.sleep();

    runs(function() {
      window.location.hash = "#red"
    });

    Helpers.sleep();

    runs(function() {
      expect($("#test").text()).toEqual("Red!");
      expect(spy.called).toBeTruthy();
    });
  });
});
<|endoftext|>


<commit_before>(function($) {
    $.fn.excerptize = function(options) {
            var defaults = {
                numberOfCharacters: 100,
                cutOffAtWord: true,
                tags: 'span',
                showMoreText: '[...]',
                showLessText: 'less'
            };

            options = $.extend(defaults, options);

            $(this).each(function(){
                var excerptizedObj = $(this),
                fullText = excerptizedObj.text(),
                excerpt = fullText.substr(0, options.numberOfCharacters),
                excerptized = '';

	            // if full text is less than or equal to excerpt, don't bother
	            if(fullText.length<=options.numberOfCharacters) {
	                return;
	            }

	            if(options.cutOffAtWord) {
	                excerpt = excerpt.substr(0, Math.min(excerpt.length, excerpt.lastIndexOf(" ")))
	            }

	            excerptizedObj.html(getExcerptized(excerpt, fullText, options));
	            bindControls(excerptizedObj);

	            // To avoid the flicker when page first loads,
	            // you can make the 'excerptized' element hidden.
	            // This will ensure excerpt is displayed.
	            excerptizedObj.show();
            });
	}

    // private functions

    function getExcerptized(excerpt, fullText, options) {
        return excerpt
                + ' '
                + options.showMoreText
                + ''
                + '<'+options.tags+' style="display:none;">'
                + fullText.substr(excerpt.length)
                + ''
                + options.showLessText + ''
                + '</'+options.tags+'>';
    }

    function bindControls(excerptizedObj) {
        excerptizedObj.find('.excerptized-show-more').click(function(){
            $(this).hide();
            $(this).next().show();
        });

        excerptizedObj.find('.excerptized-show-less').click(function(){
            $(this).parent().hide();
            excerptizedObj.find('.excerptized-show-more').show();
        });
    }
})(jQuery);
<commit_msg>Fixed propagation issue for view more/less links.<commit_after>(function($) {
    $.fn.excerptize = function(options) {
            var defaults = {
                numberOfCharacters: 100,
                cutOffAtWord: true,
                tags: 'span',
                showMoreText: '[...]',
                showLessText: 'less'
            };

            options = $.extend(defaults, options);

            $(this).each(function(){
                var excerptizedObj = $(this),
                fullText = excerptizedObj.text(),
                excerpt = fullText.substr(0, options.numberOfCharacters),
                excerptized = '';

	            // if full text is less than or equal to excerpt, don't bother
	            if(fullText.length<=options.numberOfCharacters) {
	                return;
	            }

	            if(options.cutOffAtWord) {
	                excerpt = excerpt.substr(0, Math.min(excerpt.length, excerpt.lastIndexOf(" ")))
	            }

	            excerptizedObj.html(getExcerptized(excerpt, fullText, options));
	            bindControls(excerptizedObj);

	            // To avoid the flicker when page first loads,
	            // you can make the 'excerptized' element hidden.
	            // This will ensure excerpt is displayed.
	            excerptizedObj.show();
            });
	}

    // private functions

    function getExcerptized(excerpt, fullText, options) {
        return excerpt
                + ' '
                + options.showMoreText
                + ''
                + '<'+options.tags+' style="display:none;">'
                + fullText.substr(excerpt.length)
                + ''
                + options.showLessText + ''
                + '</'+options.tags+'>';
    }

    function bindControls(excerptizedObj) {
        excerptizedObj.find('.excerptized-show-more').click(function(){
            $(this).hide();
            $(this).next().show();
            return false;
        });

        excerptizedObj.find('.excerptized-show-less').click(function(){
            $(this).parent().hide();
            excerptizedObj.find('.excerptized-show-more').show();
            return false;
        });
    }
})(jQuery);
<|endoftext|>


<commit_before>export const noop = () => {}; // eslint-disable-line arrow-body-style
export const idFn = (x) => x;
<commit_msg>remove no longer used utils<commit_after><|endoftext|>


<commit_before>import React, {PropTypes} from 'react';

import user from 'focus-core/user';
import intersection from 'lodash/array/intersection';
import isArray from 'lodash/lang/isArray';

function Role({hasAll,hasOne,children,emptyBlock}) {
    let userRoles = user.getRoles();
    //console.log("emptyBlock",emptyBlock);
    if(isArray(hasAll) && intersection(userRoles, hasAll).length === hasAll.length) {
        return children;
    } else if(isArray(hasOne) && intersection(userRoles, hasOne).length > 0) {
        return children;
    }
    return emptyBlock;
}

Role.displayName = 'Role';
Role.defaultProps = {
    emptyBlock: null
};
Role.propTypes = {
    children : PropTypes.object,
    hasOne: PropTypes.array,
    hasAll:PropTypes.array
};

export default Role;
<commit_msg>clean role<commit_after>import React, { PropTypes } from 'react';

import user from 'focus-core/user';
import intersection from 'lodash/array/intersection';
import isArray from 'lodash/lang/isArray';

function Role({ hasAll, hasOne, children, emptyBlock }) {
    let userRoles = user.getRoles();
    //console.log("emptyBlock",emptyBlock);
    if (isArray(hasAll) && intersection(userRoles, hasAll).length === hasAll.length) {
        return children;
    } else if (isArray(hasOne) && intersection(userRoles, hasOne).length > 0) {
        return children;
    }
    return emptyBlock;
}

Role.displayName = 'Role';

Role.propTypes = {
    children: PropTypes.object,
    hasOne: PropTypes.array,
    hasAll: PropTypes.array
};

Role.defaultProps = {
    emptyBlock: null
};

export default Role;
<|endoftext|>


<commit_before>function basicAuth(req) {
	var authHeader = req.headers.authorization;
	if (!authHeader)
		return;

	var parts = authHeader.split(' ');
	if (parts[0].toLowerCase() !== 'basic')
		return;

	var data = parts[1];
	if (!data)
		return;

	auth = new Buffer(auth, 'base64').toString();
	auth = auth.match(/^([^:]*):(.*)$/);
	if (!auth)
		return;

	return { user: auth[1], pass: auth[2] };
};

module.exports = exports = basicAuth;
<commit_msg>Stylistic changes on basicAuth<commit_after>function basicAuth(req) {
	var authHeader = req.headers.authorization;
	if (!authHeader)
		return;

	var parts = authHeader.split(' ');
	if (parts.length !== 2)
		return;

	if (!parts[0].toLowerCase() !== 'basic')
		return;

	var data = parts[1];
	if (!data)
		return;

	auth = new Buffer(auth, 'base64').toString();
	auth = auth.match(/^([^:]*):(.*)$/);
	if (!auth)
		return;

	return { user: auth[1], pass: auth[2] };
};

module.exports = exports = basicAuth;
<|endoftext|>


<commit_before>//TODO change to percents
//TODO add other views
//TODO add other fact types (periscope / beginner debunking)

// The expected number of bits of information from real science is
// -[1/7*lg(1/7) * 7]
// = 2.807 bits

// The expected number of bits of information from experimenting randomly on an adventurer is
// -[1/7*lg(1/7) + 2/7*lg(2/7) + 1/7*lg(1/7) + 3/7*lg(3/7)]
// = 1.842 bits

import React from 'react';
// import logo from './logo.svg';
import './App.css';

import _ from 'lodash'
import update from 'react-addons-update'
import PureRenderMixin from 'react-addons-pure-render-mixin';

// This is what an Alchemical looks like:
// [1, 1, -1]

// Here are all of the Alchemicals:
var alchemicals = [
  [-1, +1, -1],
  [+1, -1, +1],
  [+1, -1, -1],
  [-1, +1, +1],
  [-1, -1, +1],
  [+1, +1, -1],
  [-1, -1, -1],
  [+1, +1, +1],
]

var ingredients = [
  "Mushroom",
  "Fern",
  "Toad",
  "Birdclaw",
  "Flower",
  "Mandrake",
  "Scorion",
  "Feather",
]

var potions = {
  "Red+":   [+1, 0, 0],
  "Red-":   [-1, 0, 0],
  "Green+": [0, +1, 0],
  "Green-": [0, -1, 0],
  "Blue+":  [0, 0, +1],
  "Blue-":  [0, 0, -1],
  "Soup":   [0, 0, 0],
}

var Fact = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return

      {this.props.index}: {JSON.stringify(this.props.item)}
      <button onClick={this.props.deleteFact} value={this.props.index}>Delete</button>

  }
});

var FactList = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return
{this.props.items.map((fact, factIndex) => <Fact key={factIndex} item={fact} index={factIndex} deleteFact={this.props.deleteFact}/>)}
;
  }
});

var Ingredient = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return
<input type="radio" name="ingredient" onChange={this.props.callback}/>{this.props.name}

  }
})

var Potion = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return
<input type="checkbox" name="potion" onChange={this.props.callback}/>{this.props.name}

  }
})

var SheetCell = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return {this.numWorlds()}
  },
  numWorlds: function() {
    var worlds = _.filter(this.props.worlds, _.bind(function(world) {
      return _.isEqual(world[this.props.ingredientIndex], this.props.alchemical)
    }, this))
    return worlds.length
  }
})

var SheetRow = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return
{ingredients.map((ingredient, index) => <SheetCell ingredientIndex={index} alchemical={this.props.alchemical} key={index} worlds={this.props.worlds}/>)}

  }
})

var AlchemistsSolverApp = React.createClass({
  mixins: [PureRenderMixin],

  getInitialState: function() {
    return {
      factlist: [],
      currentFact: this.makeNewFact(),
      worlds: permutator(alchemicals),
    }
  },
  makeNewFact: function() {
    return {
      ingredients: [0, 1],
      possibleResults: [false, false, false, false, false, false, false]
    }
  },
  handleSubmit: function(e) {
    e.preventDefault();
    this.setState({
      factlist: this.state.factlist.concat([this.state.currentFact]),
      worlds: _.filter(this.state.worlds, _.curry(check)(this.state.currentFact)),
    });
  },
  ingredientChange: function(ingredientIndex, ingredient) {
    var newIngredients = [];
    newIngredients[ingredientIndex] = ingredient;
    var newState = update(this.state,
      {currentFact: {ingredients: {$merge: newIngredients}}})
    this.setState(newState)
  },
  potionChange: function(potionIndex) {
    var newPossibleResults = [];
    newPossibleResults[potionIndex] = !this.state.currentFact.possibleResults[potionIndex];
    var newState = update(this.state,
      {currentFact: {possibleResults: {$merge: newPossibleResults}}})
    this.setState(newState)
  },
  render: function() {
    var self = this;
    return (

Alchemists Solver

        <FactList items={this.state.factlist} deleteFact={this.deleteFact}/>

        <form action="" style={{display: "inline-block"}}>
          {ingredients.map((name, index) => <Ingredient name={name} ingredientNumber={0} key={index} callback={function() {self.ingredientChange(0, index)}} />)}
        </form>

        <form action="" style={{display: "inline-block"}}>
          {ingredients.map((name, index) => <Ingredient name={name} ingredientNumber={1} key={index} callback={function() {self.ingredientChange(1, index)}} />)}
        </form>

        <form action="" style={{display: "inline-block"}}>
          {_.keys(potions).map((name, index) => <Potion name={name} key={index} callback={function() {self.potionChange(index)}} />)}
        </form>

        <form onSubmit={this.handleSubmit}>
          <button>{'Add Fact'}</button>
        </form>

{this.computeStuff()}

            {alchemicals.map((alchemical, index) => <SheetRow alchemical={alchemical} key={index} worlds={this.state.worlds}/>)}

    );
  },
  deleteFact: function(e) {
    var newFactList = removeAtIndex(this.state.factlist, parseInt(e.target.value, 10))
    var worlds = permutator(alchemicals)
    for (var factIndex in newFactList) {
      var fact = newFactList[factIndex]
      console.log(fact)
      worlds = _.filter(worlds, _.curry(check)(fact))
    }
    this.setState({factlist: newFactList, worlds: worlds})
  },
  computeStuff: function() {
    return this.state.worlds.length
  }
});

// non-mutating
function removeAtIndex(arr, index) {
  return _.filter(arr, function(val, idx) {return idx !== index})
}

var ColorMapping = {
  0: "red",
  1: "green",
  2: "blue",
};

// var SignMapping = {
//   -1: "minus",
//   0: "neutral",
//   1: "plus",
// };

// Alchemical -> Alchemical -> Potion
function mix(alchemicalA, alchemicalB) {
  var mean = _.zipWith(alchemicalA, alchemicalB, function(a,b){return (a+b)/2})
  for (var index = 0; index < 3; index++) {
    if (mean[(index+1) % 3] !== 0)
      mean[index] = 0
  }

  return mean
}

function check(fact, world) {
  var alchemicalA = world[fact.ingredients[0]]
  var alchemicalB = world[fact.ingredients[1]]
  var result = mix(alchemicalA, alchemicalB)
  var potionIndex = _.findIndex(_.values(potions), _.curry(_.isEqual)(result))
  return fact.possibleResults[potionIndex]
}

// http://stackoverflow.com/a/20871714/6036628
function permutator(inputArr) {
  var results = [];

  function permute(arr, memo) {
    var cur, memo = memo || [];

    for (var i = 0; i < arr.length; i++) {
      cur = arr.splice(i, 1);
      if (arr.length === 0) {
        results.push(memo.concat(cur));
      }
      permute(arr.slice(), memo.concat(cur));
      arr.splice(i, 0, cur[0]);
    }

    return results;
  }

  return permute(inputArr);
}

// ===== Unit tests =====

// Here is what a World looks like:
var exampleWorld = [
  [+1, -1, -1],
  [-1, +1, -1],
  [+1, -1, +1],
  [-1, +1, +1],
  [+1, +1, +1],
  [-1, -1, +1],
  [+1, +1, -1],
  [-1, -1, -1],
]

// This is what an Ingredient looks like:
var exampleIngredientA = 4
var exampleIngredientB = 5

// This is what a Potion looks like:
var examplePotionA = [0, 0, 1] // this is a blue+
var examplePotionB = [0, 0, 0] // this is soup

// This is what a Fact looks like:
// {
//   ingredients: [5, 7]
//   possibleResults: [true, false, false, false, false, false, true]
// }
// combining ingredient 5 and 7 make either a red+ or a soup
var exampleFact = {
  ingredients: [exampleIngredientA, exampleIngredientB],
  possibleResults: [examplePotionA, examplePotionB]
}

console.log(check(exampleFact, exampleWorld))

export default AlchemistsSolverApp;
<commit_msg>Converts counts to percentages<commit_after>//TODO change to percents
//TODO add other views
//TODO add other fact types (periscope / beginner debunking)

// The expected number of bits of information from real science is
// -[1/7*lg(1/7) * 7]
// = 2.807 bits

// The expected number of bits of information from experimenting randomly on an adventurer is
// -[1/7*lg(1/7) + 2/7*lg(2/7) + 1/7*lg(1/7) + 3/7*lg(3/7)]
// = 1.842 bits

import React from 'react';
// import logo from './logo.svg';
import './App.css';

import _ from 'lodash'
import update from 'react-addons-update'
import PureRenderMixin from 'react-addons-pure-render-mixin';

// This is what an Alchemical looks like:
// [1, 1, -1]

// Here are all of the Alchemicals:
var alchemicals = [
  [-1, +1, -1],
  [+1, -1, +1],
  [+1, -1, -1],
  [-1, +1, +1],
  [-1, -1, +1],
  [+1, +1, -1],
  [-1, -1, -1],
  [+1, +1, +1],
]

var ingredients = [
  "Mushroom",
  "Fern",
  "Toad",
  "Birdclaw",
  "Flower",
  "Mandrake",
  "Scorion",
  "Feather",
]

var potions = {
  "Red+":   [+1, 0, 0],
  "Red-":   [-1, 0, 0],
  "Green+": [0, +1, 0],
  "Green-": [0, -1, 0],
  "Blue+":  [0, 0, +1],
  "Blue-":  [0, 0, -1],
  "Soup":   [0, 0, 0],
}

var Fact = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return

      {this.props.index}: {JSON.stringify(this.props.item)}
      <button onClick={this.props.deleteFact} value={this.props.index}>Delete</button>

  }
});

var FactList = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return
{this.props.items.map((fact, factIndex) => <Fact key={factIndex} item={fact} index={factIndex} deleteFact={this.props.deleteFact}/>)}
;
  }
});

var Ingredient = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return
<input type="radio" name="ingredient" onChange={this.props.callback}/>{this.props.name}

  }
})

var Potion = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return
<input type="checkbox" name="potion" onChange={this.props.callback}/>{this.props.name}

  }
})

var SheetCell = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return {this.percentage()}
  },
  percentage: function() {
    var worlds = _.filter(this.props.worlds, _.bind(function(world) {
      return _.isEqual(world[this.props.ingredientIndex], this.props.alchemical)
    }, this))
    return Math.round(100 * worlds.length / this.props.worlds.length, 0)
  }
})

var SheetRow = React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return
{ingredients.map((ingredient, index) => <SheetCell ingredientIndex={index} alchemical={this.props.alchemical} key={index} worlds={this.props.worlds}/>)}

  }
})

var AlchemistsSolverApp = React.createClass({
  mixins: [PureRenderMixin],

  getInitialState: function() {
    return {
      factlist: [],
      currentFact: this.makeNewFact(),
      worlds: permutator(alchemicals),
    }
  },
  makeNewFact: function() {
    return {
      ingredients: [0, 1],
      possibleResults: [false, false, false, false, false, false, false]
    }
  },
  handleSubmit: function(e) {
    e.preventDefault();
    this.setState({
      factlist: this.state.factlist.concat([this.state.currentFact]),
      worlds: _.filter(this.state.worlds, _.curry(check)(this.state.currentFact)),
    });
  },
  ingredientChange: function(ingredientIndex, ingredient) {
    var newIngredients = [];
    newIngredients[ingredientIndex] = ingredient;
    var newState = update(this.state,
      {currentFact: {ingredients: {$merge: newIngredients}}})
    this.setState(newState)
  },
  potionChange: function(potionIndex) {
    var newPossibleResults = [];
    newPossibleResults[potionIndex] = !this.state.currentFact.possibleResults[potionIndex];
    var newState = update(this.state,
      {currentFact: {possibleResults: {$merge: newPossibleResults}}})
    this.setState(newState)
  },
  render: function() {
    var self = this;
    return (

Alchemists Solver

        <FactList items={this.state.factlist} deleteFact={this.deleteFact}/>

        <form action="" style={{display: "inline-block"}}>
          {ingredients.map((name, index) => <Ingredient name={name} ingredientNumber={0} key={index} callback={function() {self.ingredientChange(0, index)}} />)}
        </form>

        <form action="" style={{display: "inline-block"}}>
          {ingredients.map((name, index) => <Ingredient name={name} ingredientNumber={1} key={index} callback={function() {self.ingredientChange(1, index)}} />)}
        </form>

        <form action="" style={{display: "inline-block"}}>
          {_.keys(potions).map((name, index) => <Potion name={name} key={index} callback={function() {self.potionChange(index)}} />)}
        </form>

        <form onSubmit={this.handleSubmit}>
          <button>{'Add Fact'}</button>
        </form>

{this.computeStuff()}

            {alchemicals.map((alchemical, index) => <SheetRow alchemical={alchemical} key={index} worlds={this.state.worlds}/>)}

    );
  },
  deleteFact: function(e) {
    var newFactList = removeAtIndex(this.state.factlist, parseInt(e.target.value, 10))
    var worlds = permutator(alchemicals)
    for (var factIndex in newFactList) {
      var fact = newFactList[factIndex]
      console.log(fact)
      worlds = _.filter(worlds, _.curry(check)(fact))
    }
    this.setState({factlist: newFactList, worlds: worlds})
  },
  computeStuff: function() {
    return this.state.worlds.length
  }
});

// non-mutating
function removeAtIndex(arr, index) {
  return _.filter(arr, function(val, idx) {return idx !== index})
}

var ColorMapping = {
  0: "red",
  1: "green",
  2: "blue",
};

// var SignMapping = {
//   -1: "minus",
//   0: "neutral",
//   1: "plus",
// };

// Alchemical -> Alchemical -> Potion
function mix(alchemicalA, alchemicalB) {
  var mean = _.zipWith(alchemicalA, alchemicalB, function(a,b){return (a+b)/2})
  for (var index = 0; index < 3; index++) {
    if (mean[(index+1) % 3] !== 0)
      mean[index] = 0
  }

  return mean
}

function check(fact, world) {
  var alchemicalA = world[fact.ingredients[0]]
  var alchemicalB = world[fact.ingredients[1]]
  var result = mix(alchemicalA, alchemicalB)
  var potionIndex = _.findIndex(_.values(potions), _.curry(_.isEqual)(result))
  return fact.possibleResults[potionIndex]
}

// http://stackoverflow.com/a/20871714/6036628
function permutator(inputArr) {
  var results = [];

  function permute(arr, memo) {
    var cur, memo = memo || [];

    for (var i = 0; i < arr.length; i++) {
      cur = arr.splice(i, 1);
      if (arr.length === 0) {
        results.push(memo.concat(cur));
      }
      permute(arr.slice(), memo.concat(cur));
      arr.splice(i, 0, cur[0]);
    }

    return results;
  }

  return permute(inputArr);
}

// ===== Unit tests =====

// Here is what a World looks like:
var exampleWorld = [
  [+1, -1, -1],
  [-1, +1, -1],
  [+1, -1, +1],
  [-1, +1, +1],
  [+1, +1, +1],
  [-1, -1, +1],
  [+1, +1, -1],
  [-1, -1, -1],
]

// This is what an Ingredient looks like:
var exampleIngredientA = 4
var exampleIngredientB = 5

// This is what a Potion looks like:
var examplePotionA = [0, 0, 1] // this is a blue+
var examplePotionB = [0, 0, 0] // this is soup

// This is what a Fact looks like:
// {
//   ingredients: [5, 7]
//   possibleResults: [true, false, false, false, false, false, true]
// }
// combining ingredient 5 and 7 make either a red+ or a soup
var exampleFact = {
  ingredients: [exampleIngredientA, exampleIngredientB],
  possibleResults: [examplePotionA, examplePotionB]
}

console.log(check(exampleFact, exampleWorld))

export default AlchemistsSolverApp;
<|endoftext|>