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

const { extname } = require('path');

const config = hexo.config.feed = Object.assign({
  type: 'atom',
  limit: 20,
  hub: '',
  content: true,
  content_limit: 140,
  content_limit_delim: '',
  order_by: '-date',
  autodiscovery: true
}, hexo.config.feed);

let type = config.type;
let path = config.path;
const feedFn = require('./lib/generator');

if (typeof type === 'string') type = [type];

if (!type || !Array.isArray(type)) {
  type = ['atom'];
}

if (Array.isArray(type) && type.length > 2) {
  type = type.slice(0, 2);
}

type = type.map((str, i) => {
  str = str.toLowerCase();
  if (str !== 'atom' && str !== 'rss2') {
    if (i === 0) str = 'atom';
    else str = 'rss2';
  }
  return str;
});

if (typeof path === 'string') path = [path];

if (!path || !Array.isArray(path)) {
  path = type.map(str => str.concat('.xml'));
}

if (Array.isArray(path)) {
  if (path.length > 2) path = path.slice(0, 2);
  if (path.length !== type.length) {
    if (path.length === 0) path = type.map(str => str.concat('.xml'));
    else path.push(type[1]);
  }
}

path = path.map(str => {
  if (!extname(str)) return str.concat('.xml');
  return str;
});

config.type = type;
config.path = path;

for (const feedType of type) {
  hexo.extend.generator.register(feedType, locals => {
    return feedFn.call(hexo, locals, feedType, path[type.indexOf(feedType)]);
  });
}

if (typeof config.autodiscovery === 'undefined') config.autodiscovery = true;

if (config.autodiscovery === true) {
  hexo.extend.filter.register('after_render:html', require('./lib/autodiscovery'));
}
<commit_msg>fix: 'path' might be larger than 'type'<commit_after>/* global hexo */
'use strict';

const { extname } = require('path');

const config = hexo.config.feed = Object.assign({
  type: 'atom',
  limit: 20,
  hub: '',
  content: true,
  content_limit: 140,
  content_limit_delim: '',
  order_by: '-date',
  autodiscovery: true
}, hexo.config.feed);

let type = config.type;
let path = config.path;
const feedFn = require('./lib/generator');

if (typeof type === 'string') type = [type];

if (!type || !Array.isArray(type)) {
  type = ['atom'];
}

if (Array.isArray(type) && type.length > 2) {
  type = type.slice(0, 2);
}

type = type.map((str, i) => {
  str = str.toLowerCase();
  if (str !== 'atom' && str !== 'rss2') {
    if (i === 0) str = 'atom';
    else str = 'rss2';
  }
  return str;
});

if (typeof path === 'string') path = [path];

if (!path || !Array.isArray(path)) {
  path = type.map(str => str.concat('.xml'));
}

if (Array.isArray(path)) {
  if (path.length !== type.length) {
    if (path.length > type.length) path = path.slice(0, type.length);
    else if (path.length === 0) path = type.map(str => str.concat('.xml'));
    else path.push(type[1].concat('.xml'));
  }
}

path = path.map(str => {
  if (!extname(str)) return str.concat('.xml');
  return str;
});

config.type = type;
config.path = path;

for (const feedType of type) {
  hexo.extend.generator.register(feedType, locals => {
    return feedFn.call(hexo, locals, feedType, path[type.indexOf(feedType)]);
  });
}

if (typeof config.autodiscovery === 'undefined') config.autodiscovery = true;

if (config.autodiscovery === true) {
  hexo.extend.filter.register('after_render:html', require('./lib/autodiscovery'));
}
<|endoftext|>


<commit_before>var tape = require("tape"),
    arrays = require("../");

tape("nest.entries(array) returns the array of input values, in input order", function(test) {
  var nest = arrays.nest();
  test.deepEqual(nest.entries([1, 2, 3]), [1, 2, 3]);
  test.deepEqual(nest.entries([1, 3, 2]), [1, 3, 2]);
  test.deepEqual(nest.entries([3, 1, 2]), [3, 1, 2]);
  test.end();
});

tape("nest.sortValues(order).entries(array) returns input values in sorted order", function(test) {
  var nestAscending = arrays.nest().sortValues(function(a, b) { return a.foo - b.foo; }),
      nestDescending = arrays.nest().sortValues(function(a, b) { return b.foo - a.foo; }),
      a = {foo: 1},
      b = {foo: 2},
      c = {foo: 3};
  test.deepEqual(nestAscending.entries([a, b, c]), [a, b, c]);
  test.deepEqual(nestAscending.entries([a, c, b]), [a, b, c]);
  test.deepEqual(nestAscending.entries([c, a, b]), [a, b, c]);
  test.deepEqual(nestDescending.entries([a, b, c]), [c, b, a]);
  test.deepEqual(nestDescending.entries([a, c, b]), [c, b, a]);
  test.deepEqual(nestDescending.entries([c, a, b]), [c, b, a]);
  test.end();
});

tape("nest.key(key).entries(array) returns entries for each distinct key, with values in input order", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.ascending),
      a = {foo: 1},
      b = {foo: 1},
      c = {foo: 2};
  test.deepEqual(nest.entries([c, a, b, c]), [{key: "1", values: [a, b]}, {key: "2", values: [c, c]}]);
  test.deepEqual(nest.entries([c, b, a, c]), [{key: "1", values: [b, a]}, {key: "2", values: [c, c]}]);
  test.end();
});

tape("nest.key(key) coerces key values to strings", function(test) {
  var nest = arrays.nest().key(function(d) { return d.number ? 1 : "1"; }).sortKeys(arrays.ascending),
      a = {number: true},
      b = {number: false};
  test.deepEqual(nest.entries([a, b]), [{key: "1", values: [a, b]}]);
  test.end();
});

tape("nest.key(key1).key(key2).entries(array) returns entries for each distinct key set, with values in input order", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.ascending).key(function(d) { return d.bar; }).sortKeys(arrays.ascending),
      a = {foo: 1, bar: "a"},
      b = {foo: 1, bar: "a"},
      c = {foo: 2, bar: "a"},
      d = {foo: 1, bar: "b"},
      e = {foo: 1, bar: "b"},
      f = {foo: 2, bar: "b"};
  test.deepEqual(nest.entries([a, b, c, d, e, f]), [{key: "1", values: [{key: "a", values: [a, b]}, {key: "b", values: [d, e]}]}, {key: "2", values: [{key: "a", values: [c]}, {key: "b", values: [f]}]}]);
  test.deepEqual(nest.entries([f, e, d, c, b, a]), [{key: "1", values: [{key: "a", values: [b, a]}, {key: "b", values: [e, d]}]}, {key: "2", values: [{key: "a", values: [c]}, {key: "b", values: [f]}]}]);
  test.end();
});

tape("nest.key(key).sortKeys(order).entries(array) sorts entries by key using the specified order function", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.descending),
      a = {foo: 1},
      b = {foo: 1},
      c = {foo: 2};
  test.deepEqual(nest.entries([c, a, b, c]), [{key: "2", values: [c, c]}, {key: "1", values: [a, b]}]);
  test.deepEqual(nest.entries([c, b, a, c]), [{key: "2", values: [c, c]}, {key: "1", values: [b, a]}]);
  test.end();
});

tape("nest.key(key1).sortKeys(order1).key(key2).sortKeys(order2).entries(array) sorts entries by key using the specified order functions", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.descending).key(function(d) { return d.bar; }).sortKeys(arrays.descending),
      a = {foo: 1, bar: "a"},
      b = {foo: 1, bar: "a"},
      c = {foo: 2, bar: "a"},
      d = {foo: 1, bar: "b"},
      e = {foo: 1, bar: "b"},
      f = {foo: 2, bar: "b"};
  test.deepEqual(nest.entries([a, b, c, d, e, f]), [{key: "2", values: [{key: "b", values: [f]}, {key: "a", values: [c]}]}, {key: "1", values: [{key: "b", values: [d, e]}, {key: "a", values: [a, b]}]}]);
  test.deepEqual(nest.entries([f, e, d, c, b, a]), [{key: "2", values: [{key: "b", values: [f]}, {key: "a", values: [c]}]}, {key: "1", values: [{key: "b", values: [e, d]}, {key: "a", values: [b, a]}]}]);
  test.end();
});

tape("nest.rollup(rollup).entries(array) aggregates values using the specified rollup function", function(test) {
  test.equal(arrays.nest().rollup(function(values) { return values.length; }).entries([1, 2, 3, 4, 5]), 5);
  test.equal(arrays.nest().rollup(arrays.sum).entries([1, 2, 3, 4, 5]), 1 + 2 + 3 + 4 + 5);
  test.equal(arrays.nest().rollup(arrays.max).entries([1, 2, 3, 4, 5]), 5);
  test.deepEqual(arrays.nest().rollup(arrays.extent).entries([1, 2, 3, 4, 5]), [1, 5]);
  test.end();
});

tape("nest.key(key).rollup(rollup).entries(array) aggregates values per key using the specified rollup function", function(test) {
  var a = {foo: 1},
      b = {foo: 1},
      c = {foo: 2};
  test.deepEqual(arrays.nest().key(function(d) { return d.foo; }).rollup(function(values) { return values.length; }).entries([a, b, c]), [{key: "1", values: 2}, {key: "2", values: 1}]);
  test.end();
});

tape("nest.map(array) returns the array of input values, in input order", function(test) {
  var nest = arrays.nest();
  test.deepEqual(nest.map([1, 2, 3]), [1, 2, 3]);
  test.deepEqual(nest.map([1, 3, 2]), [1, 3, 2]);
  test.deepEqual(nest.map([3, 1, 2]), [3, 1, 2]);
  test.end();
});

tape("nest.sortValues(order).map(array) returns input values in sorted order", function(test) {
  var nestAscending = arrays.nest().sortValues(function(a, b) { return a.foo - b.foo; }),
      nestDescending = arrays.nest().sortValues(function(a, b) { return b.foo - a.foo; }),
      a = {foo: 1},
      b = {foo: 2},
      c = {foo: 3};
  test.deepEqual(nestAscending.map([a, b, c]), [a, b, c]);
  test.deepEqual(nestAscending.map([a, c, b]), [a, b, c]);
  test.deepEqual(nestAscending.map([c, a, b]), [a, b, c]);
  test.deepEqual(nestDescending.map([a, b, c]), [c, b, a]);
  test.deepEqual(nestDescending.map([a, c, b]), [c, b, a]);
  test.deepEqual(nestDescending.map([c, a, b]), [c, b, a]);
  test.end();
});

tape("nest.key(key).map(array) returns entries for each distinct key, with values in input order", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.ascending),
      a = {foo: 1},
      b = {foo: 1},
      c = {foo: 2};
  test.deepEqual(nest.map([c, a, b, c]), arrays.map({1: [a, b], 2: [c, c]}));
  test.deepEqual(nest.map([c, b, a, c]), arrays.map({1: [b, a], 2: [c, c]}));
  test.end();
});

tape("nest.key(key1).key(key2).map(array) returns entries for each distinct key set, with values in input order", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.ascending).key(function(d) { return d.bar; }).sortKeys(arrays.ascending),
      a = {foo: 1, bar: "a"},
      b = {foo: 1, bar: "a"},
      c = {foo: 2, bar: "a"},
      d = {foo: 1, bar: "b"},
      e = {foo: 1, bar: "b"},
      f = {foo: 2, bar: "b"};
  test.deepEqual(nest.map([a, b, c, d, e, f]), arrays.map({1: arrays.map({a: [a, b], b: [d, e]}), 2: arrays.map({a: [c], b: [f]})}));
  test.deepEqual(nest.map([f, e, d, c, b, a]), arrays.map({1: arrays.map({a: [b, a], b: [e, d]}), 2: arrays.map({a: [c], b: [f]})}));
  test.end();
});

tape("nest.rollup(rollup).map(array) aggregates values using the specified rollup function", function(test) {
  test.equal(arrays.nest().rollup(function(values) { return values.length; }).map([1, 2, 3, 4, 5]), 5);
  test.equal(arrays.nest().rollup(arrays.sum).map([1, 2, 3, 4, 5]), 1 + 2 + 3 + 4 + 5);
  test.equal(arrays.nest().rollup(arrays.max).map([1, 2, 3, 4, 5]), 5);
  test.deepEqual(arrays.nest().rollup(arrays.extent).map([1, 2, 3, 4, 5]), [1, 5]);
  test.end();
});

tape("nest.key(key).rollup(rollup).map(array) aggregates values per key using the specified rollup function", function(test) {
  var a = {foo: 1},
      b = {foo: 1},
      c = {foo: 2};
  test.deepEqual(arrays.nest().key(function(d) { return d.foo; }).rollup(function(values) { return values.length; }).map([a, b, c]), arrays.map({1: 2, 2: 1}));
  test.end();
});
<commit_msg>Test nest.rollup this.<commit_after>var tape = require("tape"),
    arrays = require("../");

tape("nest.entries(array) returns the array of input values, in input order", function(test) {
  var nest = arrays.nest();
  test.deepEqual(nest.entries([1, 2, 3]), [1, 2, 3]);
  test.deepEqual(nest.entries([1, 3, 2]), [1, 3, 2]);
  test.deepEqual(nest.entries([3, 1, 2]), [3, 1, 2]);
  test.end();
});

tape("nest.sortValues(order).entries(array) returns input values in sorted order", function(test) {
  var nestAscending = arrays.nest().sortValues(function(a, b) { return a.foo - b.foo; }),
      nestDescending = arrays.nest().sortValues(function(a, b) { return b.foo - a.foo; }),
      a = {foo: 1},
      b = {foo: 2},
      c = {foo: 3};
  test.deepEqual(nestAscending.entries([a, b, c]), [a, b, c]);
  test.deepEqual(nestAscending.entries([a, c, b]), [a, b, c]);
  test.deepEqual(nestAscending.entries([c, a, b]), [a, b, c]);
  test.deepEqual(nestDescending.entries([a, b, c]), [c, b, a]);
  test.deepEqual(nestDescending.entries([a, c, b]), [c, b, a]);
  test.deepEqual(nestDescending.entries([c, a, b]), [c, b, a]);
  test.end();
});

tape("nest.key(key).entries(array) returns entries for each distinct key, with values in input order", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.ascending),
      a = {foo: 1},
      b = {foo: 1},
      c = {foo: 2};
  test.deepEqual(nest.entries([c, a, b, c]), [{key: "1", values: [a, b]}, {key: "2", values: [c, c]}]);
  test.deepEqual(nest.entries([c, b, a, c]), [{key: "1", values: [b, a]}, {key: "2", values: [c, c]}]);
  test.end();
});

tape("nest.key(key) coerces key values to strings", function(test) {
  var nest = arrays.nest().key(function(d) { return d.number ? 1 : "1"; }).sortKeys(arrays.ascending),
      a = {number: true},
      b = {number: false};
  test.deepEqual(nest.entries([a, b]), [{key: "1", values: [a, b]}]);
  test.end();
});

tape("nest.key(key1).key(key2).entries(array) returns entries for each distinct key set, with values in input order", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.ascending).key(function(d) { return d.bar; }).sortKeys(arrays.ascending),
      a = {foo: 1, bar: "a"},
      b = {foo: 1, bar: "a"},
      c = {foo: 2, bar: "a"},
      d = {foo: 1, bar: "b"},
      e = {foo: 1, bar: "b"},
      f = {foo: 2, bar: "b"};
  test.deepEqual(nest.entries([a, b, c, d, e, f]), [{key: "1", values: [{key: "a", values: [a, b]}, {key: "b", values: [d, e]}]}, {key: "2", values: [{key: "a", values: [c]}, {key: "b", values: [f]}]}]);
  test.deepEqual(nest.entries([f, e, d, c, b, a]), [{key: "1", values: [{key: "a", values: [b, a]}, {key: "b", values: [e, d]}]}, {key: "2", values: [{key: "a", values: [c]}, {key: "b", values: [f]}]}]);
  test.end();
});

tape("nest.key(key).sortKeys(order).entries(array) sorts entries by key using the specified order function", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.descending),
      a = {foo: 1},
      b = {foo: 1},
      c = {foo: 2};
  test.deepEqual(nest.entries([c, a, b, c]), [{key: "2", values: [c, c]}, {key: "1", values: [a, b]}]);
  test.deepEqual(nest.entries([c, b, a, c]), [{key: "2", values: [c, c]}, {key: "1", values: [b, a]}]);
  test.end();
});

tape("nest.key(key1).sortKeys(order1).key(key2).sortKeys(order2).entries(array) sorts entries by key using the specified order functions", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.descending).key(function(d) { return d.bar; }).sortKeys(arrays.descending),
      a = {foo: 1, bar: "a"},
      b = {foo: 1, bar: "a"},
      c = {foo: 2, bar: "a"},
      d = {foo: 1, bar: "b"},
      e = {foo: 1, bar: "b"},
      f = {foo: 2, bar: "b"};
  test.deepEqual(nest.entries([a, b, c, d, e, f]), [{key: "2", values: [{key: "b", values: [f]}, {key: "a", values: [c]}]}, {key: "1", values: [{key: "b", values: [d, e]}, {key: "a", values: [a, b]}]}]);
  test.deepEqual(nest.entries([f, e, d, c, b, a]), [{key: "2", values: [{key: "b", values: [f]}, {key: "a", values: [c]}]}, {key: "1", values: [{key: "b", values: [e, d]}, {key: "a", values: [b, a]}]}]);
  test.end();
});

tape("nest.rollup(rollup).entries(array) aggregates values using the specified rollup function", function(test) {
  test.equal(arrays.nest().rollup(function(values) { return values.length; }).entries([1, 2, 3, 4, 5]), 5);
  test.equal(arrays.nest().rollup(arrays.sum).entries([1, 2, 3, 4, 5]), 1 + 2 + 3 + 4 + 5);
  test.equal(arrays.nest().rollup(arrays.max).entries([1, 2, 3, 4, 5]), 5);
  test.deepEqual(arrays.nest().rollup(arrays.extent).entries([1, 2, 3, 4, 5]), [1, 5]);
  test.end();
});

tape("nest.rollup(rollup) uses the global this context", function(test) {
  var that;
  arrays.nest().rollup(function() { that = this; }).entries([1, 2, 3, 4, 5]);
  test.equal(that, global);
  test.end();
});

tape("nest.key(key).rollup(rollup).entries(array) aggregates values per key using the specified rollup function", function(test) {
  var a = {foo: 1},
      b = {foo: 1},
      c = {foo: 2};
  test.deepEqual(arrays.nest().key(function(d) { return d.foo; }).rollup(function(values) { return values.length; }).entries([a, b, c]), [{key: "1", values: 2}, {key: "2", values: 1}]);
  test.end();
});

tape("nest.map(array) returns the array of input values, in input order", function(test) {
  var nest = arrays.nest();
  test.deepEqual(nest.map([1, 2, 3]), [1, 2, 3]);
  test.deepEqual(nest.map([1, 3, 2]), [1, 3, 2]);
  test.deepEqual(nest.map([3, 1, 2]), [3, 1, 2]);
  test.end();
});

tape("nest.sortValues(order).map(array) returns input values in sorted order", function(test) {
  var nestAscending = arrays.nest().sortValues(function(a, b) { return a.foo - b.foo; }),
      nestDescending = arrays.nest().sortValues(function(a, b) { return b.foo - a.foo; }),
      a = {foo: 1},
      b = {foo: 2},
      c = {foo: 3};
  test.deepEqual(nestAscending.map([a, b, c]), [a, b, c]);
  test.deepEqual(nestAscending.map([a, c, b]), [a, b, c]);
  test.deepEqual(nestAscending.map([c, a, b]), [a, b, c]);
  test.deepEqual(nestDescending.map([a, b, c]), [c, b, a]);
  test.deepEqual(nestDescending.map([a, c, b]), [c, b, a]);
  test.deepEqual(nestDescending.map([c, a, b]), [c, b, a]);
  test.end();
});

tape("nest.key(key).map(array) returns entries for each distinct key, with values in input order", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.ascending),
      a = {foo: 1},
      b = {foo: 1},
      c = {foo: 2};
  test.deepEqual(nest.map([c, a, b, c]), arrays.map({1: [a, b], 2: [c, c]}));
  test.deepEqual(nest.map([c, b, a, c]), arrays.map({1: [b, a], 2: [c, c]}));
  test.end();
});

tape("nest.key(key1).key(key2).map(array) returns entries for each distinct key set, with values in input order", function(test) {
  var nest = arrays.nest().key(function(d) { return d.foo; }).sortKeys(arrays.ascending).key(function(d) { return d.bar; }).sortKeys(arrays.ascending),
      a = {foo: 1, bar: "a"},
      b = {foo: 1, bar: "a"},
      c = {foo: 2, bar: "a"},
      d = {foo: 1, bar: "b"},
      e = {foo: 1, bar: "b"},
      f = {foo: 2, bar: "b"};
  test.deepEqual(nest.map([a, b, c, d, e, f]), arrays.map({1: arrays.map({a: [a, b], b: [d, e]}), 2: arrays.map({a: [c], b: [f]})}));
  test.deepEqual(nest.map([f, e, d, c, b, a]), arrays.map({1: arrays.map({a: [b, a], b: [e, d]}), 2: arrays.map({a: [c], b: [f]})}));
  test.end();
});

tape("nest.rollup(rollup).map(array) aggregates values using the specified rollup function", function(test) {
  test.equal(arrays.nest().rollup(function(values) { return values.length; }).map([1, 2, 3, 4, 5]), 5);
  test.equal(arrays.nest().rollup(arrays.sum).map([1, 2, 3, 4, 5]), 1 + 2 + 3 + 4 + 5);
  test.equal(arrays.nest().rollup(arrays.max).map([1, 2, 3, 4, 5]), 5);
  test.deepEqual(arrays.nest().rollup(arrays.extent).map([1, 2, 3, 4, 5]), [1, 5]);
  test.end();
});

tape("nest.key(key).rollup(rollup).map(array) aggregates values per key using the specified rollup function", function(test) {
  var a = {foo: 1},
      b = {foo: 1},
      c = {foo: 2};
  test.deepEqual(arrays.nest().key(function(d) { return d.foo; }).rollup(function(values) { return values.length; }).map([a, b, c]), arrays.map({1: 2, 2: 1}));
  test.end();
});
<|endoftext|>


<commit_before>module.exports = function(config) {
	config.set({
		basePath: '../',
		frameworks: ['ng-scenario'],
		files: [
			'test/e2e/**/*.js'
		],

		autoWatch: true,

		browsers: ['Firefox'],

		singleRun: false,

		proxies: {
			'/': 'http://localhost:8000/'
		},

		urlRoot: "__karma__",

		junitReporter: {
			outputFile: 'test_out/e2e.xml',
			suite: 'e2e'
		}
	});
};
<commit_msg>Reverted e2e config to recover original (correct) behaviour for e2e tests<commit_after>module.exports = function(config) {
	config.set({
		basePath: '../',
		frameworks: ['ng-scenario'],
		files: [
			'test/e2e/**/*.js'
		],

		autoWatch: false,

		browsers: ['Firefox'],

		singleRun: true,

		proxies: {
			'/': 'http://localhost:8000/'
		},

		urlRoot: "__karma__",

		junitReporter: {
			outputFile: 'test_out/e2e.xml',
			suite: 'e2e'
		}
	});
};
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var React = require('react');
var dom = React.createElement;
var Router = require('react-router');
var RouteHandler = Router.RouteHandler;
var Link = Router.Link;
var merge = require('utils-merge');

/**
 * Load the function initializers
 */

var createRenderFn = require('./lib/render-fn');
var createDomFn = require('./lib/dom-fn');
var loadingStatus = require('./lib/loading-status');
var Navigation = require('./lib/navigation');
var Params = require('./lib/params');

/**
 * noop
 */

function noop(a) { return a; }

/**
 * save React types
 */

var PropTypes = React.PropTypes;
var ReactObj = PropTypes.object;
var ReactFunc = PropTypes.func;

/**
 * expose component creation
 */

exports['default'] = exports = module.exports = createComponent;

/**
 * Lifecylce methods
 */

var lifecycle = [
  'componentDidMount',
  'componentWillReceiveProps',
  'shouldComponentUpdate',
  'componentWillUpdate',
  'componentDidUpdate',
  'componentWillUnmount'
];

/**
 * Create an Onus component
 */

function createComponent(conf, filename) {
  // create a mixin with the defined lifecycle events
  var events = {};
  for (var i = 0, event; i < lifecycle.length; i++) {
    event = lifecycle[i];
    if (conf[event]) events[event] = conf[event];
  }

  // load the standard mixins
  var mixins = [
    Router.State,
    Navigation,
    Params,
    loadingStatus,
    events
  ].concat(conf.mixins || []);

  var component = {
    displayName: conf.displayName,

    mixins: mixins,

    contextTypes: merge({
      store: ReactObj.isRequired,
      forms: ReactObj,
      translate: ReactObj,
      errorHandler: ReactFunc,
      encodeParams: ReactFunc,
      decodeParams: ReactFunc,
      events: ReactFunc,
      canary: ReactObj
    }, conf.contextTypes),

    __onus_onStoreChange: function(href) {
      var self = this;
      self.isMounted() && self.forceUpdate();
    },

    componentWillMount: function() {
      var self = this;
      var context = self.context;

      var store = self._store = context.store.context(self.__onus_onStoreChange);
      if (context.store.getAsync) self.getAsync = context.store.getAsync.bind(context.store);
      self._t = self._t || context.translate ? context.translate.context(store) : noop;
      self.forms = self.context.forms;
      self.canary = context.canary.context(self.__onus_onStoreChange);
      self._error_handler = self._error_handler || context.errorHandler || noop;

      if (module.hot) {
        (conf.__subs = conf.__subs || {})[this._rootNodeID] = function() {
          self.forceUpdate();
        };
      }

      if (conf.componentWillMount) conf.componentWillMount.call(this);
    },

    componentWillUnmount: function() {
      var self = this;
      if (module.hot) delete conf.__subs[self._rootNodeID];
      self._store.destroy();
    },

    statics: conf.statics,

    _DOM: conf._DOM || createDomFn(conf, dom, noop, Link),

    _yield: conf._yield || _yield,

    _render: conf._render || createRenderFn(conf, dom, noop),

    // TODO
    _error: function(DOM,
      get,
      props,
      state,
      _yield,
      params,
      query,
      forms,
      t,
      err) {
      console.error(err.stack || err);
    },

    equalPairs: function() {
      var a = arguments;
      for (var i = 0; i < a.length; i+=2) {
        if (!this.isEqual(a[i], a[i + 1])) return false;
      }
      return true;
    },

    isEqual: function(a, b) {
      var typeA = typeof a;
      var typeB = typeof b
      // the types have changed
      if (typeA !== typeB) return false;
      // scalars
      if (a === b) return true;
      // defined values
      if (a && b) {
        if (typeof a.__hash !== 'undefined' && typeof b.__hash !== 'undefined') return a.__hash === b.__hash;
        if (typeof a.hashCode === 'function' && typeof b.hashCode === 'function') return a.hashCode() === b.hashCode();
      }
      // TODO add other comparisons
      return false;
    },

    loadedClassName: conf.loadedClassName || 'is-loaded',

    loadingClassName: conf.loadingClassName || 'is-loading',

    componentClassName: conf.componentClassName || conf.displayName + '-component',

    render: function() {
      // TODO see if we can cache this
      // TODO detect any recursive re-renders
      if (process.env.NODE_ENV === 'development') {
        if (typeof window !== 'undefined') {
          onus.renderCounts[conf.displayName] |= 0;
          onus.renderCounts[conf.displayName]++;
          onus.renderTotal++;
        }
      }

      return this._render();
    }
  };

  if (conf.initialState) component.getInitialState = function() {
    var state = {};
    for (var k in conf.initialState) {
      state[k] = conf.initialState[k];
    }
    return state;
  };

  for (var k in conf) {
    if (component[k] || !conf.hasOwnProperty(k) || events[k]) continue;
    component[k] = conf[k];
  }

  return React.createClass(component);
}

if (process.env.NODE_ENV === 'development') {
  if (typeof window !== 'undefined') {
    window.onus = {
      renderCounts: {},
      renderTotal: 0,
      reset: function() {
        onus.renderCounts = {};
        onus.renderTotal = 0;
      }
    };
  }
}

/**
 * Wrap the yield function
 */

function _yield(name, $get, t) {
  var props = this.props;

  if (!name) return props.children ? props.children : dom(RouteHandler);

  var prop = props[name];
  if (typeof prop !== 'function') return prop;
  var args = Array.prototype.slice.call(arguments, 3);
  return prop.apply({g: $get, t: t}, args);
}
<commit_msg>make canary optional<commit_after>/**
 * Module dependencies
 */

var React = require('react');
var dom = React.createElement;
var Router = require('react-router');
var RouteHandler = Router.RouteHandler;
var Link = Router.Link;
var merge = require('utils-merge');

/**
 * Load the function initializers
 */

var createRenderFn = require('./lib/render-fn');
var createDomFn = require('./lib/dom-fn');
var loadingStatus = require('./lib/loading-status');
var Navigation = require('./lib/navigation');
var Params = require('./lib/params');

/**
 * noop
 */

function noop(a) { return a; }

/**
 * save React types
 */

var PropTypes = React.PropTypes;
var ReactObj = PropTypes.object;
var ReactFunc = PropTypes.func;

/**
 * expose component creation
 */

exports['default'] = exports = module.exports = createComponent;

/**
 * Lifecylce methods
 */

var lifecycle = [
  'componentDidMount',
  'componentWillReceiveProps',
  'shouldComponentUpdate',
  'componentWillUpdate',
  'componentDidUpdate',
  'componentWillUnmount'
];

/**
 * Create an Onus component
 */

function createComponent(conf, filename) {
  // create a mixin with the defined lifecycle events
  var events = {};
  for (var i = 0, event; i < lifecycle.length; i++) {
    event = lifecycle[i];
    if (conf[event]) events[event] = conf[event];
  }

  // load the standard mixins
  var mixins = [
    Router.State,
    Navigation,
    Params,
    loadingStatus,
    events
  ].concat(conf.mixins || []);

  var component = {
    displayName: conf.displayName,

    mixins: mixins,

    contextTypes: merge({
      store: ReactObj.isRequired,
      forms: ReactObj,
      translate: ReactObj,
      errorHandler: ReactFunc,
      encodeParams: ReactFunc,
      decodeParams: ReactFunc,
      events: ReactFunc,
      canary: ReactObj
    }, conf.contextTypes),

    __onus_onStoreChange: function(href) {
      var self = this;
      self.isMounted() && self.forceUpdate();
    },

    componentWillMount: function() {
      var self = this;
      var context = self.context;

      var store = self._store = context.store.context(self.__onus_onStoreChange);
      if (context.store.getAsync) self.getAsync = context.store.getAsync.bind(context.store);
      self._t = self._t || context.translate ? context.translate.context(store) : noop;
      self.forms = self.context.forms;
      if (context.canary) self.canary = context.canary.context(self.__onus_onStoreChange);
      self._error_handler = self._error_handler || context.errorHandler || noop;

      if (module.hot) {
        (conf.__subs = conf.__subs || {})[this._rootNodeID] = function() {
          self.forceUpdate();
        };
      }

      if (conf.componentWillMount) conf.componentWillMount.call(this);
    },

    componentWillUnmount: function() {
      var self = this;
      if (module.hot) delete conf.__subs[self._rootNodeID];
      self._store.destroy();
    },

    statics: conf.statics,

    _DOM: conf._DOM || createDomFn(conf, dom, noop, Link),

    _yield: conf._yield || _yield,

    _render: conf._render || createRenderFn(conf, dom, noop),

    // TODO
    _error: function(DOM,
      get,
      props,
      state,
      _yield,
      params,
      query,
      forms,
      t,
      err) {
      console.error(err.stack || err);
    },

    equalPairs: function() {
      var a = arguments;
      for (var i = 0; i < a.length; i+=2) {
        if (!this.isEqual(a[i], a[i + 1])) return false;
      }
      return true;
    },

    isEqual: function(a, b) {
      var typeA = typeof a;
      var typeB = typeof b
      // the types have changed
      if (typeA !== typeB) return false;
      // scalars
      if (a === b) return true;
      // defined values
      if (a && b) {
        if (typeof a.__hash !== 'undefined' && typeof b.__hash !== 'undefined') return a.__hash === b.__hash;
        if (typeof a.hashCode === 'function' && typeof b.hashCode === 'function') return a.hashCode() === b.hashCode();
      }
      // TODO add other comparisons
      return false;
    },

    loadedClassName: conf.loadedClassName || 'is-loaded',

    loadingClassName: conf.loadingClassName || 'is-loading',

    componentClassName: conf.componentClassName || conf.displayName + '-component',

    render: function() {
      // TODO see if we can cache this
      // TODO detect any recursive re-renders
      if (process.env.NODE_ENV === 'development') {
        if (typeof window !== 'undefined') {
          onus.renderCounts[conf.displayName] |= 0;
          onus.renderCounts[conf.displayName]++;
          onus.renderTotal++;
        }
      }

      return this._render();
    }
  };

  if (conf.initialState) component.getInitialState = function() {
    var state = {};
    for (var k in conf.initialState) {
      state[k] = conf.initialState[k];
    }
    return state;
  };

  for (var k in conf) {
    if (component[k] || !conf.hasOwnProperty(k) || events[k]) continue;
    component[k] = conf[k];
  }

  return React.createClass(component);
}

if (process.env.NODE_ENV === 'development') {
  if (typeof window !== 'undefined') {
    window.onus = {
      renderCounts: {},
      renderTotal: 0,
      reset: function() {
        onus.renderCounts = {};
        onus.renderTotal = 0;
      }
    };
  }
}

/**
 * Wrap the yield function
 */

function _yield(name, $get, t) {
  var props = this.props;

  if (!name) return props.children ? props.children : dom(RouteHandler);

  var prop = props[name];
  if (typeof prop !== 'function') return prop;
  var args = Array.prototype.slice.call(arguments, 3);
  return prop.apply({g: $get, t: t}, args);
}
<|endoftext|>


<commit_before>/// <reference path="../Runtime/Nullstone.js"/>
/// CODE
/// <reference path="../Media/MediaParser.js"/>

//#region Fayde

var Fayde = {
    TypeConverters: {
        Thickness: function (str) {
            /// <param name="str" type="String"></param>
            if (!str)
                return new Thickness();
            var tokens = str.split(",");
            var left, top, right, bottom;
            if (tokens.length === 1) {
                left = top = right = bottom = parseFloat(tokens[0]);
            } else if (tokens.length === 2) {
                left = right = parseFloat(tokens[0]);
                top = bottom = parseFloat(tokens[1]);
            } else if (tokens.length === 4) {
                left = parseFloat(tokens[0]);
                top = parseFloat(tokens[1]);
                right = parseFloat(tokens[2]);
                bottom = parseFloat(tokens[3]);
            } else {
                throw new ParseException("Cannot parse Thickness value '" + str + "'");
            }
            return new Thickness(left, top, right, bottom);
        },
        CornerRadius: function (str) {
            /// <param name="str" type="String"></param>
            if (!str)
                return new Thickness();
            var tokens = str.split(",");
            var topLeft, topRight, bottomRight, bottomLeft;
            if (tokens.length === 1) {
                topLeft = topRight = bottomRight = bottomLeft = parseFloat(tokens[0]);
            } else if (tokens.length === 4) {
                topLeft = parseFloat(tokens[0]);
                topRight = parseFloat(tokens[1]);
                bottomLeft = parseFloat(tokens[2]);
                bottomRight = parseFloat(tokens[3]);
            } else {
                throw new ParseException("Cannot parse CornerRadius value '" + str + "'");
            }
        }
    },
    TypeConverter: {
        ConvertObject: function (propd, val, objectType, doStringConversion) {
            /// <param name="propd" type="DependencyProperty"></param>
            /// <param name="val" type="Object"></param>
            /// <param name="objectType" type="Function"></param>
            /// <param name="doStringConversion" type="Boolean"></param>

            if (val == null)
                return val;

            var targetType = propd.GetTargetType();
            if (typeof targetType === "function" && targetType._IsNullstone) {
                var converter = Fayde.TypeConverters[targetType._TypeName];
                if (converter != null)
                    return converter(val);
            } else if (targetType instanceof Enum) {
                if (typeof val === "string") {
                    return targetType.Object[val];
                }
            } else if (typeof targetType === "number") {
                if (typeof val === "number")
                    return val;
                return parseFloat(val);
            }

            if (typeof targetType === "string")
                return doStringConversion ? val.toString() : "";

            var tc;
            if (propd._IsAttached) {
                //TODO: Find type converter for attached property
            } else {
                //TODO: Find type converter
            }
            return val;

            //TODO: Default to basic type converter, return
            //if (tc == null)
            //tc = new TypeConverter();
            //return tc.ConvertFrom(val);
        },
        GeometryFromString: function (val) {
            return Fayde._MediaParser.ParseGeometry(val);
        },
        PointCollectionFromString: function (val) {
            return Fayde._MediaParser.ParsePointCollection(val);
        }
    }
};

//#endregion<commit_msg>Fixed regression bug in type converter. Trying to convert from Thickness to Thickness.<commit_after>/// <reference path="../Runtime/Nullstone.js"/>
/// CODE
/// <reference path="../Media/MediaParser.js"/>

//#region Fayde

var Fayde = {
    TypeConverters: {
        Thickness: function (str) {
            /// <param name="str" type="String"></param>
            if (!str)
                return new Thickness();
            var tokens = str.split(",");
            var left, top, right, bottom;
            if (tokens.length === 1) {
                left = top = right = bottom = parseFloat(tokens[0]);
            } else if (tokens.length === 2) {
                left = right = parseFloat(tokens[0]);
                top = bottom = parseFloat(tokens[1]);
            } else if (tokens.length === 4) {
                left = parseFloat(tokens[0]);
                top = parseFloat(tokens[1]);
                right = parseFloat(tokens[2]);
                bottom = parseFloat(tokens[3]);
            } else {
                throw new ParseException("Cannot parse Thickness value '" + str + "'");
            }
            return new Thickness(left, top, right, bottom);
        },
        CornerRadius: function (str) {
            /// <param name="str" type="String"></param>
            if (!str)
                return new Thickness();
            var tokens = str.split(",");
            var topLeft, topRight, bottomRight, bottomLeft;
            if (tokens.length === 1) {
                topLeft = topRight = bottomRight = bottomLeft = parseFloat(tokens[0]);
            } else if (tokens.length === 4) {
                topLeft = parseFloat(tokens[0]);
                topRight = parseFloat(tokens[1]);
                bottomLeft = parseFloat(tokens[2]);
                bottomRight = parseFloat(tokens[3]);
            } else {
                throw new ParseException("Cannot parse CornerRadius value '" + str + "'");
            }
        }
    },
    TypeConverter: {
        ConvertObject: function (propd, val, objectType, doStringConversion) {
            /// <param name="propd" type="DependencyProperty"></param>
            /// <param name="val" type="Object"></param>
            /// <param name="objectType" type="Function"></param>
            /// <param name="doStringConversion" type="Boolean"></param>

            if (val == null)
                return val;

            var targetType = propd.GetTargetType();
            if (typeof targetType === "function" && targetType._IsNullstone) {
                if (val instanceof targetType)
                    return val;
                var converter = Fayde.TypeConverters[targetType._TypeName];
                if (converter != null)
                    return converter(val);
            } else if (targetType instanceof Enum) {
                if (typeof val === "string") {
                    return targetType.Object[val];
                }
            } else if (typeof targetType === "number") {
                if (typeof val === "number")
                    return val;
                return parseFloat(val);
            }

            if (typeof targetType === "string")
                return doStringConversion ? val.toString() : "";

            var tc;
            if (propd._IsAttached) {
                //TODO: Find type converter for attached property
            } else {
                //TODO: Find type converter
            }
            return val;

            //TODO: Default to basic type converter, return
            //if (tc == null)
            //tc = new TypeConverter();
            //return tc.ConvertFrom(val);
        },
        GeometryFromString: function (val) {
            return Fayde._MediaParser.ParseGeometry(val);
        },
        PointCollectionFromString: function (val) {
            return Fayde._MediaParser.ParsePointCollection(val);
        }
    }
};

//#endregion<|endoftext|>


<commit_before>var nextTick = require('next-tick')
var isPromise = require('is-promise')

module.exports = Promise
function Promise(fn) {
  if (!(this instanceof Promise)) return new Promise(fn)
  if (typeof fn !== 'function') throw new TypeError('not a function')
  var state = null
    , value = null
    , resolved = false
    , deferreds = []

  this.then = function(onFulfilled, onRejected) {
    return new Promise(function(resolve, reject) {
      handle({ onFulfilled: onFulfilled, onRejected: onRejected, resolve: resolve, reject: reject })
    })
  }

  function handle(deferred) {
    if (state === null) {
      deferreds.push(deferred)
      return
    }
    nextTick(function() {
      var cb = state ? deferred.onFulfilled : deferred.onRejected
      if (typeof cb !== 'function'){
        (state ? deferred.resolve : deferred.reject)(value)
        return
      }
      var ret
      try {
        ret = cb(value)
      }
      catch (e) {
        deferred.reject(e)
        return
      }
      deferred.resolve(ret)
    })
  }

  function resolve(newValue) {
    if (state !== null)
      return
    if (isPromise(newValue)) {
      newValue.then(resolve, reject)
      return
    }
    state = true
    value = newValue
    finale()
  }

  function reject(newValue) {
    if (state !== null)
      return
    state = false
    value = newValue
    finale()
  }

  function finale() {
    for (var i = 0, len = deferreds.length; i < len; i++)
      handle(deferreds[i])
    deferreds = null
  }

  function ifUnResolved(fn) {
    return function (value) {
      if (resolved) return
      resolved = true
      return fn(value)
    }
  }

  try { fn(ifUnResolved(resolve), ifUnResolved(reject)) }
  catch(e) { ifUnResolved(reject)(e) }
}
<commit_msg>handle the resolved-with-promise case correctly<commit_after>var nextTick = require('next-tick')
var isPromise = require('is-promise')

module.exports = Promise
function Promise(fn) {
  if (!(this instanceof Promise)) return new Promise(fn)
  if (typeof fn !== 'function') throw new TypeError('not a function')
  var state = null
    , delegating = false
    , value = null
    , deferreds = []

  this.then = function(onFulfilled, onRejected) {
    return new Promise(function(resolve, reject) {
      handle({ onFulfilled: onFulfilled, onRejected: onRejected, resolve: resolve, reject: reject })
    })
  }

  function handle(deferred) {
    if (state === null) {
      deferreds.push(deferred)
      return
    }
    nextTick(function() {
      var cb = state ? deferred.onFulfilled : deferred.onRejected
      if (typeof cb !== 'function'){
        (state ? deferred.resolve : deferred.reject)(value)
        return
      }
      var ret
      try {
        ret = cb(value)
      }
      catch (e) {
        deferred.reject(e)
        return
      }
      deferred.resolve(ret)
    })
  }

  function resolve(newValue) {
    if (delegating)
      return
    resolve_(newValue)
  }

  function resolve_(newValue) {
    if (state !== null)
      return
    if (isPromise(newValue)) {
      delegating = true
      newValue.then(resolve_, reject_)
      return
    }
    state = true
    value = newValue
    finale()
  }

  function reject(newValue) {
    if (delegating)
      return
    reject_(newValue)
  }

  function reject_(newValue) {
    if (state !== null)
      return
    state = false
    value = newValue
    finale()
  }

  function finale() {
    for (var i = 0, len = deferreds.length; i < len; i++)
      handle(deferreds[i])
    deferreds = null
  }

  try { fn(resolve, reject) }
  catch(e) { reject(e) }
}
<|endoftext|>


<commit_before>
// function () {
//   var port = app.get('port');
//   if (arguments.length >= 1) {
//     port = arguments[0];
//   }
//
//   if (!module.parent) {
//     return app.listen(port, function () {
//       console.log('Base2 start at port %d', app.get('port'));
//     });
//   }
//
//   process.on('uncaughtException', function (err) {
//     console.error('Uncaught exception:', err, err.stack);
//     // Exception
//     switch (err.errno) {
//       case 'EADDRINUSE': // 端口被占用
//         process.exit(5001);
//         break;
//       default:
//       //
//     }
//   });
// };

module.exports = function (config) {
  var app = require('./app')(config);

  app.start = app.listen;

  return app;
};
<commit_msg>refact<commit_after>module.exports = function (config) {
  var app = require('./app')(config);

  app.start = app.listen;

  return app;
};
<|endoftext|>


<commit_before>L.PhotonBase = L.Class.extend({

    forEach: function (els, callback) {
        Array.prototype.forEach.call(els, callback);
    },

    ajax: function (callback, thisobj) {
        if (typeof this.xhr === 'object') {
            this.xhr.abort();
        }
        this.xhr = new XMLHttpRequest();
        var self = this;
        this.xhr.open('GET', this.options.url + this.buildQueryString(this.getParams()), true);

        this.xhr.onload = function(e) {
            self.fire('ajax:return');
            if (this.status === 200) {
                if (callback) {
                    var raw = this.response;
                    raw = JSON.parse(raw);
                    callback.call(thisobj || this, raw);
                }
            }
            delete this.xhr;
        };

        this.fire('ajax:send');
        this.xhr.send();
    },

    buildQueryString: function (params) {
        var queryString = [];
        for (var key in params) {
            if (params[key]) {
                queryString.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
            }
        }
        return queryString.join('&');
    },

    featureToPopupContent: function (feature) {
        var container = L.DomUtil.create('div', 'leaflet-photon-popup'),
            title = L.DomUtil.create('h3', '', container);
        title.innerHTML = feature.properties.label;
        return container;
    }

});

L.PhotonBaseSearch = L.PhotonBase.extend({

    includes: L.Mixin.Events,

    options: {
        url: 'https://photon.komoot.de/api/?',
        placeholder: 'Start typing...',
        minChar: 3,
        limit: 5,
        submitDelay: 300,
        includePosition: true,
        noResultLabel: 'No result',
        feedbackEmail: 'photon@komoot.de',  // Set to null to remove feedback box
        feedbackLabel: 'Feedback'
    },

    CACHE: '',
    RESULTS: [],
    KEYS: {
        LEFT: 37,
        UP: 38,
        RIGHT: 39,
        DOWN: 40,
        TAB: 9,
        RETURN: 13,
        ESC: 27,
        APPLE: 91,
        SHIFT: 16,
        ALT: 17,
        CTRL: 18
    },

    initialize: function (input, options) {
        this.input = input;
        L.setOptions(this, options);
        var CURRENT = null;

        try {
            Object.defineProperty(this, 'CURRENT', {
                get: function () {
                    return CURRENT;
                },
                set: function (index) {
                    if (typeof index === 'object') {
                        index = this.resultToIndex(index);
                    }
                    CURRENT = index;
                }
            });
        } catch (e) {
            // Hello IE8
        }
        this.input.type = L.Browser.ie ? 'text' : 'search';
        this.input.placeholder = this.options.placeholder;
        this.input.autocomplete = 'off';
        this.input.autocorrect = 'off';
        L.DomEvent.disableClickPropagation(this.input);

        L.DomEvent.on(this.input, 'keydown', this.onKeyDown, this);
        L.DomEvent.on(this.input, 'input', this.onInput, this);
        L.DomEvent.on(this.input, 'blur', this.onBlur, this);
        L.DomEvent.on(this.input, 'focus', this.onFocus, this);
        this.createResultsContainer();
    },

    createResultsContainer: function () {
        this.resultsContainer = this.options.resultsContainer || L.DomUtil.create('ul', 'photon-autocomplete', document.querySelector('body'));
    },

    resizeContainer: function()
    {
        var l = this.getLeft(this.input);
        var t = this.getTop(this.input) + this.input.offsetHeight;
        this.resultsContainer.style.left = l + 'px';
        this.resultsContainer.style.top = t + 'px';
        var width = this.options.width ? this.options.width : this.input.offsetWidth - 2;
        this.resultsContainer.style.width = width + 'px';
    },

    onKeyDown: function (e) {
        switch (e.keyCode) {
            case this.KEYS.TAB:
                if(this.CURRENT !== null)
                {
                    this.setChoice();
                }
                L.DomEvent.stop(e);
                break;
            case this.KEYS.RETURN:
                L.DomEvent.stop(e);
                this.setChoice();
                break;
            case this.KEYS.ESC:
                L.DomEvent.stop(e);
                this.hide();
                this.input.blur();
                break;
            case this.KEYS.DOWN:
                if(this.RESULTS.length > 0) {
                    if(this.CURRENT !== null && this.CURRENT < this.RESULTS.length - 1) { // what if one resutl?
                        this.CURRENT++;
                        this.highlight();
                    }
                    else if(this.CURRENT === null) {
                        this.CURRENT = 0;
                        this.highlight();
                    }
                }
                break;
            case this.KEYS.UP:
                if(this.CURRENT !== null) {
                    L.DomEvent.stop(e);
                }
                if(this.RESULTS.length > 0) {
                    if(this.CURRENT > 0) {
                        this.CURRENT--;
                        this.highlight();
                    }
                    else if(this.CURRENT === 0) {
                        this.CURRENT = null;
                        this.highlight();
                    }
                }
                break;
        }
    },

    onInput: function (e) {
        if (typeof this.submitDelay === 'number') {
            window.clearTimeout(this.submitDelay);
            delete this.submitDelay;
        }
        this.submitDelay = window.setTimeout(L.Util.bind(this.search, this), this.options.submitDelay);
    },

    onBlur: function (e) {
        this.fire('blur');
        var self = this;
        setTimeout(function () {
            self.hide();
        }, 100);
    },

    onFocus: function (e) {
        this.fire('focus');
        this.input.select();
        this.search();  // In case we have a value from a previous search.
    },

    clear: function () {
        this.RESULTS = [];
        this.CURRENT = null;
        this.CACHE = '';
        this.resultsContainer.innerHTML = '';
    },

    hide: function() {
        this.fire('hide');
        this.clear();
        this.resultsContainer.style.display = 'none';
    },

    setChoice: function (choice) {
        choice = choice || this.RESULTS[this.CURRENT];
        if (choice) {
            this.hide();
            this.fire('selected', {choice: choice.feature});
            this.onSelected(choice.feature);
            this.input.value = '';
        }
    },

    search: function() {
        var val = this.input.value;
        var minChar = typeof this.options.minChar === 'function' ? this.options.minChar(val) : val.length >= this.options.minChar;
        if (!val || !minChar) return this.clear();
        if(val + '' === this.CACHE + '') return;
        else this.CACHE = val;
        this._doSearch();
    },

    _doSearch: function () {
        this.ajax(this.handleResults, this);
    },

    _onSelected: function (feature) {
    },

    onSelected: function (choice) {
        return (this.options.onSelected || this._onSelected).call(this, choice);
    },

    _formatResult: function (feature, el) {
        var title = L.DomUtil.create('strong', '', el),
            detailsContainer = L.DomUtil.create('small', '', el),
            details = [],
            type = this.formatType(feature);
        title.innerHTML = feature.properties.name;
        if (type) details.push(type);
        if (feature.properties.city && feature.properties.city !== feature.properties.name) {
            details.push(feature.properties.city);
        }
        if (feature.properties.country) details.push(feature.properties.country);
        detailsContainer.innerHTML = details.join(', ');
    },

    formatResult: function (feature, el) {
        return (this.options.formatResult || this._formatResult).call(this, feature, el);
    },

    formatType: function (feature) {
        return (this.options.formatType || this._formatType).call(this, feature);
    },

    _formatType: function (feature) {
        return feature.properties.osm_value;
    },

    createResult: function (feature) {
        var el = L.DomUtil.create('li', '', this.resultsContainer);
        this.formatResult(feature, el);
        var result = {
            feature: feature,
            el: el
        };
        // Touch handling needed
        L.DomEvent.on(el, 'mouseover', function (e) {
            this.CURRENT = result;
            this.highlight();
        }, this);
        L.DomEvent.on(el, 'mousedown', function (e) {
            this.setChoice();
        }, this);
        return result;
    },

    resultToIndex: function (result) {
        var out = null;
        this.forEach(this.RESULTS, function (item, index) {
            if (item === result) {
                out = index;
                return;
            }
        });
        return out;
    },

    handleResults: function(geojson) {
        var self = this;
        this.clear();
        this.resultsContainer.style.display = 'block';
        this.resizeContainer();
        this.forEach(geojson.features, function (feature) {
            self.RESULTS.push(self.createResult(feature));
        });
        if (geojson.features.length === 0) {
            var noresult = L.DomUtil.create('li', 'photon-no-result', this.resultsContainer);
            noresult.innerHTML = this.options.noResultLabel;
        }
        if (this.options.feedbackEmail) {
            var feedback = L.DomUtil.create('a', 'photon-feedback', this.resultsContainer);
            feedback.href = 'mailto:' + this.options.feedbackEmail;
            feedback.innerHTML = this.options.feedbackLabel;
        }
        this.CURRENT = 0;
        this.highlight();
        if (this.options.resultsHandler) {
            this.options.resultsHandler(geojson);
        }
    },

    highlight: function () {
        var self = this;
        this.forEach(this.RESULTS, function (item, index) {
            if (index === self.CURRENT) {
                L.DomUtil.addClass(item.el, 'on');
            }
            else {
                L.DomUtil.removeClass(item.el, 'on');
            }
        });
    },

    getLeft: function (el) {
        var tmp = el.offsetLeft;
        el = el.offsetParent;
        while(el) {
            tmp += el.offsetLeft;
            el = el.offsetParent;
        }
        return tmp;
    },

    getTop: function (el) {
        var tmp = el.offsetTop;
        el = el.offsetParent;
        while(el) {
            tmp += el.offsetTop;
            el = el.offsetParent;
        }
        return tmp;
    },

    getParams: function () {
        return {
            q: this.CACHE,
            lang: this.options.lang,
            limit: this.options.limit
        };
    }

});

L.PhotonSearch = L.PhotonBaseSearch.extend({

    initialize: function (map, input, options) {
        this.map = map;
        L.PhotonBaseSearch.prototype.initialize.call(this, input, options);
    },

    _onSelected: function (feature) {
        this.map.setView([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], 16);
    },

    getParams: function () {
        var params = L.PhotonBaseSearch.prototype.getParams.call(this);
        if (this.options.includePosition) {
            params.lat = this.map.getCenter().lat;
            params.lon = this.map.getCenter().lng;
        }
        return params;
    }

});

L.Control.Photon = L.Control.extend({

    includes: L.Mixin.Events,

    onAdd: function (map, options) {
        this.map = map;
        this.container = L.DomUtil.create('div', 'leaflet-photon');

        this.options = L.Util.extend(this.options, options);

        this.input = L.DomUtil.create('input', 'photon-input', this.container);
        this.search = new L.PhotonSearch(map, this.input, this.options);
        this.search.on('blur', this.forwardEvent, this);
        this.search.on('focus', this.forwardEvent, this);
        this.search.on('hide', this.forwardEvent, this);
        this.search.on('selected', this.forwardEvent, this);
        this.search.on('ajax:send', this.forwardEvent, this);
        this.search.on('ajax:return', this.forwardEvent, this);
        return this.container;
    },

    // TODO onRemove

    forwardEvent: function (e) {
        this.fire(e.type, e);
    }

});

L.control.photon = function(options) {
    return new L.Control.Photon(options);
}

L.Map.addInitHook(function () {
    if (this.options.photonControl) {
        this.photonControl = new L.Control.Photon(this.options.photonControlOptions || {});
        this.addControl(this.photonControl);
    }
});

L.PhotonReverse = L.PhotonBase.extend({

    includes: L.Mixin.Events,

    options: {
        url: 'http://photon.komoot.de/reverse/?',
        limit: 1,
        handleResults: null
    },

    initialize: function (options) {
        L.setOptions(this, options);
    },

    doReverse: function (latlng) {
        latlng = L.latLng(latlng);
        this.fire('reverse', {latlng: latlng});
        this.latlng = latlng;
        this.ajax(this.handleResults, this);
    },

    _handleResults: function (data) {
        /*eslint-disable no-console */
        console.log(data);
        /*eslint-enable no-alert */
    },

    handleResults: function (data) {
        return (this.options.handleResults || this._handleResults).call(this, data);
    },

    getParams: function () {
        return {
            lang: this.options.lang,
            limit: this.options.limit,
            lat: this.latlng.lat,
            lon: this.latlng.lng
        };
    }

});
<commit_msg>Changed L.Mixin.Events include<commit_after>L.PhotonBase = L.Class.extend({

    forEach: function (els, callback) {
        Array.prototype.forEach.call(els, callback);
    },

    ajax: function (callback, thisobj) {
        if (typeof this.xhr === 'object') {
            this.xhr.abort();
        }
        this.xhr = new XMLHttpRequest();
        var self = this;
        this.xhr.open('GET', this.options.url + this.buildQueryString(this.getParams()), true);

        this.xhr.onload = function(e) {
            self.fire('ajax:return');
            if (this.status === 200) {
                if (callback) {
                    var raw = this.response;
                    raw = JSON.parse(raw);
                    callback.call(thisobj || this, raw);
                }
            }
            delete this.xhr;
        };

        this.fire('ajax:send');
        this.xhr.send();
    },

    buildQueryString: function (params) {
        var queryString = [];
        for (var key in params) {
            if (params[key]) {
                queryString.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
            }
        }
        return queryString.join('&');
    },

    featureToPopupContent: function (feature) {
        var container = L.DomUtil.create('div', 'leaflet-photon-popup'),
            title = L.DomUtil.create('h3', '', container);
        title.innerHTML = feature.properties.label;
        return container;
    }

});

L.PhotonBaseSearch = L.PhotonBase.extend({

    includes: ((typeof L.Evented !== 'undefined' && L.Evented.prototype) || L.Mixin.Events),

    options: {
        url: 'https://photon.komoot.de/api/?',
        placeholder: 'Start typing...',
        minChar: 3,
        limit: 5,
        submitDelay: 300,
        includePosition: true,
        noResultLabel: 'No result',
        feedbackEmail: 'photon@komoot.de',  // Set to null to remove feedback box
        feedbackLabel: 'Feedback'
    },

    CACHE: '',
    RESULTS: [],
    KEYS: {
        LEFT: 37,
        UP: 38,
        RIGHT: 39,
        DOWN: 40,
        TAB: 9,
        RETURN: 13,
        ESC: 27,
        APPLE: 91,
        SHIFT: 16,
        ALT: 17,
        CTRL: 18
    },

    initialize: function (input, options) {
        this.input = input;
        L.setOptions(this, options);
        var CURRENT = null;

        try {
            Object.defineProperty(this, 'CURRENT', {
                get: function () {
                    return CURRENT;
                },
                set: function (index) {
                    if (typeof index === 'object') {
                        index = this.resultToIndex(index);
                    }
                    CURRENT = index;
                }
            });
        } catch (e) {
            // Hello IE8
        }
        this.input.type = L.Browser.ie ? 'text' : 'search';
        this.input.placeholder = this.options.placeholder;
        this.input.autocomplete = 'off';
        this.input.autocorrect = 'off';
        L.DomEvent.disableClickPropagation(this.input);

        L.DomEvent.on(this.input, 'keydown', this.onKeyDown, this);
        L.DomEvent.on(this.input, 'input', this.onInput, this);
        L.DomEvent.on(this.input, 'blur', this.onBlur, this);
        L.DomEvent.on(this.input, 'focus', this.onFocus, this);
        this.createResultsContainer();
    },

    createResultsContainer: function () {
        this.resultsContainer = this.options.resultsContainer || L.DomUtil.create('ul', 'photon-autocomplete', document.querySelector('body'));
    },

    resizeContainer: function()
    {
        var l = this.getLeft(this.input);
        var t = this.getTop(this.input) + this.input.offsetHeight;
        this.resultsContainer.style.left = l + 'px';
        this.resultsContainer.style.top = t + 'px';
        var width = this.options.width ? this.options.width : this.input.offsetWidth - 2;
        this.resultsContainer.style.width = width + 'px';
    },

    onKeyDown: function (e) {
        switch (e.keyCode) {
            case this.KEYS.TAB:
                if(this.CURRENT !== null)
                {
                    this.setChoice();
                }
                L.DomEvent.stop(e);
                break;
            case this.KEYS.RETURN:
                L.DomEvent.stop(e);
                this.setChoice();
                break;
            case this.KEYS.ESC:
                L.DomEvent.stop(e);
                this.hide();
                this.input.blur();
                break;
            case this.KEYS.DOWN:
                if(this.RESULTS.length > 0) {
                    if(this.CURRENT !== null && this.CURRENT < this.RESULTS.length - 1) { // what if one resutl?
                        this.CURRENT++;
                        this.highlight();
                    }
                    else if(this.CURRENT === null) {
                        this.CURRENT = 0;
                        this.highlight();
                    }
                }
                break;
            case this.KEYS.UP:
                if(this.CURRENT !== null) {
                    L.DomEvent.stop(e);
                }
                if(this.RESULTS.length > 0) {
                    if(this.CURRENT > 0) {
                        this.CURRENT--;
                        this.highlight();
                    }
                    else if(this.CURRENT === 0) {
                        this.CURRENT = null;
                        this.highlight();
                    }
                }
                break;
        }
    },

    onInput: function (e) {
        if (typeof this.submitDelay === 'number') {
            window.clearTimeout(this.submitDelay);
            delete this.submitDelay;
        }
        this.submitDelay = window.setTimeout(L.Util.bind(this.search, this), this.options.submitDelay);
    },

    onBlur: function (e) {
        this.fire('blur');
        var self = this;
        setTimeout(function () {
            self.hide();
        }, 100);
    },

    onFocus: function (e) {
        this.fire('focus');
        this.input.select();
        this.search();  // In case we have a value from a previous search.
    },

    clear: function () {
        this.RESULTS = [];
        this.CURRENT = null;
        this.CACHE = '';
        this.resultsContainer.innerHTML = '';
    },

    hide: function() {
        this.fire('hide');
        this.clear();
        this.resultsContainer.style.display = 'none';
    },

    setChoice: function (choice) {
        choice = choice || this.RESULTS[this.CURRENT];
        if (choice) {
            this.hide();
            this.fire('selected', {choice: choice.feature});
            this.onSelected(choice.feature);
            this.input.value = '';
        }
    },

    search: function() {
        var val = this.input.value;
        var minChar = typeof this.options.minChar === 'function' ? this.options.minChar(val) : val.length >= this.options.minChar;
        if (!val || !minChar) return this.clear();
        if(val + '' === this.CACHE + '') return;
        else this.CACHE = val;
        this._doSearch();
    },

    _doSearch: function () {
        this.ajax(this.handleResults, this);
    },

    _onSelected: function (feature) {
    },

    onSelected: function (choice) {
        return (this.options.onSelected || this._onSelected).call(this, choice);
    },

    _formatResult: function (feature, el) {
        var title = L.DomUtil.create('strong', '', el),
            detailsContainer = L.DomUtil.create('small', '', el),
            details = [],
            type = this.formatType(feature);
        title.innerHTML = feature.properties.name;
        if (type) details.push(type);
        if (feature.properties.city && feature.properties.city !== feature.properties.name) {
            details.push(feature.properties.city);
        }
        if (feature.properties.country) details.push(feature.properties.country);
        detailsContainer.innerHTML = details.join(', ');
    },

    formatResult: function (feature, el) {
        return (this.options.formatResult || this._formatResult).call(this, feature, el);
    },

    formatType: function (feature) {
        return (this.options.formatType || this._formatType).call(this, feature);
    },

    _formatType: function (feature) {
        return feature.properties.osm_value;
    },

    createResult: function (feature) {
        var el = L.DomUtil.create('li', '', this.resultsContainer);
        this.formatResult(feature, el);
        var result = {
            feature: feature,
            el: el
        };
        // Touch handling needed
        L.DomEvent.on(el, 'mouseover', function (e) {
            this.CURRENT = result;
            this.highlight();
        }, this);
        L.DomEvent.on(el, 'mousedown', function (e) {
            this.setChoice();
        }, this);
        return result;
    },

    resultToIndex: function (result) {
        var out = null;
        this.forEach(this.RESULTS, function (item, index) {
            if (item === result) {
                out = index;
                return;
            }
        });
        return out;
    },

    handleResults: function(geojson) {
        var self = this;
        this.clear();
        this.resultsContainer.style.display = 'block';
        this.resizeContainer();
        this.forEach(geojson.features, function (feature) {
            self.RESULTS.push(self.createResult(feature));
        });
        if (geojson.features.length === 0) {
            var noresult = L.DomUtil.create('li', 'photon-no-result', this.resultsContainer);
            noresult.innerHTML = this.options.noResultLabel;
        }
        if (this.options.feedbackEmail) {
            var feedback = L.DomUtil.create('a', 'photon-feedback', this.resultsContainer);
            feedback.href = 'mailto:' + this.options.feedbackEmail;
            feedback.innerHTML = this.options.feedbackLabel;
        }
        this.CURRENT = 0;
        this.highlight();
        if (this.options.resultsHandler) {
            this.options.resultsHandler(geojson);
        }
    },

    highlight: function () {
        var self = this;
        this.forEach(this.RESULTS, function (item, index) {
            if (index === self.CURRENT) {
                L.DomUtil.addClass(item.el, 'on');
            }
            else {
                L.DomUtil.removeClass(item.el, 'on');
            }
        });
    },

    getLeft: function (el) {
        var tmp = el.offsetLeft;
        el = el.offsetParent;
        while(el) {
            tmp += el.offsetLeft;
            el = el.offsetParent;
        }
        return tmp;
    },

    getTop: function (el) {
        var tmp = el.offsetTop;
        el = el.offsetParent;
        while(el) {
            tmp += el.offsetTop;
            el = el.offsetParent;
        }
        return tmp;
    },

    getParams: function () {
        return {
            q: this.CACHE,
            lang: this.options.lang,
            limit: this.options.limit
        };
    }

});

L.PhotonSearch = L.PhotonBaseSearch.extend({

    initialize: function (map, input, options) {
        this.map = map;
        L.PhotonBaseSearch.prototype.initialize.call(this, input, options);
    },

    _onSelected: function (feature) {
        this.map.setView([feature.geometry.coordinates[1], feature.geometry.coordinates[0]], 16);
    },

    getParams: function () {
        var params = L.PhotonBaseSearch.prototype.getParams.call(this);
        if (this.options.includePosition) {
            params.lat = this.map.getCenter().lat;
            params.lon = this.map.getCenter().lng;
        }
        return params;
    }

});

L.Control.Photon = L.Control.extend({

    includes: ((typeof L.Evented !== 'undefined' && L.Evented.prototype) || L.Mixin.Events),

    onAdd: function (map, options) {
        this.map = map;
        this.container = L.DomUtil.create('div', 'leaflet-photon');

        this.options = L.Util.extend(this.options, options);

        this.input = L.DomUtil.create('input', 'photon-input', this.container);
        this.search = new L.PhotonSearch(map, this.input, this.options);
        this.search.on('blur', this.forwardEvent, this);
        this.search.on('focus', this.forwardEvent, this);
        this.search.on('hide', this.forwardEvent, this);
        this.search.on('selected', this.forwardEvent, this);
        this.search.on('ajax:send', this.forwardEvent, this);
        this.search.on('ajax:return', this.forwardEvent, this);
        return this.container;
    },

    // TODO onRemove

    forwardEvent: function (e) {
        this.fire(e.type, e);
    }

});

L.control.photon = function(options) {
    return new L.Control.Photon(options);
}

L.Map.addInitHook(function () {
    if (this.options.photonControl) {
        this.photonControl = new L.Control.Photon(this.options.photonControlOptions || {});
        this.addControl(this.photonControl);
    }
});

L.PhotonReverse = L.PhotonBase.extend({

    includes: ((typeof L.Evented !== 'undefined' && L.Evented.prototype) || L.Mixin.Events),

    options: {
        url: 'http://photon.komoot.de/reverse/?',
        limit: 1,
        handleResults: null
    },

    initialize: function (options) {
        L.setOptions(this, options);
    },

    doReverse: function (latlng) {
        latlng = L.latLng(latlng);
        this.fire('reverse', {latlng: latlng});
        this.latlng = latlng;
        this.ajax(this.handleResults, this);
    },

    _handleResults: function (data) {
        /*eslint-disable no-console */
        console.log(data);
        /*eslint-enable no-alert */
    },

    handleResults: function (data) {
        return (this.options.handleResults || this._handleResults).call(this, data);
    },

    getParams: function () {
        return {
            lang: this.options.lang,
            limit: this.options.limit,
            lat: this.latlng.lat,
            lon: this.latlng.lng
        };
    }

});
<|endoftext|>


<commit_before>/*global path*/
define([
  'path'
], function (path) {
  process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
  return {
    getHomePath: getHomePath
  };
  function getHomePath () {
    var systemHomePath = process.env[(process.platform == 'win32') ? 'HOMEPATH' : 'HOME'];
    return systemHomePath;
  }
});
<commit_msg>removed forced tls ignore<commit_after>/*global path*/
define([
  'path'
], function (path) {
  return {
    getHomePath: getHomePath
  };
  function getHomePath () {
    var systemHomePath = process.env[(process.platform == 'win32') ? 'HOMEPATH' : 'HOME'];
    return systemHomePath;
  }
});
<|endoftext|>


<commit_before>// jshint node: true
'use strict';

var child_process = require('child_process'),
    spawnCommand = require('spawn-command'),
    chalk = require('chalk'),
    os = require('os'),
    hostname = os.hostname(),
    username = require('username').sync(),
    slice = Array.prototype.slice,
    defaults = {
        prompt: prompt
    };

exports.spawn = spawn;
exports.exec = exec;
exports.spawnSeries = spawnSeries;
exports.quoteArg = quoteArg;
exports.defaults = defaults;

/**
 * Add quote if needed
 * @param  {String} arg argument to quote
 * @return {String}     quoted argument
 */
function quoteArg(arg) {
    return /\s/.test(arg) ? '"' + arg.replace(/"/g, '\\') + '"' : arg;
}

/**
 * Spawn a command
 * Usage
 *     spawn(String cmd)
 *     spawn(String cmd, Array args)
 *     spawn(String cmd, Object options)
 *     spawn(String cmd, Function done)
 *     spawn(String cmd, Array args, Object options)
 *     spawn(String cmd, Array args, Function done)
 *     spawn(String cmd, Array args, Object options, Function done)
 * @param  {String}   cmd     command to execute
 * @param  {Array}    args    If specified, use child_process.spawn, else use spawn-command
 * @param  {Object}   options child process spawn options.
 * @param  {Function} done    called with arguments (code)
 * @return {ChildProcess}     child process
 */
function spawn() {
    var argv = _spawnArgs(arguments),
        cmd = argv[0],
        args = argv[1],
        options = argv[2],
        done = argv[3],
        child = _spawn(cmd, args, options, done);

    return child;
}

/**
 * Execute a command
 * Usage
 *     exec(String cmd)
 *     exec(String cmd, Array args)
 *     exec(String cmd, Object options)
 *     exec(String cmd, Function done)
 *     exec(String cmd, Array args, Object options)
 *     exec(String cmd, Array args, Function done)
 *     exec(String cmd, Array args, Object options, Function done)
 * @param  {String}   cmd     command to execute
 * @param  {Array}    args    If specified, use child_process.spawn, else use spawn-command
 * @param  {Object}   options child process spawn options.
 * @param  {Function} done    called with arguments (error, output, code)
 * @return {ChildProcess}     child process
 */
function exec() {
    var argv = _spawnArgs(arguments),
        cmd = argv[0],
        args = argv[1],
        options = argv[2],
        done = argv[3],
        out = [],
        err = [],
        count = 0,
        pipeout = emptyFn,
        pipeerr = emptyFn,
        child, stdout, stderr, stdio;

    stdio = options.stdio || 'pipe';
    options.stdio = 'pipe';

    if (stdio === 'inherit' || stdio[1] === 'inherit' || stdio[1] === 1 || stdio[1] === process.stdout) {
        pipeout = function(chunk) {
            process.stdout.write(chunk);
        };
    }

    if (stdio === 'inherit' || stdio[2] === 'inherit' || stdio[2] === 2 || stdio[2] === process.stderr) {
        pipeerr = function(chunk) {
            process.stderr.write(chunk);
        };
    }

    child = _spawn(cmd, args, options);

    count++;
    child.on('close', end);

    function end(code, signal) {
        if (code) {
            out.code = code;
        }

        if (--count === 0) {
            var output = out.join('');
            var error = err.join('');

            if (code === 0 && error.length === 0) {
                done(null, output, out.code);
            } else {
                done(error, output, out.code);
            }
        }
    }

    count++;
    child.stdout.on('data', function(chunk) {
        out.push(chunk);
        pipeout(chunk);
    });
    child.stdout.on('end', end);

    count++;
    child.stderr.on('data', function(chunk) {
        err.push(chunk);
        pipeerr(chunk);
    });
    child.stderr.on('end', end);

    return child;
}

/**
 * Spawn commands in series
 * Usage
 *     spawnSeries(Array commands)
 *     spawnSeries(Array commands, Object options)
 *     spawnSeries(Array commands, Function done)
 *     spawnSeries(Array commands, Object options, Function done)
 *     spawnSeries(Array commands, Object options, Function callback, Function done)
 * @param  {Array}    commands commands to execute. If command is an array, it will be considered as arguments of spawn
 * @param  {Object}   options  child process spawn options.
 * @param  {Function} callback called with arguments (cmd, child, options, index)
 * @param  {Function} done     called with arguments (error)
 */
function spawnSeries(commands, options, callback, done) {
    var i = -1,
        _len = commands.length;

    switch (arguments.length) {
        case 1:
            options = {};
            callback = emptyFn;
            done = emptyFn;
            break;
        case 2:
            if (isFunction(options)) {
                done = options;
                options = {};
            } else {
                done = emptyFn;
            }
            callback = emptyFn;
            break;
        case 3:
            if (isFunction(callback)) {
                done = callback;
                callback = emptyFn;
            }
            break;
    }

    iterate(0);

    function iterate(err) {
        var child, cmd, argv, args, opts, next;
        if (!err && ++i < _len) {
            cmd = commands[i];
            if (Array.isArray(cmd)) {
                argv = _spawnArgs(cmd);
                args = argv[1];
                opts = extend({}, options, argv[2]);
                next = argv[3];
                cmd = argv[0];
                child = _spawn(cmd, args, opts, next);
            } else if (isFunction(cmd)) {
                cmd(iterate);
                callback(cmd, child, opts, i);
                return;
            } else {
                opts = options;
                child = _spawn(cmd, null, opts, emptyFn);
            }
            child.once('exit', iterate);
            callback(cmd, child, opts, i);
        } else {
            done(err);
        }
    }
}

function _spawn(cmd, args, options, done) {
    var child;
    if (Array.isArray(args)) {
        if (options.prompt) {
            options.prompt(cmd + ' ' + args.map(quoteArg).join(' '), options.cwd, username, hostname, options);
        }
        child = child_process.spawn(cmd, args, options);
    } else {
        if (options.prompt) {
            options.prompt(cmd, options.cwd, username, hostname, options);
        }
        child = spawnCommand(cmd, options);
    }

    if ('function' === typeof done) {
        child.once('close', done);
    }

    return child;
}

function _spawnArgs(argv) {
    argv = slice.call(argv);
    var cmd = argv[0],
        args = argv[1],
        options = argv[2],
        done = argv[3];

    switch (argv.length) {
        case 1:
            // spawn cmd
            options = {};
            done = emptyFn;
            break;
        case 2:
            if (Array.isArray(argv[1])) {
                // spawn cmd, Array
                done = emptyFn;
            } else if ('function' === typeof argv[1]) {
                // spawn cmd, Function
                args = null;
                done = argv[1];
                options = {};
            } else if (argv[1] && 'object' === typeof argv[1]) {
                // spawn cmd, Object
                args = null;
                done = emptyFn;
                options = argv[1];
            } else {
                throw new Error('Invalid argv');
            }
            break;
        case 3:
            if (Array.isArray(argv[1])) {
                args = argv[1];
                if ('function' === typeof argv[2]) {
                    // spawn cmd, Array, Function
                    options = {};
                    done = argv[2];
                } else {
                    // spawn cmd, Array, Object
                    if (argv[2] && 'object' === typeof argv[2]) {
                        options = argv[2];
                    } else {
                        options = {};
                    }
                    done = emptyFn;
                }
            } else if (argv[1] && 'object' === typeof argv[1] && 'function' === typeof argv[2]) {
                // spawn cmd, Object, Function
                args = null;
                options = argv[1];
                done = argv[2];
            } else {
                throw new Error('Invalid arguments');
            }
            break;
        default:
            if (args && !Array.isArray(args)) {
                throw new Error('Invalid argument args');
            }

            if (options && 'object' !== typeof options) {
                throw new Error('Invalid argument options');
            }

            if (done && 'function' !== typeof done) {
                throw new Error('Invalid argument done');
            }

            if ('object' !== typeof options) {
                options = {};
            }

            if ('function' !== typeof done) {
                done = emptyFn;
            }
    }

    options = extend({}, defaults, options);

    if (options.prompt && 'function' !== typeof options.prompt) {
        options.prompt = defaults.prompt;
    }

    return [cmd, args, options, done];
}

function prompt(cmd, cwd, username, hostname) {
    var text = chalk.green(username + '@' + hostname) + ' ' + chalk.yellow(cwd || process.cwd()) + '\n$ ' + cmd;
    console.log(text);
}

function emptyFn() {}

function clone(obj) {
    var dst = {},
        prop;
    for (prop in obj) {
        dst[prop] = obj[prop];
    }

    return dst;
}

// ==============
// From jQuery
// ==============
function extend() {
    var src, copyIsArray, copy, name, options, clone,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // Handle a deep copy situation
    if (typeof target === "boolean") {
        deep = target;

        // skip the boolean and the target
        target = arguments[i] || {};
        i++;
    }

    // Handle case when target is a string or something (possible in deep copy)
    if (typeof target !== "object" && !isFunction(target)) {
        target = {};
    }

    for (; i < length; i++) {
        // Only deal with non-null/undefined values
        if ((options = arguments[i]) != null) {
            // Extend the base object
            for (name in options) {
                src = target[name];
                copy = options[name];

                // Prevent never-ending loop
                if (target === copy) {
                    continue;
                }

                // Recurse if we're merging plain objects or arrays
                if (deep && copy && (isObject(copy) || (copyIsArray = Array.isArray(copy)))) {
                    if (copyIsArray) {
                        copyIsArray = false;
                        clone = src && Array.isArray(src) ? src : [];

                    } else {
                        clone = src && isObject(src) ? src : {};
                    }

                    // Never move original objects, clone them
                    target[name] = extend(deep, clone, copy);

                    // Don't bring in undefined values
                } else if (copy !== undefined) {
                    target[name] = copy;
                }
            }
        }
    }

    // Return the modified object
    return target;
}

// ==============
// From lodash
// ==============
var objToString = Object.prototype.toString;

function isObject(value) {
    // Avoid a V8 JIT bug in Chrome 19-20.
    // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
    var type = typeof value;
    return !!value && (type === 'object' || type === 'function');
}

function isFunction(value) {
    // The use of `Object#toString` avoids issues with the `typeof` operator
    // in older versions of Chrome and Safari which return 'function' for regexes
    // and Safari 8 which returns 'object' for typed array constructors.
    return isObject(value) && objToString.call(value) === '[object Function]';
}<commit_msg>fix options inherit in spawSeries<commit_after>// jshint node: true
'use strict';

var child_process = require('child_process'),
    spawnCommand = require('spawn-command'),
    chalk = require('chalk'),
    os = require('os'),
    hostname = os.hostname(),
    username = require('username').sync(),
    slice = Array.prototype.slice,
    defaults = {
        prompt: prompt
    };

exports.spawn = spawn;
exports.exec = exec;
exports.spawnSeries = spawnSeries;
exports.quoteArg = quoteArg;
exports.defaults = defaults;

/**
 * Add quote if needed
 * @param  {String} arg argument to quote
 * @return {String}     quoted argument
 */
function quoteArg(arg) {
    return /\s/.test(arg) ? '"' + arg.replace(/"/g, '\\') + '"' : arg;
}

/**
 * Spawn a command
 * Usage
 *     spawn(String cmd)
 *     spawn(String cmd, Array args)
 *     spawn(String cmd, Object options)
 *     spawn(String cmd, Function done)
 *     spawn(String cmd, Array args, Object options)
 *     spawn(String cmd, Array args, Function done)
 *     spawn(String cmd, Array args, Object options, Function done)
 * @param  {String}   cmd     command to execute
 * @param  {Array}    args    If specified, use child_process.spawn, else use spawn-command
 * @param  {Object}   options child process spawn options.
 * @param  {Function} done    called with arguments (code)
 * @return {ChildProcess}     child process
 */
function spawn() {
    var argv = _spawnArgs(arguments),
        cmd = argv[0],
        args = argv[1],
        options = argv[2],
        done = argv[3],
        child = _spawn(cmd, args, options, done);

    return child;
}

/**
 * Execute a command
 * Usage
 *     exec(String cmd)
 *     exec(String cmd, Array args)
 *     exec(String cmd, Object options)
 *     exec(String cmd, Function done)
 *     exec(String cmd, Array args, Object options)
 *     exec(String cmd, Array args, Function done)
 *     exec(String cmd, Array args, Object options, Function done)
 * @param  {String}   cmd     command to execute
 * @param  {Array}    args    If specified, use child_process.spawn, else use spawn-command
 * @param  {Object}   options child process spawn options.
 * @param  {Function} done    called with arguments (error, output, code)
 * @return {ChildProcess}     child process
 */
function exec() {
    var argv = _spawnArgs(arguments),
        cmd = argv[0],
        args = argv[1],
        options = argv[2],
        done = argv[3],
        out = [],
        err = [],
        count = 0,
        pipeout = emptyFn,
        pipeerr = emptyFn,
        child, stdout, stderr, stdio;

    stdio = options.stdio || 'pipe';
    options.stdio = 'pipe';

    if (stdio === 'inherit' || stdio[1] === 'inherit' || stdio[1] === 1 || stdio[1] === process.stdout) {
        pipeout = function(chunk) {
            process.stdout.write(chunk);
        };
    }

    if (stdio === 'inherit' || stdio[2] === 'inherit' || stdio[2] === 2 || stdio[2] === process.stderr) {
        pipeerr = function(chunk) {
            process.stderr.write(chunk);
        };
    }

    child = _spawn(cmd, args, options);

    count++;
    child.on('close', end);

    function end(code, signal) {
        if (code) {
            out.code = code;
        }

        if (--count === 0) {
            var output = out.join('');
            var error = err.join('');

            if (code === 0 && error.length === 0) {
                done(null, output, out.code);
            } else {
                done(error, output, out.code);
            }
        }
    }

    count++;
    child.stdout.on('data', function(chunk) {
        out.push(chunk);
        pipeout(chunk);
    });
    child.stdout.on('end', end);

    count++;
    child.stderr.on('data', function(chunk) {
        err.push(chunk);
        pipeerr(chunk);
    });
    child.stderr.on('end', end);

    return child;
}

/**
 * Spawn commands in series
 * Usage
 *     spawnSeries(Array commands)
 *     spawnSeries(Array commands, Object options)
 *     spawnSeries(Array commands, Function done)
 *     spawnSeries(Array commands, Object options, Function done)
 *     spawnSeries(Array commands, Object options, Function callback, Function done)
 * @param  {Array}    commands commands to execute. If command is an array, it will be considered as arguments of spawn
 * @param  {Object}   options  child process spawn options.
 * @param  {Function} callback called with arguments (cmd, child, options, index)
 * @param  {Function} done     called with arguments (error)
 */
function spawnSeries(commands, options, callback, done) {
    var i = -1,
        _len = commands.length;

    switch (arguments.length) {
        case 1:
            options = {};
            callback = emptyFn;
            done = emptyFn;
            break;
        case 2:
            if (isFunction(options)) {
                done = options;
                options = {};
            } else {
                done = emptyFn;
            }
            callback = emptyFn;
            break;
        case 3:
            if (isFunction(callback)) {
                done = callback;
                callback = emptyFn;
            }
            break;
    }

    iterate(0);

    function iterate(err) {
        var child, cmd, argv, args, opts, next;
        if (!err && ++i < _len) {
            cmd = commands[i];
            if (Array.isArray(cmd)) {
                argv = _spawnArgs(cmd, options);
                cmd = argv[0];
                args = argv[1];
                opts = argv[2];
                next = argv[3];
                child = _spawn(cmd, args, opts, next);
            } else if (isFunction(cmd)) {
                cmd(iterate);
                callback(cmd, child, opts, i);
                return;
            } else {
                opts = options;
                child = _spawn(cmd, null, opts, emptyFn);
            }
            child.once('exit', iterate);
            callback(cmd, child, opts, i);
        } else {
            done(err);
        }
    }
}

function _spawn(cmd, args, options, done) {
    var child;
    if (Array.isArray(args)) {
        if (options.prompt) {
            options.prompt(cmd + ' ' + args.map(quoteArg).join(' '), options.cwd, username, hostname, options);
        }
        child = child_process.spawn(cmd, args, options);
    } else {
        if (options.prompt) {
            options.prompt(cmd, options.cwd, username, hostname, options);
        }
        child = spawnCommand(cmd, options);
    }

    if ('function' === typeof done) {
        child.once('close', done);
    }

    return child;
}

function _spawnArgs(argv, currentDefaults) {
    argv = slice.call(argv);
    var cmd = argv[0],
        args = argv[1],
        options = argv[2],
        done = argv[3];

    switch (argv.length) {
        case 1:
            // spawn cmd
            options = {};
            done = emptyFn;
            break;
        case 2:
            if (Array.isArray(argv[1])) {
                // spawn cmd, Array
                done = emptyFn;
            } else if ('function' === typeof argv[1]) {
                // spawn cmd, Function
                args = null;
                done = argv[1];
                options = {};
            } else if (argv[1] && 'object' === typeof argv[1]) {
                // spawn cmd, Object
                args = null;
                done = emptyFn;
                options = argv[1];
            } else {
                throw new Error('Invalid argv');
            }
            break;
        case 3:
            if (Array.isArray(argv[1])) {
                args = argv[1];
                if ('function' === typeof argv[2]) {
                    // spawn cmd, Array, Function
                    options = {};
                    done = argv[2];
                } else {
                    // spawn cmd, Array, Object
                    if (argv[2] && 'object' === typeof argv[2]) {
                        options = argv[2];
                    } else {
                        options = {};
                    }
                    done = emptyFn;
                }
            } else if (argv[1] && 'object' === typeof argv[1] && 'function' === typeof argv[2]) {
                // spawn cmd, Object, Function
                args = null;
                options = argv[1];
                done = argv[2];
            } else {
                throw new Error('Invalid arguments');
            }
            break;
        default:
            if (args && !Array.isArray(args)) {
                throw new Error('Invalid argument args');
            }

            if (options && 'object' !== typeof options) {
                throw new Error('Invalid argument options');
            }

            if (done && 'function' !== typeof done) {
                throw new Error('Invalid argument done');
            }

            if ('object' !== typeof options) {
                options = {};
            }

            if ('function' !== typeof done) {
                done = emptyFn;
            }
    }

    options = extend({}, defaults, currentDefaults, options);

    if (options.prompt && 'function' !== typeof options.prompt) {
        options.prompt = defaults.prompt;
    }

    return [cmd, args, options, done];
}

function prompt(cmd, cwd, username, hostname) {
    var text = chalk.green(username + '@' + hostname) + ' ' + chalk.yellow(cwd || process.cwd()) + '\n$ ' + cmd;
    console.log(text);
}

function emptyFn() {}

function clone(obj) {
    var dst = {},
        prop;
    for (prop in obj) {
        dst[prop] = obj[prop];
    }

    return dst;
}

// ==============
// From jQuery
// ==============
function extend() {
    var src, copyIsArray, copy, name, options, clone,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // Handle a deep copy situation
    if (typeof target === "boolean") {
        deep = target;

        // skip the boolean and the target
        target = arguments[i] || {};
        i++;
    }

    // Handle case when target is a string or something (possible in deep copy)
    if (typeof target !== "object" && !isFunction(target)) {
        target = {};
    }

    for (; i < length; i++) {
        // Only deal with non-null/undefined values
        if ((options = arguments[i]) != null) {
            // Extend the base object
            for (name in options) {
                src = target[name];
                copy = options[name];

                // Prevent never-ending loop
                if (target === copy) {
                    continue;
                }

                // Recurse if we're merging plain objects or arrays
                if (deep && copy && (isObject(copy) || (copyIsArray = Array.isArray(copy)))) {
                    if (copyIsArray) {
                        copyIsArray = false;
                        clone = src && Array.isArray(src) ? src : [];

                    } else {
                        clone = src && isObject(src) ? src : {};
                    }

                    // Never move original objects, clone them
                    target[name] = extend(deep, clone, copy);

                    // Don't bring in undefined values
                } else if (copy !== undefined) {
                    target[name] = copy;
                }
            }
        }
    }

    // Return the modified object
    return target;
}

// ==============
// From lodash
// ==============
var objToString = Object.prototype.toString;

function isObject(value) {
    // Avoid a V8 JIT bug in Chrome 19-20.
    // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
    var type = typeof value;
    return !!value && (type === 'object' || type === 'function');
}

function isFunction(value) {
    // The use of `Object#toString` avoids issues with the `typeof` operator
    // in older versions of Chrome and Safari which return 'function' for regexes
    // and Safari 8 which returns 'object' for typed array constructors.
    return isObject(value) && objToString.call(value) === '[object Function]';
}<|endoftext|>