<commit_before>"use strict";

const path = require("path"),
	fs = require("fs"),
	retsu = require("retsu"),
	coerce = require("tiny-coerce"),
	mime = require("mimetype"),
	precise = require("precise"),
	regex = require(path.join(__dirname, "regex.js")),
	login = "/login",
	rateHeaders = [
		"x-ratelimit-limit",
		"x-ratelimit-remaining",
		"x-ratelimit-reset"
	];

function asyncFlag (req, res, next) {
	req.protectAsync = true;
	next();
}

function bypass (req, res, next) {
	req.unprotect = req.server.config.auth.unprotect.filter(i => i.test(req.url) === true).length > 0;
	next();
}

function file (req, res, next) {
	if (req.headers.expect !== void 0) {
		next(new Error(417));
	} else {
		const lpath = path.join(req.server.config.root, "www", req.parsed.pathname.replace(regex.dir, ""));

		fs.lstat(lpath, (e, stats) => {
			if (e !== null) {
				next(e);
			} else if (stats.isDirectory() === false) {
				req.file = {path: lpath, stats: stats};
				req.server.log("Routed request to disk", "debug");
				next();
			} else if (regex.get.test(req.method) === true && regex.dir.test(req.parsed.pathname) === false) {
				res.redirect((req.parsed.pathname !== "/" ? req.parsed.pathname : "") + "/" + req.parsed.search);
			} else {
				const nth = req.server.config.index.length;
				let count = 0,
					handled = false;

				if (nth > 0) {
					retsu.each(req.server.config.index, i => {
						const npath = path.join(lpath, i);

						fs.lstat(npath, (err, lstats) => {
							if (err === null && handled === false) {
								handled = true;
								req.file = {path: npath, stats: lstats};
								req.server.log("Routed request to disk", "debug");
								next();
							} else if (++count === nth && handled === false) {
								next();
							}
						});
					});
				} else {
					next();
				}
			}
		});
	}
}

function guard (req, res, next) {
	if (req.parsed.url === login || req.isAuthenticated() === true) {
		next();
	} else {
		res.redirect(login);
	}
}

function parse (req, res, next) {
	if (regex.body.test(req.method) === true && req.body !== void 0) {
		const type = req.headers["content-type"];

		if (regex.encode_form.test(type) === true) {
			const args = req.body ? retsu.chunk(req.body.split(regex.body_split), 2) : [];

			req.body = {};
			retsu.each(args, i => {
				req.body[i[0]] = coerce(decodeURIComponent(i[1]));
			});
		} else if (regex.encode_json.test(type) === true || regex.json_wrap.test(req.body) === true) {
			try {
				req.body = JSON.parse(req.body);
			} catch (e) {
				void 0;
			}
		}
	}

	next();
}

function payload (req, res, next) {
	req.invalid = false;

	if (regex.body.test(req.method) === true) {
		const obj = req.httpVersionMajor === 1 ? req : res;
		let body = "";

		obj.setEncoding("utf8");

		obj.on("data", data => {
			body += data;

			if (req.server.config.maxBytes > 0 && Buffer.byteLength(body) > req.server.config.maxBytes) {
				req.invalid = true;
				next(new Error(413));
			}
		});

		obj.on("end", () => {
			if (req.invalid === false) {
				if (body !== void 0) {
					req.body = body;
				}

				next();
			}
		});
	} else {
		next();
	}
}

function keymaster (req, res, next) {
	// No authentication, or it's already happened
	if (req.protect === false || req.protectAsync === false || (req.session !== void 0 && req.isAuthenticated() === true) === true) {
		const method = regex.get_rewrite.test(req.method) ? "get" : req.method.toLowerCase(),
			routes = req.server.router.middleware.get(method.toUpperCase()) || new Map(),
			uri = req.parsed.pathname;
		let result;

		if (routes.has(uri)) {
			result = routes.get(uri)[0];

			if (typeof result === "function") {
				result.call(req.server.tenso, req, res);
			} else {
				res.send(result);
			}
		} else {
			retsu.each(Array.from(routes.keys()), i => {
				let key = i;

				if (regex.has_param.test(i) === true && regex.leftBrace.test(i) === false) {
					key = i.replace(/\/:(\w*)/g, "/(.*)");
				}

				if (new RegExp(`^${key}$`, "i").test(uri) === true) {
					return !(result = routes.get(i)[0]);
				}

				return void 0;
			});

			if (result !== void 0) {
				if (typeof result === "function") {
					result.call(req.server.tenso, req, res);
				} else {
					res.send(result);
				}
			} else {
				next(new Error(404));
			}
		}
	} else {
		next(new Error(401));
	}
}

function rate (req, res, next) {
	if (req.server.config.rate.enabled === false || req.unprotect === true) {
		next();
	} else {
		const results = req.server.rate(req, req.server.config.rate.override),
			good = results.shift();

		retsu.each(rateHeaders, (i, idx) => res.header(i, results[idx]));

		if (good === true) {
			next();
		} else {
			next(new Error(req.server.config.rate.status || 429));
		}
	}
}

function stream (req, res, next) {
	if (req.file === void 0) {
		next(new Error(404));
	} else {
		const headers = {
			"content-length": req.file.stats.size,
			"content-type": mime.lookup(req.file.path),
			"last-modified": req.file.stats.mtime.toUTCString()
		};

		let status = 200,
			letag, options;

		if (req.server.canETag(req.parsed.pathname, req.method) === true) {
			letag = headers.etag = req.server.etag(req.parsed.pathname, req.file.stats.size, req.file.stats.mtime);
		}

		if (regex.get_only.test(req.method) === true) {
			if (letag !== void 0 && req.headers["if-none-match"] === letag) {
				delete headers["content-length"];
				res.send("", 304, headers);
			} else if (req.headers["if-none-match"] === void 0 && Date.parse(req.headers["if-modified-since"]) >= req.file.stats.mtime) {
				delete headers["content-length"];
				res.send("", 304, headers);
			} else if (req.server.router.http2 === false) {
				options = {};

				// Setting the partial content headers
				if (req.headers.range !== void 0) {
					retsu.each(req.headers.range.replace(/^.*=/, "").split(",")[0].split("-"), (i, idx) => {
						options[idx === 0 ? "start" : "end"] = i ? parseInt(i, 10) : void 0;
					});

					// Byte offsets
					if (isNaN(options.start) === true && isNaN(options.end) === false) {
						options.start = req.file.stats.size - options.end;
						options.end = req.file.stats.size;
					} else if (isNaN(options.end) === true) {
						options.end = req.file.stats.size;
					}

					if (options.start >= options.end || isNaN(options.start) === true || isNaN(options.end) === true) {
						return next(new Error(416));
					}

					status = 206;
					headers["content-range"] = `bytes ${options.start}-${options.end}/${req.file.stats.size}`;
					headers["content-length"] = options.end - options.start + 1;
				}

				res.send(fs.createReadStream(req.file.path, options), status, headers);
			} else if (req.headers.range !== void 0) {
				return next(new Error(416)); // Partial responses are not supported at this time for HTTP2
			} else {
				req.server.router.http2Send(req, res, req.file.path, status, headers);
			}
		} else {
			res.send("", 200, headers);
		}
	}

	return void 0;
}

function statik (req, res) {
	const pathname = req.parsed.pathname.replace(regex.root, ""),
		invalid = (pathname.replace(regex.dir, "").split("/").filter(i => i !== ".")[0] || "") === "..",
		outDir = !invalid ? (pathname.match(/\.{2}\//g) || []).length : 0,
		inDir = !invalid ? (pathname.match(/\w+?(\.\w+|\/)+/g) || []).length : 0;

	if (invalid === true) {
		res.error(404);
	} else if (outDir > 0 && outDir >= inDir) {
		res.error(404);
	} else {
		file(req, res, err2 => {
			if (err2 !== void 0) {
				res.error(404);
			} else {
				req.session = void 0;
				stream(req, res, err3 => {
					if (err3 !== void 0) {
						res.error(404);
					}
				});
			}
		});
	}
}

function timer (req, res, next) {
	req.timer = precise().start();
	next();
}

function zuul (req, res, next) {
	const uri = req.parsed.path;
	let protectd = false;

	if (regex.options.test(req.method) === false) {
		retsu.each(req.server.config.auth.protect, i => {
			if (i.test(uri) === true) {
				return !(protectd = true);
			}

			return void 0;
		});

		// Setting state so the connection can be terminated properly
		req.protect = protectd;
		req.protectAsync = false;

		rate(req, res, e => {
			if (e !== void 0) {
				next(e);
			} else if (protectd === true) {
				next();
			} else {
				keymaster(req, res, next);
			}
		});
	} else {
		res.send("OPTIONS requests are only support for CORS");
	}
}

module.exports = {
	asyncFlag: asyncFlag,
	bypass: bypass,
	guard: guard,
	parse: parse,
	payload: payload,
	rate: rate,
	"static": statik,
	timer: timer,
	zuul: zuul
};
<commit_msg>Optimizing `parse()` function<commit_after>"use strict";

const path = require("path"),
	fs = require("fs"),
	retsu = require("retsu"),
	coerce = require("tiny-coerce"),
	mime = require("mimetype"),
	precise = require("precise"),
	regex = require(path.join(__dirname, "regex.js")),
	login = "/login",
	rateHeaders = [
		"x-ratelimit-limit",
		"x-ratelimit-remaining",
		"x-ratelimit-reset"
	];

function asyncFlag (req, res, next) {
	req.protectAsync = true;
	next();
}

function bypass (req, res, next) {
	req.unprotect = req.server.config.auth.unprotect.filter(i => i.test(req.url) === true).length > 0;
	next();
}

function file (req, res, next) {
	if (req.headers.expect !== void 0) {
		next(new Error(417));
	} else {
		const lpath = path.join(req.server.config.root, "www", req.parsed.pathname.replace(regex.dir, ""));

		fs.lstat(lpath, (e, stats) => {
			if (e !== null) {
				next(e);
			} else if (stats.isDirectory() === false) {
				req.file = {path: lpath, stats: stats};
				req.server.log("Routed request to disk", "debug");
				next();
			} else if (regex.get.test(req.method) === true && regex.dir.test(req.parsed.pathname) === false) {
				res.redirect((req.parsed.pathname !== "/" ? req.parsed.pathname : "") + "/" + req.parsed.search);
			} else {
				const nth = req.server.config.index.length;
				let count = 0,
					handled = false;

				if (nth > 0) {
					retsu.each(req.server.config.index, i => {
						const npath = path.join(lpath, i);

						fs.lstat(npath, (err, lstats) => {
							if (err === null && handled === false) {
								handled = true;
								req.file = {path: npath, stats: lstats};
								req.server.log("Routed request to disk", "debug");
								next();
							} else if (++count === nth && handled === false) {
								next();
							}
						});
					});
				} else {
					next();
				}
			}
		});
	}
}

function guard (req, res, next) {
	if (req.parsed.url === login || req.isAuthenticated() === true) {
		next();
	} else {
		res.redirect(login);
	}
}

function parse (req, res, next) {
	let valid = true,
		exception;

	if (regex.body.test(req.method) === true && req.body !== void 0) {
		const type = req.headers["content-type"];

		if (regex.encode_form.test(type) === true) {
			const args = req.body ? retsu.chunk(req.body.split(regex.body_split), 2) : [];

			req.body = {};
			retsu.each(args, i => {
				req.body[i[0]] = coerce(decodeURIComponent(i[1]));
			});
		} else if (regex.encode_json.test(type) === true || regex.json_wrap.test(req.body) === true) {
			try {
				req.body = JSON.parse(req.body);
			} catch (e) {
				exception = e;
				valid = false;
			}
		}
	}

	next(valid === false ? exception : void 0);
}

function payload (req, res, next) {
	req.invalid = false;

	if (regex.body.test(req.method) === true) {
		const obj = req.httpVersionMajor === 1 ? req : res;
		let body = "";

		obj.setEncoding("utf8");

		obj.on("data", data => {
			body += data;

			if (req.server.config.maxBytes > 0 && Buffer.byteLength(body) > req.server.config.maxBytes) {
				req.invalid = true;
				next(new Error(413));
			}
		});

		obj.on("end", () => {
			if (req.invalid === false) {
				if (body !== void 0) {
					req.body = body;
				}

				next();
			}
		});
	} else {
		next();
	}
}

function keymaster (req, res, next) {
	// No authentication, or it's already happened
	if (req.protect === false || req.protectAsync === false || (req.session !== void 0 && req.isAuthenticated() === true) === true) {
		const method = regex.get_rewrite.test(req.method) ? "get" : req.method.toLowerCase(),
			routes = req.server.router.middleware.get(method.toUpperCase()) || new Map(),
			uri = req.parsed.pathname;
		let result;

		if (routes.has(uri)) {
			result = routes.get(uri)[0];

			if (typeof result === "function") {
				result.call(req.server.tenso, req, res);
			} else {
				res.send(result);
			}
		} else {
			retsu.each(Array.from(routes.keys()), i => {
				let key = i;

				if (regex.has_param.test(i) === true && regex.leftBrace.test(i) === false) {
					key = i.replace(/\/:(\w*)/g, "/(.*)");
				}

				if (new RegExp(`^${key}$`, "i").test(uri) === true) {
					return !(result = routes.get(i)[0]);
				}

				return void 0;
			});

			if (result !== void 0) {
				if (typeof result === "function") {
					result.call(req.server.tenso, req, res);
				} else {
					res.send(result);
				}
			} else {
				next(new Error(404));
			}
		}
	} else {
		next(new Error(401));
	}
}

function rate (req, res, next) {
	if (req.server.config.rate.enabled === false || req.unprotect === true) {
		next();
	} else {
		const results = req.server.rate(req, req.server.config.rate.override),
			good = results.shift();

		retsu.each(rateHeaders, (i, idx) => res.header(i, results[idx]));

		if (good === true) {
			next();
		} else {
			next(new Error(req.server.config.rate.status || 429));
		}
	}
}

function stream (req, res, next) {
	if (req.file === void 0) {
		next(new Error(404));
	} else {
		const headers = {
			"content-length": req.file.stats.size,
			"content-type": mime.lookup(req.file.path),
			"last-modified": req.file.stats.mtime.toUTCString()
		};

		let status = 200,
			letag, options;

		if (req.server.canETag(req.parsed.pathname, req.method) === true) {
			letag = headers.etag = req.server.etag(req.parsed.pathname, req.file.stats.size, req.file.stats.mtime);
		}

		if (regex.get_only.test(req.method) === true) {
			if (letag !== void 0 && req.headers["if-none-match"] === letag) {
				delete headers["content-length"];
				res.send("", 304, headers);
			} else if (req.headers["if-none-match"] === void 0 && Date.parse(req.headers["if-modified-since"]) >= req.file.stats.mtime) {
				delete headers["content-length"];
				res.send("", 304, headers);
			} else if (req.server.router.http2 === false) {
				options = {};

				// Setting the partial content headers
				if (req.headers.range !== void 0) {
					retsu.each(req.headers.range.replace(/^.*=/, "").split(",")[0].split("-"), (i, idx) => {
						options[idx === 0 ? "start" : "end"] = i ? parseInt(i, 10) : void 0;
					});

					// Byte offsets
					if (isNaN(options.start) === true && isNaN(options.end) === false) {
						options.start = req.file.stats.size - options.end;
						options.end = req.file.stats.size;
					} else if (isNaN(options.end) === true) {
						options.end = req.file.stats.size;
					}

					if (options.start >= options.end || isNaN(options.start) === true || isNaN(options.end) === true) {
						return next(new Error(416));
					}

					status = 206;
					headers["content-range"] = `bytes ${options.start}-${options.end}/${req.file.stats.size}`;
					headers["content-length"] = options.end - options.start + 1;
				}

				res.send(fs.createReadStream(req.file.path, options), status, headers);
			} else if (req.headers.range !== void 0) {
				return next(new Error(416)); // Partial responses are not supported at this time for HTTP2
			} else {
				req.server.router.http2Send(req, res, req.file.path, status, headers);
			}
		} else {
			res.send("", 200, headers);
		}
	}

	return void 0;
}

function statik (req, res) {
	const pathname = req.parsed.pathname.replace(regex.root, ""),
		invalid = (pathname.replace(regex.dir, "").split("/").filter(i => i !== ".")[0] || "") === "..",
		outDir = !invalid ? (pathname.match(/\.{2}\//g) || []).length : 0,
		inDir = !invalid ? (pathname.match(/\w+?(\.\w+|\/)+/g) || []).length : 0;

	if (invalid === true) {
		res.error(404);
	} else if (outDir > 0 && outDir >= inDir) {
		res.error(404);
	} else {
		file(req, res, err2 => {
			if (err2 !== void 0) {
				res.error(404);
			} else {
				req.session = void 0;
				stream(req, res, err3 => {
					if (err3 !== void 0) {
						res.error(404);
					}
				});
			}
		});
	}
}

function timer (req, res, next) {
	req.timer = precise().start();
	next();
}

function zuul (req, res, next) {
	const uri = req.parsed.path;
	let protectd = false;

	if (regex.options.test(req.method) === false) {
		retsu.each(req.server.config.auth.protect, i => {
			if (i.test(uri) === true) {
				return !(protectd = true);
			}

			return void 0;
		});

		// Setting state so the connection can be terminated properly
		req.protect = protectd;
		req.protectAsync = false;

		rate(req, res, e => {
			if (e !== void 0) {
				next(e);
			} else if (protectd === true) {
				next();
			} else {
				keymaster(req, res, next);
			}
		});
	} else {
		res.send("OPTIONS requests are only support for CORS");
	}
}

module.exports = {
	asyncFlag: asyncFlag,
	bypass: bypass,
	guard: guard,
	parse: parse,
	payload: payload,
	rate: rate,
	"static": statik,
	timer: timer,
	zuul: zuul
};
<|endoftext|>


<commit_before>'use strict';

module.exports = function (data) {
	if (data.minify !== 'css') {return data;}

	var CleanCSS = require('clean-css');
	var result = new CleanCSS({
		processImport: false,
		rebase: false,
		roundingPrecision: -1,
		advanced: true,
		aggressiveMerging: false,
		restructuring: false,
		shorthandCompacting: true
	}).minify(data.value);

	if (result.errors[0]) {
		throw new Error(result.errors[0]);
	}

	data.value = result.styles;
	return data;
};
<commit_msg>changed css minifcation options to be 100% safe, and optimally practical<commit_after>'use strict';

module.exports = function (data) {
	if (data.minify !== 'css') {return data;}

	var CleanCSS = require('clean-css');
	var result = new CleanCSS({
		processImport: false,
		rebase: false,
		roundingPrecision: 5,
		advanced: true,
		aggressiveMerging: false,
		restructuring: false,
		shorthandCompacting: false
	}).minify(data.value);

	if (result.errors[0]) {
		throw new Error(result.errors[0]);
	}

	data.value = result.styles;
	return data;
};
<|endoftext|>


<commit_before>var Observable = require('../utils').Observable,
    metrics = require('../metrics'),
    metric_prefix = 'timer.bin.',
    crypto = require('crypto');

module.exports = Observable.extend({
  constructor: function BinModel(store) {
    Observable.call(this);
    this.store = store;
  },
  load: function (params, fn) {
    var timer = metrics.createTimer(metric_prefix + 'load');
    var original = fn;
    fn = function () {
      timer.stop();
      original.apply(this, [].slice.call(arguments));
    };
    this.store.getBin.call(this.store, params, fn);
  },
  latest: function (params, fn) {
    var timer = metrics.createTimer(metric_prefix + 'latest');
    var original = fn;
    fn = function () {
      timer.stop();
      original.apply(this, [].slice.call(arguments));
    };
    this.store.getLatestBin.call(this.store, params, fn);
  },
  // Create a new bin.
  create: function (data, fn) {
    var timer = metrics.createTimer(metric_prefix + 'create');
    this.store.generateBinId(function (err, id) {
      if (err) {
        return fn(err);
      }

      data.url = id;
      data.revision = 1;
      data.streamingKey = this.createStreamingKey(id, data.revision);
      this.store.setBin(data, function (err, id) {
        timer.stop();
        data.id = id;
        fn(err || null, err ? undefined : data);
      });
    }.bind(this));
  },
  // Create a new revision.
  createRevision: function (data, fn) {
    var timer = metrics.createTimer(metric_prefix + 'createRevision');
    data.streamingKey = this.createStreamingKey(data.url, data.revision);
    this.store.setBin(data, function (err, id) {
      timer.stop();
      data.id = id;
      fn(err || null, err ? undefined : data);
    });
  },
  updatePanel: function (panel, data, fn) {
    var timer = metrics.createTimer(metric_prefix + 'updatePanel');
    var original = fn;
    fn = function () {
      timer.stop();
      original.apply(this, [].slice.call(arguments));
    };
    this.store.setBinPanel.call(this.store, panel, data, fn);
  },
  archive: function (bin, fn) {
    var timer = metrics.createTimer(metric_prefix + 'archive');
    var original = fn;
    fn = function () {
      timer.stop();
      original.apply(this, [].slice.call(arguments));
    };
    this.store.archiveBin.call(this.store, bin, fn);
  },
  createStreamingKey: function (id, rev) {
    var key = "" + id + rev + Math.random();
    return crypto.createHash('md5').update(key).digest('hex');
  },
  report: function (params, fn) {
    this.store.reportBin.apply(this.store, arguments);
  },
  getVisibility: function(bin, fn) {
    this.store.getVisibility(bin, fn);
  }
});
<commit_msg>Adding getBinWithOwner method TODO update methodname elsewhere<commit_after>var Observable = require('../utils').Observable,
    metrics = require('../metrics'),
    metric_prefix = 'timer.bin.',
    crypto = require('crypto');

module.exports = Observable.extend({
  constructor: function BinModel(store) {
    Observable.call(this);
    this.store = store;
  },
  load: function (params, fn) {
    var timer = metrics.createTimer(metric_prefix + 'load');
    var original = fn;
    fn = function () {
      timer.stop();
      original.apply(this, [].slice.call(arguments));
    };
    this.store.getBin.call(this.store, params, fn);
  },
  latest: function (params, fn) {
    var timer = metrics.createTimer(metric_prefix + 'latest');
    var original = fn;
    fn = function () {
      timer.stop();
      original.apply(this, [].slice.call(arguments));
    };
    this.store.getLatestBin.call(this.store, params, fn);
  },
  // Create a new bin.
  create: function (data, fn) {
    var timer = metrics.createTimer(metric_prefix + 'create');
    this.store.generateBinId(function (err, id) {
      if (err) {
        return fn(err);
      }

      data.url = id;
      data.revision = 1;
      data.streamingKey = this.createStreamingKey(id, data.revision);
      this.store.setBin(data, function (err, id) {
        timer.stop();
        data.id = id;
        fn(err || null, err ? undefined : data);
      });
    }.bind(this));
  },
  // Create a new revision.
  createRevision: function (data, fn) {
    var timer = metrics.createTimer(metric_prefix + 'createRevision');
    data.streamingKey = this.createStreamingKey(data.url, data.revision);
    this.store.setBin(data, function (err, id) {
      timer.stop();
      data.id = id;
      fn(err || null, err ? undefined : data);
    });
  },
  updatePanel: function (panel, data, fn) {
    var timer = metrics.createTimer(metric_prefix + 'updatePanel');
    var original = fn;
    fn = function () {
      timer.stop();
      original.apply(this, [].slice.call(arguments));
    };
    this.store.setBinPanel.call(this.store, panel, data, fn);
  },
  archive: function (bin, fn) {
    var timer = metrics.createTimer(metric_prefix + 'archive');
    var original = fn;
    fn = function () {
      timer.stop();
      original.apply(this, [].slice.call(arguments));
    };
    this.store.archiveBin.call(this.store, bin, fn);
  },
  createStreamingKey: function (id, rev) {
    var key = "" + id + rev + Math.random();
    return crypto.createHash('md5').update(key).digest('hex');
  },
  report: function (params, fn) {
    this.store.reportBin.apply(this.store, arguments);
  },
  getVisibility: function(bin, fn) {
    this.store.getVisibility(bin, fn);
  },
  getBinWithOwner: function(bin, fn) {
    this.store.getBinOwner(bin, fn);
  }
});
<|endoftext|>


<commit_before>(function() {
  var Pool, cachedConnections, connectMongo, mongo;

  mongo = require('mongodb');

  Pool = require('./pool');

  cachedConnections = {};

  connectMongo = function(config, callback, useCache) {
    var cacheKey, cb, dbCon, dbServer, k, v;
    if (useCache == null) {
      useCache = true;
    }
    cacheKey = ((function() {
      var _results;
      _results = [];
      for (k in config) {
        v = config[k];
        _results.push("" + k + "=" + v);
      }
      return _results;
    })()).join(';');
    if (useCache && cachedConnections[cacheKey]) {
      return callback(null, cachedConnections[cacheKey]);
    }
    cb = function(err, db) {
      if (!err) {
        cachedConnections[cacheKey] = db;
      }
      return callback(err, db);
    };
    dbServer = new mongo.Server(config.host, config.port, {
      auto_reconnect: true
    });
    dbCon = new mongo.Db(config.db, dbServer, {
      safe: true
    });
    return dbCon.open(function(err, db) {
      if (err) {
        throw err;
      }
      if (config.user) {
        return db.authenticate(config.user, config.password, {}, function(err, success) {
          return cb(err, db);
        });
      } else {
        return cb(null, db);
      }
    });
  };

  module.exports.connect = connectMongo;

  module.exports.create = function(config, callback) {
    var pool;
    pool = new Pool({
      max: config.max || 5,
      create: function(cb) {
        return connectMongo(config, cb, false);
      },
      success: function() {
        return callback(null, pool);
      }
    });
  };

}).call(this);
<commit_msg>cleanup<commit_after>(function() {
  var Pool, cachedConnections, connectMongo, mongo;

  mongo = require('mongodb');

  Pool = require('./pool');

  cachedConnections = {};

  connectMongo = function(config, callback, useCache) {
    var cacheKey, cb, dbCon, dbServer, k, v;
    if (useCache == null) {
      useCache = true;
    }
    cacheKey = ((function() {
      var _results;
      _results = [];
      for (k in config) {
        v = config[k];
        _results.push("" + k + "=" + v);
      }
      return _results;
    })()).join(';');
    if (useCache && cachedConnections[cacheKey]) {
      return callback(null, cachedConnections[cacheKey]);
    }
    cb = function(err, db) {
      if (!err) {
        cachedConnections[cacheKey] = db;
      }
      return callback(err, db);
    };
    dbServer = new mongo.Server(config.host, config.port, {
      auto_reconnect: true
    });
    dbCon = new mongo.Db(config.db, dbServer, {
      safe: true
    });
    return dbCon.open(function(err, db) {
      if (err) {
        throw err;
      }
      if (config.user) {
        return db.authenticate(config.user, config.password, {}, function(err, success) {
          return cb(err, db);
        });
      } else {
        return cb(null, db);
      }
    });
  };

  module.exports.connect = connectMongo;

  module.exports.create = function(config, callback) {
    var pool;
    return pool = new Pool({
      max: config.max || 5,
      create: function(cb) {
        return connectMongo(config, cb, false);
      },
      success: function() {
        return callback(null, pool);
      }
    });
  };

}).call(this);
<|endoftext|>


<commit_before>(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  CodeMirror.defineMode('coq', function(_config, parserConfig) {

    var vernacular = [
      'Add', 'All', 'Arguments', 'Axiom',
      'Bind',
      'Canonical', 'Check', 'Class', 'Close', 'Coercion', 'CoFixpoint',
      'CoInductive', 'Context', 'Contextual', 'Corollary',
      'Defined', 'Definition', 'Delimit',
      'Eval',
      'End', 'Example', 'Export',
      'Fact', 'Fixpoint', 'From',
      'Global', 'Goal', 'Graph',
      'Hint', 'Hypotheses', 'Hypothesis',
      'Implicit', 'Implicits', 'Import', 'Inductive', 'Infix', 'Instance',
      'Lemma', 'Let', 'Local', 'Ltac',
      'Module', 'Morphism',
      'Notation',
      'Open',
      'Parameter', 'Parameters', 'Prenex', 'Print', 'Printing', 'Program',
      'Projections', 'Proof',
      'Proposition',
      'Qed',
      'Record', 'Relation', 'Remark', 'Require', 'Reserved', 'Resolve', 'Rewrite',
      'Save', 'Scope', 'Search', 'Section', 'Set', 'Show', 'Strict', 'Structure',
      'Tactic', 'Theorem', 'Types',
      'Unset',
      'Variable', 'Variables', 'View'
    ];

    var gallina = [
      'as',
      'at',
      'cofix',
      'else', 'end',
      'False', 'fix', 'for', 'forall', 'fun',
      'if', 'in', 'is',
      'let',
      'match',
      'of',
      'Prop',
      'return',
      'struct',
      'then', 'True', 'Type',
      'when', 'with'
    ];

    var tactics = [
      'after', 'apply', 'assert', 'auto', 'autorewrite',
      'case', 'change', 'clear', 'compute', 'congruence', 'constructor',
      'cut', 'cutrewrite',
      'dependent', 'destruct',
      'eapply', 'eassumption', 'eauto', 'econstructor', 'elim', 'exists',
      'field', 'firstorder', 'fold', 'fourier',
      'generalize',
      'have', 'hnf',
      'induction', 'injection', 'intro', 'intros', 'inversion',
      'left',
      'move',
      'pattern', 'pose',
      'refine', 'remember', 'rename', 'replace', 'revert', 'rewrite',
      'right', 'ring',
      'set', 'simpl', 'specialize', 'split', 'subst', 'symmetry',
      'transitivity', 'trivial',
      'unfold', 'unlock', 'using'
    ];

    var terminators = [
      'assumption',
      'by',
      'contradiction',
      'discriminate',
      'exact',
      'now',
      'omega',
      'reflexivity',
      'tauto'
    ];

    var admitters = [
      'admit',
      'Admitted'
    ];

    var words = {};
    vernacular.map(function(word){words[word] = 'builtin';});
    gallina.map(function(word){words[word] = 'keyword';});
    tactics.map(function(word){words[word] = 'tactic';});
    terminators.map(function(word){words[word] = 'terminator';});
    admitters.map(function(word){words[word] = 'keyword';});

//        'let': 'keyword',
//        'print_endline': 'builtin',
//        'true': 'atom',

    function tokenBase(stream, state) {
      if(stream.sol()) {
        state.logicalsol = true; // logicalsol: only \s caracters seen from sol
      }
      if(stream.eol())
        state.logicalsol = false;

      if(stream.eatSpace())
        return null;

      var ch = stream.next();

      if(state.logicalsol) {
        if(/[\*\-\+]/.test(ch)) {
          state.logicalsol = false;
          return 'bullet';
        }
        if(/[\{\}]/.test(ch)) {
          state.logicalsol = false;
          return 'brace';
        }
        if(!(/\s/.test(ch)))
          state.logicalsol = false;
      }

      if(ch === '.') {
        state.tokenize = tokenStatementEnd;
        return state.tokenize(stream, state);
      }

      if (ch === '"') {
        state.tokenize = tokenString;
        return state.tokenize(stream, state);
      }

      if (ch === '(') {
        if (stream.eat('*')) {
          state.commentLevel++;
          state.tokenize = tokenComment;
          return state.tokenize(stream, state);
        }
      }

      if (ch === '~') {
        stream.eatWhile(/\w/);
        return 'variable-2';
      }

      if (ch === '`') {
        stream.eatWhile(/\w/);
        return 'quote';
      }

      if (/\d/.test(ch)) {
        stream.eatWhile(/[\d]/);
        /*
        if (stream.eat('.')) {
          stream.eatWhile(/[\d]/);
        }
        */
        return 'number';
      }

      if ( /[+\-*&%=<>!?|]/.test(ch)) {
        return 'operator';
      }

      if(/[\[\]]/.test(ch)) {
        return 'bracket';
      }

      stream.eatWhile(/\w/);
      var cur = stream.current();
      return words.hasOwnProperty(cur) ? words[cur] : 'variable';
    }

    function tokenString(stream, state) {
      var next, end = false, escaped = false;
      while ((next = stream.next()) !== null) {
        if (next === '"' && !escaped) {
          end = true;
          break;
        }
        escaped = !escaped && next === '\\';
      }
      if (end && !escaped) {
        state.tokenize = tokenBase;
      }
      return 'string';
    }

    function tokenComment(stream, state) {
      var prev, next;
      while(state.commentLevel > 0 && (next = stream.next()) !== null) {
        if (prev === '(' && next === '*') state.commentLevel++;
        if (prev === '*' && next === ')') state.commentLevel--;
        prev = next;
      }
      if (state.commentLevel <= 0) {
        state.tokenize = tokenBase;
      }
      return 'comment';
    }

    function tokenStatementEnd(stream, state) {
      state.tokenize = tokenBase;
      if(stream.eol() || stream.match(/\s/, false))
        return 'statementend';

    }

    return {
      startState: function() {
        return {tokenize: tokenBase, commentLevel: 0};
      },
      token: function(stream, state) {
        return state.tokenize(stream, state);
      },
      blockCommentStart: "(*",
      blockCommentEnd: "*)",
      lineComment: null
    };
  });

  CodeMirror.defineMIME('text/x-coq', {
    name: 'coq'
  });

});
<commit_msg>Some more coq-mode keywords<commit_after>(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  CodeMirror.defineMode('coq', function(_config, parserConfig) {

    var vernacular = [
      'About', 'Add', 'All', 'Arguments', 'Axiom',
      'Bind',
      'Canonical', 'Check', 'Class', 'Close', 'Coercion', 'CoFixpoint',
      'CoInductive', 'Context', 'Contextual', 'Corollary',
      'Defined', 'Definition', 'Delimit',
      'Eval',
      'End', 'Example', 'Export',
      'Fact', 'Fixpoint', 'From',
      'Global', 'Goal', 'Graph',
      'Hint', 'Hypotheses', 'Hypothesis',
      'Implicit', 'Implicits', 'Import', 'Inductive', 'Infix', 'Instance',
      'Lemma', 'Let', 'Local', 'Ltac',
      'Module', 'Morphism',
      'Notation',
      'Open',
      'Parameter', 'Parameters', 'Prenex', 'Print', 'Printing', 'Program',
      'Projections', 'Proof',
      'Proposition',
      'Qed',
      'Record', 'Relation', 'Remark', 'Require', 'Reserved', 'Resolve', 'Rewrite',
      'Save', 'Scope', 'Search', 'Section', 'Set', 'Show', 'Strict', 'Structure',
      'Tactic', 'Theorem', 'Types',
      'Unset',
      'Variable', 'Variables', 'View'
    ];

    var gallina = [
      'as',
      'at',
      'cofix',
      'else', 'end',
      'False', 'fix', 'for', 'forall', 'fun',
      'if', 'in', 'is',
      'let',
      'match',
      'of',
      'Prop',
      'return',
      'struct',
      'then', 'True', 'Type',
      'when', 'with'
    ];

    var tactics = [
      'after', 'apply', 'assert', 'auto', 'autorewrite',
      'case', 'change', 'clear', 'compute', 'congruence', 'constructor',
      'congr', 'cut', 'cutrewrite',
      'dependent', 'destruct',
      'eapply', 'eassumption', 'eauto', 'econstructor', 'elim', 'exists',
      'field', 'firstorder', 'fold', 'fourier',
      'generalize',
      'have', 'hnf',
      'induction', 'injection', 'intro', 'intros', 'inversion',
      'left',
      'move',
      'pattern', 'pose',
      'refine', 'remember', 'rename', 'replace', 'revert', 'rewrite',
      'right', 'ring',
      'set', 'simpl', 'specialize', 'split', 'subst', 'suff', 'symmetry',
      'transitivity', 'trivial',
      'unfold', 'unlock', 'using',
      'vm_compute',
      'wlog'
    ];

    var terminators = [
      'assumption',
      'by',
      'contradiction',
      'discriminate',
      'exact',
      'now',
      'omega',
      'reflexivity',
      'tauto'
    ];

    var admitters = [
      'admit',
      'Admitted'
    ];

    var words = {};
    vernacular.map(function(word){words[word] = 'builtin';});
    gallina.map(function(word){words[word] = 'keyword';});
    tactics.map(function(word){words[word] = 'tactic';});
    terminators.map(function(word){words[word] = 'terminator';});
    admitters.map(function(word){words[word] = 'keyword';});

//        'let': 'keyword',
//        'print_endline': 'builtin',
//        'true': 'atom',

    function tokenBase(stream, state) {
      if(stream.sol()) {
        state.logicalsol = true; // logicalsol: only \s caracters seen from sol
      }
      if(stream.eol())
        state.logicalsol = false;

      if(stream.eatSpace())
        return null;

      var ch = stream.next();

      if(state.logicalsol) {
        if(/[\*\-\+]/.test(ch)) {
          state.logicalsol = false;
          return 'bullet';
        }
        if(/[\{\}]/.test(ch)) {
          state.logicalsol = false;
          return 'brace';
        }
        if(!(/\s/.test(ch)))
          state.logicalsol = false;
      }

      if(ch === '.') {
        state.tokenize = tokenStatementEnd;
        return state.tokenize(stream, state);
      }

      if (ch === '"') {
        state.tokenize = tokenString;
        return state.tokenize(stream, state);
      }

      if (ch === '(') {
        if (stream.eat('*')) {
          state.commentLevel++;
          state.tokenize = tokenComment;
          return state.tokenize(stream, state);
        }
      }

      if (ch === '~') {
        stream.eatWhile(/\w/);
        return 'variable-2';
      }

      if (ch === '`') {
        stream.eatWhile(/\w/);
        return 'quote';
      }

      if (/\d/.test(ch)) {
        stream.eatWhile(/[\d]/);
        /*
        if (stream.eat('.')) {
          stream.eatWhile(/[\d]/);
        }
        */
        return 'number';
      }

      if ( /[+\-*&%=<>!?|]/.test(ch)) {
        return 'operator';
      }

      if(/[\[\]]/.test(ch)) {
        return 'bracket';
      }

      stream.eatWhile(/\w/);
      var cur = stream.current();
      return words.hasOwnProperty(cur) ? words[cur] : 'variable';
    }

    function tokenString(stream, state) {
      var next, end = false, escaped = false;
      while ((next = stream.next()) !== null) {
        if (next === '"' && !escaped) {
          end = true;
          break;
        }
        escaped = !escaped && next === '\\';
      }
      if (end && !escaped) {
        state.tokenize = tokenBase;
      }
      return 'string';
    }

    function tokenComment(stream, state) {
      var prev, next;
      while(state.commentLevel > 0 && (next = stream.next()) !== null) {
        if (prev === '(' && next === '*') state.commentLevel++;
        if (prev === '*' && next === ')') state.commentLevel--;
        prev = next;
      }
      if (state.commentLevel <= 0) {
        state.tokenize = tokenBase;
      }
      return 'comment';
    }

    function tokenStatementEnd(stream, state) {
      state.tokenize = tokenBase;
      if(stream.eol() || stream.match(/\s/, false))
        return 'statementend';

    }

    return {
      startState: function() {
        return {tokenize: tokenBase, commentLevel: 0};
      },
      token: function(stream, state) {
        return state.tokenize(stream, state);
      },
      blockCommentStart: "(*",
      blockCommentEnd: "*)",
      lineComment: null
    };
  });

  CodeMirror.defineMIME('text/x-coq', {
    name: 'coq'
  });

});
<|endoftext|>


<commit_before>Reminders = new Mongo.Collection("reminders");

Meteor.methods({
   addReminder: (reminder) => {
      if (!Meteor.userId()) {
         throw new Meteor.Error('not-authorized');
      }
      reminder.createdBy = Meteor.userId();

      Reminders.insert(reminder);
      console.log('Succesfully inserted reminder: ', reminder);
   },
   deleteReminder: (reminder) => {
      if (!Meteor.userId()) {
         throw new Meteor.Error('not-authorized');
      }

      Reminders.remove(reminder._id);
      console.log('Removed reminder: ', reminder);
   }
});

// Initialise default reminders
Meteor.startup(() => {
   console.log('Meteor startup called');
   if (!Reminders.findOne({isListReminders: true})) {
      var reminders = [
         {
            description: 'Blodprøver'
         },
         {
            description: 'Højdosis'
         }];
      Reminders.insert({
         isListReminders: true,
         reminders: reminders
      });
   }
   if (Meteor.isServer){
      Reminders._ensureIndex({"createdBy": 1});
   }
});<commit_msg>Avoid white screen of death due to slow meteor startup<commit_after>Reminders = new Mongo.Collection("reminders");

Meteor.methods({
   addReminder: (reminder) => {
      if (!Meteor.userId()) {
         throw new Meteor.Error('not-authorized');
      }
      reminder.createdBy = Meteor.userId();

      Reminders.insert(reminder);
      console.log('Succesfully inserted reminder: ', reminder);
   },
   deleteReminder: (reminder) => {
      if (!Meteor.userId()) {
         throw new Meteor.Error('not-authorized');
      }

      Reminders.remove(reminder._id);
      console.log('Removed reminder: ', reminder);
   }
});

// Initialise default reminders
Meteor.startup(() => {
   console.log('Meteor startup called');
   Meteor.setTimeout(function() {
      if (!Reminders.findOne({isListReminders: true})) {
         var reminders = [
            {
               description: 'Blodprøver'
            },
            {
               description: 'Højdosis'
            }];
         Reminders.insert({
            isListReminders: true,
            reminders: reminders
         });
         if (Meteor.isServer){
            Reminders._ensureIndex({"createdBy": 1});
         }
      }
   }, 10000);
});
<|endoftext|>


<commit_before>// This file describes the person object. It requires:
// * mortality

function PersonObject(YearOfBirth, Sex, Sexuality)//, YearOfObservation Param)
{
	//Active
	this.Active=0;// status variable
	//Sex
	this.Sex=Sex;
	//Alive
	//this.AliveStatus=1;// status variable

	this.Sexuality=1;// 1= heterosexual, 2= homosexual, 3= bisexual
	if (typeof(Sexuality)!="undefined"){
		this.Sexuality=Sexuality;
	}

	this.YearOfBirth=YearOfBirth;

	this.Death=new DeathObject(this);

	this.Immigrant=false;
	this.Nationality;

	//Location (in this case, there is only one location variable, it might represent state or a local area)
	this.Location=new EventVector;

	//Alcohol
	this.Alcohol=1E9;//Date of alcoholism (increases linearly with time, probability

	this.HCV = new HCVObject(this);//may need to declare this in function to reduce the size of the memory footprint

	this.HIV = new HIVObject();

	this.IDU = new IDUObject(this);//Injection drug use

	this.Haemophilia=0;

	this.SexualPartner=new EventVector;
	this.SexualPartner.Set(0, this.YearOfBirth);// no sexual partners at birth

	this.SexualPartnerRegularID=new EventVector;
	this.SexualPartnerOtherID=new EventVector;

	this.SexualPartnerRegularID.Set(-1, this.YearOfBirth);
	this.SexualPartnerOtherID.Set(-1, this.YearOfBirth);

	//QALY
	//this.QualityCalculation=function(time){(this.HCV, this.IDU, this.HIV, this.Age, time);}//
	//this.QALY(this.HCV, this.IDU, this.HIV, this.Age)//

	//Simulate general mortality

}

PersonObject.prototype.Age= function (Time){//using prototyping for speed
	return Time-this.YearOfBirth;
};

PersonObject.prototype.Alive = function (Time){//using prototyping for speed
	if (this.YearOfBirth<=Time && Time <= this.Death.Time()){
		return true;
	}
	//else
	return false;
};

PersonObject.prototype.CalculateGeneralMortality= function (TimeFromWhichToCalculateMortality, SMR){//, MaleMortality, FemaleMortality){
	// if this.Sex==0 && this.Aboriginal==false
	if (this.Sex==0){
		this.Death.Set('General', MaleMortality.TimeOfDeath(this.YearOfBirth, TimeFromWhichToCalculateMortality, SMR))
	}
	else {
		this.Death.Set('General', FemaleMortality.TimeOfDeath(this.YearOfBirth, TimeFromWhichToCalculateMortality, SMR));
	}
};

PersonObject.prototype.SetNationality= function (NationValue, Time){
	this.Immigrant=true;
	if (typeof(this.Nationality)=='undefined'){
		this.Nationality=new EventVector();
	}
	this.Nationality.Set(NationValue, Time);
};

PersonObject.prototype.CurrentNationality= function (Time){
	if(this.Immigrant==false){
		return 0;// 0 is the Local
	}
	return this.Nationality.Value(Time);
};

PersonObject.prototype.InCountry= function (Time){
	if(this.CurrentNationality(Time)==0){
		return true;// 0 is the Local
	}
	return false;
};

PersonObject.prototype.StartInjecting= function (Time){
	throw "This shouldn't run at all.";

};

// PersonObject.prototype.HCVInfection= function (YearOfInfection, Genotype, HCVParam) {
	// var Alcohol=0;
	// this.HCV.Infection(YearOfInfection, Genotype, this.Age(YearOfInfection), this.Sex, this.Alcohol, HCVParam );
// }

function DeathObject(PersonPointer){
	this.Data={};

	this.Data.General=1E9;
	this.Earliest=1E9;
	this.EarliestCause='';

	// this.General=1E9;
	// this.IDU=1E9;
	// this.HCV=1E9;
	// this.HCC=1E9;
	// this.LF=1E9;
	// this.HIV=1E9;
}

// DeathObject.prototype.Year= function (){
// 	// This is a general function that describes the difference between general death date and
// 	// the earliest non-general death date.
// 	return Math.min(this.General, this.IDU, this.HCV, this.HCC, this.LF, this.HIV);
// };

DeathObject.prototype.YearsOfLifeLost= function (){
	// This is a general function that describes the difference between general death date and
	// the earliest non-general death date.
	// return this.General-Math.min(this.General, this.IDU, this.HCV, this.HCC, this.LF, this.HIV);

	return this.Data.General-this.Time();
};

DeathObject.prototype.Add=function (TypeOfDeath, Time){
	this.Data[TypeOfDeath]=Time;
	// Calculate the earliest time again
	this.CalculateEarliest();
};

DeathObject.prototype.Reset=function (TypeOfDeath){
	this.Data[TypeOfDeath]=1e9;
	// Calculate the earliest time again
	this.CalculateEarliest();
};

DeathObject.prototype.CalculateEarliest=function (){
	var EarliestTime=1E10;
	var Cause;
	for (var d in this.Data){
		if (this.Data[d]<EarliestTime){
			console.log(this.Data[d]);
			console.log(d);

			EarliestTime=this.Data[d];
			Cause=d;
		}
	}
	if  (EarliestTime>1E9){
		EarliestTime=1E9;
	}
	this.EarliestCause=Cause;
	this.Earliest=EarliestTime;
};

DeathObject.prototype.Time=function (TypeOfDeath){
	if (typeof(TypeOfDeath)=='undefined'){// Not providing the function with a death type will return the earliest time of death, i.e. THE cause of death
		return this.Earliest;
	}
	// else if the type of death is specified
	if (typeof(this.Data[TypeOfDeath])=='undefined'){// if the death type cannot be found
		return 1e9;
	}
	return this.Data[TypeOfDeath];
};

DeathObject.prototype.Cause=function (){
	return this.EarliestCause;
};

//-----------------------------------------------------------------
//
//

console.log("Loaded person.js");<commit_msg>Removing output statements<commit_after>// This file describes the person object. It requires:
// * mortality

function PersonObject(YearOfBirth, Sex, Sexuality)//, YearOfObservation Param)
{
	//Active
	this.Active=0;// status variable
	//Sex
	this.Sex=Sex;
	//Alive
	//this.AliveStatus=1;// status variable

	this.Sexuality=1;// 1= heterosexual, 2= homosexual, 3= bisexual
	if (typeof(Sexuality)!="undefined"){
		this.Sexuality=Sexuality;
	}

	this.YearOfBirth=YearOfBirth;

	this.Death=new DeathObject(this);

	this.Immigrant=false;
	this.Nationality;

	//Location (in this case, there is only one location variable, it might represent state or a local area)
	this.Location=new EventVector;

	//Alcohol
	this.Alcohol=1E9;//Date of alcoholism (increases linearly with time, probability

	this.HCV = new HCVObject(this);//may need to declare this in function to reduce the size of the memory footprint

	this.HIV = new HIVObject();

	this.IDU = new IDUObject(this);//Injection drug use

	this.Haemophilia=0;

	this.SexualPartner=new EventVector;
	this.SexualPartner.Set(0, this.YearOfBirth);// no sexual partners at birth

	this.SexualPartnerRegularID=new EventVector;
	this.SexualPartnerOtherID=new EventVector;

	this.SexualPartnerRegularID.Set(-1, this.YearOfBirth);
	this.SexualPartnerOtherID.Set(-1, this.YearOfBirth);

	//QALY
	//this.QualityCalculation=function(time){(this.HCV, this.IDU, this.HIV, this.Age, time);}//
	//this.QALY(this.HCV, this.IDU, this.HIV, this.Age)//

	//Simulate general mortality

}

PersonObject.prototype.Age= function (Time){//using prototyping for speed
	return Time-this.YearOfBirth;
};

PersonObject.prototype.Alive = function (Time){//using prototyping for speed
	if (this.YearOfBirth<=Time && Time <= this.Death.Time()){
		return true;
	}
	//else
	return false;
};

PersonObject.prototype.CalculateGeneralMortality= function (TimeFromWhichToCalculateMortality, SMR){//, MaleMortality, FemaleMortality){
	// if this.Sex==0 && this.Aboriginal==false
	if (this.Sex==0){
		this.Death.Set('General', MaleMortality.TimeOfDeath(this.YearOfBirth, TimeFromWhichToCalculateMortality, SMR))
	}
	else {
		this.Death.Set('General', FemaleMortality.TimeOfDeath(this.YearOfBirth, TimeFromWhichToCalculateMortality, SMR));
	}
};

PersonObject.prototype.SetNationality= function (NationValue, Time){
	this.Immigrant=true;
	if (typeof(this.Nationality)=='undefined'){
		this.Nationality=new EventVector();
	}
	this.Nationality.Set(NationValue, Time);
};

PersonObject.prototype.CurrentNationality= function (Time){
	if(this.Immigrant==false){
		return 0;// 0 is the Local
	}
	return this.Nationality.Value(Time);
};

PersonObject.prototype.InCountry= function (Time){
	if(this.CurrentNationality(Time)==0){
		return true;// 0 is the Local
	}
	return false;
};

PersonObject.prototype.StartInjecting= function (Time){
	throw "This shouldn't run at all.";

};

// PersonObject.prototype.HCVInfection= function (YearOfInfection, Genotype, HCVParam) {
	// var Alcohol=0;
	// this.HCV.Infection(YearOfInfection, Genotype, this.Age(YearOfInfection), this.Sex, this.Alcohol, HCVParam );
// }

function DeathObject(PersonPointer){
	this.Data={};

	this.Data.General=1E9;
	this.Earliest=1E9;
	this.EarliestCause='';

	// this.General=1E9;
	// this.IDU=1E9;
	// this.HCV=1E9;
	// this.HCC=1E9;
	// this.LF=1E9;
	// this.HIV=1E9;
}

// DeathObject.prototype.Year= function (){
// 	// This is a general function that describes the difference between general death date and
// 	// the earliest non-general death date.
// 	return Math.min(this.General, this.IDU, this.HCV, this.HCC, this.LF, this.HIV);
// };

DeathObject.prototype.YearsOfLifeLost= function (){
	// This is a general function that describes the difference between general death date and
	// the earliest non-general death date.
	// return this.General-Math.min(this.General, this.IDU, this.HCV, this.HCC, this.LF, this.HIV);

	return this.Data.General-this.Time();
};

DeathObject.prototype.Add=function (TypeOfDeath, Time){
	this.Data[TypeOfDeath]=Time;
	// Calculate the earliest time again
	this.CalculateEarliest();
};

DeathObject.prototype.Reset=function (TypeOfDeath){
	this.Data[TypeOfDeath]=1e9;
	// Calculate the earliest time again
	this.CalculateEarliest();
};

DeathObject.prototype.CalculateEarliest=function (){
	var EarliestTime=1E10;
	var Cause;
	for (var d in this.Data){
		if (this.Data[d]<EarliestTime){
			EarliestTime=this.Data[d];
			Cause=d;
		}
	}
	if  (EarliestTime>1E9){
		EarliestTime=1E9;
	}
	this.EarliestCause=Cause;
	this.Earliest=EarliestTime;
};

DeathObject.prototype.Time=function (TypeOfDeath){
	if (typeof(TypeOfDeath)=='undefined'){// Not providing the function with a death type will return the earliest time of death, i.e. THE cause of death
		return this.Earliest;
	}
	// else if the type of death is specified
	if (typeof(this.Data[TypeOfDeath])=='undefined'){// if the death type cannot be found
		return 1e9;
	}
	return this.Data[TypeOfDeath];
};

DeathObject.prototype.Cause=function (){
	return this.EarliestCause;
};

//-----------------------------------------------------------------
//
//

console.log("Loaded person.js");<|endoftext|>


<commit_before>var keystone = require('keystone'),
	Types = keystone.Field.Types;

// Create model
var Child = new keystone.List('Child', {
	//map: { name: 'name' }
	defaultSort: 'name'
});

// Create fields
Child.add({
	image: { type: Types.CloudinaryImage, folder: 'children/', select: true, publicID: 'slug', autoCleanup: true }, //select: true, selectPrefix: 'children/' isn't working
	//video: { type: Types.CloudinaryVideo, folder: 'children/', autoCleanup: true },
	name: { type: Types.Name, label: 'Name', required: true, index: true, initial: true },
	age: { type: Number, label: 'Age', required: true, index: true, initial: true },
	registrationNumber: { type: Number, label: 'Registration Number', required: true, index: true, initial: true },
	profile: {
		part1: { type: Types.Textarea, label: 'Hi! My name is...', required: true, initial: true }, // TODO: Try to make this dynamic: 'Hi! My name is Jared...'
		part2: { type: Types.Textarea, label: 'Let me tell you more about myself...', required: true, initial: true },
		part3: { type: Types.Textarea, label: 'And here\'s what others say...', required: true, initial: true },
		part4: { type: Types.Textarea, label: 'If I could have my own special wish...', required: true, initial: true }
	},
	primaryLanguage: { type: Types.Select, label: 'Primary Language', options: 'English, Spanish, Portuguese', default: 'English', required: true, initial: true },
	ethnicity: { type: Types.Select, label: 'Ethnicity', options: 'White, African American, Hispanic/Latino, Asian, Middle Eastern, Pacific Islander, Native American/Alaskan, Mixed Race, Other', required: true, initial: true },
	gender: { type: Types.Select, label: 'Gender', options: 'Male, Female', required: true, initial: true },
	legalStatus: { type: Types.Select, label: 'Legal Status', options: 'Legally Free, Something Else', required: true, initial: true },
	wednesdaysChild: { type: Types.Boolean, label: 'Wednesday\'s Child?', initial: true },
	contactWithSiblings: { type: Types.Boolean, label: 'Has contact with siblings?', initial: true },
	// linkedSiblings: { },
	contactWithParents: { type: Types.Boolean, label: 'Has contact with parents?', initial: true },
	physicalNeeds: { type: Types.Select, label: 'Physical needs', options: 'None, Mild, Moderate, Severe', required: true, initial: true },
	physicalNeedsDescription: { type: Types.Textarea, label: 'Description of physical needs', dependsOn: { physicalNeeds: ['Mild', 'Moderate', 'Severe'] }, initial: true },
	emotionalNeeds: { type: Types.Select, label: 'Emotional needs', options: 'None, Mild, Moderate, Severe', required: true, initial: true },
	emotionalNeedsDescription: { type: Types.Textarea, label: 'Description of emotional needs', dependsOn: { emotionalNeeds: ['Mild', 'Moderate', 'Severe'] }, initial: true },
	intellectualNeeds: { type: Types.Select, label: 'Intellectual needs', options: 'None, Mild, Moderate, Severe', required: true, initial: true },
	intellectualNeedsDescription: { type: Types.Textarea, label: 'Description of intellectual needs', dependsOn: { intellectualNeeds: ['Mild', 'Moderate', 'Severe'] }, initial: true },
	disabilities: { type: Types.Select, label: 'Disabilities', options: 'None, Autism, Other', initial: true } // To get a multi-select working, see https://github.com/keystonejs/keystone/issues/12
 });

/* References which should show */
//	linked Social Worker
//	linked to interested families at various steps in the process
//	linked siblings

// Pre Save
Child.schema.pre('save', function(next) {
	'use strict';

	// TODO: Assign a registration number if one isn't assigned
	next();
});

// // Define default columns in the admin interface and register the model
Child.defaultColumns = 'name, ethnicity, legalStatus, gender, wednesdaysChild';
Child.register();
<commit_msg>Update the Child model to add hidden URL fields to the schema to easily access scaled images.<commit_after>var keystone = require('keystone'),
	Types = keystone.Field.Types;

// Create model
var Child = new keystone.List('Child', {
	//map: { name: 'name' }
	defaultSort: 'name'
});

// Create fields
Child.add({
	image: { type: Types.CloudinaryImage, folder: 'children/', select: true, publicID: 'slug', autoCleanup: true }, //select: true, selectPrefix: 'children/' isn't working
	thumbnailImage: {type: Types.Url, hidden: true},
	detailImage: {type: Types.Url, hidden: true},
	//video: { type: Types.CloudinaryVideo, folder: 'children/', autoCleanup: true },
	name: { type: Types.Name, label: 'Name', required: true, index: true, initial: true },
	age: { type: Number, label: 'Age', required: true, index: true, initial: true },
	registrationNumber: { type: Number, label: 'Registration Number', required: true, index: true, initial: true },
	profile: {
		part1: { type: Types.Textarea, label: 'Hi! My name is...', required: true, initial: true }, // TODO: Try to make this dynamic: 'Hi! My name is Jared...'
		part2: { type: Types.Textarea, label: 'Let me tell you more about myself...', required: true, initial: true },
		part3: { type: Types.Textarea, label: 'And here\'s what others say...', required: true, initial: true },
		part4: { type: Types.Textarea, label: 'If I could have my own special wish...', required: true, initial: true }
	},
	primaryLanguage: { type: Types.Select, label: 'Primary Language', options: 'English, Spanish, Portuguese', default: 'English', required: true, initial: true },
	ethnicity: { type: Types.Select, label: 'Ethnicity', options: 'White, African American, Hispanic/Latino, Asian, Middle Eastern, Pacific Islander, Native American/Alaskan, Mixed Race, Other', required: true, initial: true },
	gender: { type: Types.Select, label: 'Gender', options: 'Male, Female', required: true, initial: true },
	legalStatus: { type: Types.Select, label: 'Legal Status', options: 'Legally Free, Something Else', required: true, initial: true },
	wednesdaysChild: { type: Types.Boolean, label: 'Wednesday\'s Child?', initial: true },
	contactWithSiblings: { type: Types.Boolean, label: 'Has contact with siblings?', initial: true },
	// linkedSiblings: { },
	contactWithParents: { type: Types.Boolean, label: 'Has contact with parents?', initial: true },
	physicalNeeds: { type: Types.Select, label: 'Physical needs', options: 'None, Mild, Moderate, Severe', required: true, initial: true },
	physicalNeedsDescription: { type: Types.Textarea, label: 'Description of physical needs', dependsOn: { physicalNeeds: ['Mild', 'Moderate', 'Severe'] }, initial: true },
	emotionalNeeds: { type: Types.Select, label: 'Emotional needs', options: 'None, Mild, Moderate, Severe', required: true, initial: true },
	emotionalNeedsDescription: { type: Types.Textarea, label: 'Description of emotional needs', dependsOn: { emotionalNeeds: ['Mild', 'Moderate', 'Severe'] }, initial: true },
	intellectualNeeds: { type: Types.Select, label: 'Intellectual needs', options: 'None, Mild, Moderate, Severe', required: true, initial: true },
	intellectualNeedsDescription: { type: Types.Textarea, label: 'Description of intellectual needs', dependsOn: { intellectualNeeds: ['Mild', 'Moderate', 'Severe'] }, initial: true },
	disabilities: { type: Types.Select, label: 'Disabilities', options: 'None, Autism, Other', initial: true } // To get a multi-select working, see https://github.com/keystonejs/keystone/issues/12
 });

/* References which should show */
//	linked Social Worker
//	linked to interested families at various steps in the process
//	linked siblings

// Pre Save
Child.schema.pre('save', function(next) {
	'use strict';

	this.thumbnailImage = this._.image.thumbnail(640,300,{ quality: 60 });
	this.detailImage = this._.image.thumbnail(640,640,{ quality: 60 });

	console.log(this.thumbnailImage);
	console.log(this.detailImage);

	// TODO: Assign a registration number if one isn't assigned
	next();
});

// // Define default columns in the admin interface and register the model
Child.defaultColumns = 'name, ethnicity, legalStatus, gender, wednesdaysChild';
Child.register();
<|endoftext|>


<commit_before>var Media, server = false;
if (typeof exports !== 'undefined') {
    BackboneIO = require(__dirname + '/Default');
    _ = require('underscore');
    Media = exports.Media = {};
    server = true;
} else {
    Media = root.Media = {};
}

var leadingZero = function (num) {
    return (num < 10) ? "0"+num : num;
}

var toMilliseconds = function (time) {
    var t = time.match(/(\d{2}):(\d{2}):(\d{2})\.(\d*)/);
    t.shift();
    d = moment.duration ({
        hours:        t[0],
        minutes:      t[1],
        seconds:      t[2],
        milliseconds: t[3]*10
    });

    return d.asMilliseconds();
};

var prettyTime =  function (m) {
    d = moment.duration(m);
    var p = leadingZero(d.hours())   + ':'
        + leadingZero(d.minutes()) + ':'
        + leadingZero(d.seconds()) + '.'
        + leadingZero(d.milliseconds()/10);
    return p;
};

var arrayDuration = function (a) {
    return  _.reduce(a, function (m, n) {
        return m + toMilliseconds (n);}, 0);
};

Media.Model = BackboneIO.Model.extend({
    urlRoot: "media",
    idAttribute: "_id",
    validate: function (attrs) {
        console.log ("checking", attrs);
        if (attrs.file && ! attrs.file.length) {
            console.log ('NO file');
            return new Error("file must be defined");
        }
        if (attrs.stat       &&
            (! attrs.stat.mtime ||
             ! attrs.stat.size  ||
             attrs.stat.size <= 4000)) {
            console.log ('NO or BAD stat');
            return new Error("stat must be defined");
        }
    },
    defaults: {
        _id: null,
        file: "None",
        name: "",
        audio: "None",
        video: "None",
        template: 'mediaview',
    }
});

/* all methods are overriden in Default.js */
Media.Collection = BackboneIO.Collection.extend({
    model: Media.Model,
    url: 'media',
    add: function (models, opts) {
        var self = this;
        console.log ('hacked add', this, models, opts);

        if (!opts)
            opts = {};

        var index = (opts.at) ? opts.at : this.size();
        opts.at = index;

        if (! (models instanceof Array))
            models = [models]

        models.forEach (function (e, i) {
            self.set_index (e, index + i);
            console.log ('aaadododd', e, opts);
        });

        return BackboneIO.Collection.prototype.add.call (this, models.reverse(), opts);
    },
    create: function (model, opts) {
        var index = (opts && opts.at) ? opts.at : this.size();
        this.set_index (model, index);
        return Backbone.Collection.prototype.create.call (this, model, opts);
    },
});

Media.Piece = Media.Model.extend ({
    urlRoot: 'piece',
    defaults: {
        trim: {
            timein:  0,
            timeout: 0,
        },
        overlay: [],
    },
});

Media.Block = Media.Collection.extend ({
    model: Media.Piece,
    url: 'piece',
    set_index: function (model, index) {
        console.log ('BLOCK set_index');
        console.trace();
        var id = this._get_id(model);
        this._set_id (model, id.split('-')[0] + '-' + index);

        return Media.Collection.prototype.set_index.call (this, model, index);
    },
});

Media.List = Media.Model.extend ({
    urlRoot: 'list',
    newCol: function (models, opts) {
        return new Media.Block (models, opts);
    },
    initialize: function () {
        var models = this.get('models')
        var col    = this.get('collection')
        console.log ("initing media list", models, col);
        if (!col || col instanceof Array) {
            col = this.newCol(models, {connectable: true});
            console.log ('col is array ! recreating as collection', col);
        }

        var self = this;
        col.wrapper = this;

        col.bind('all', function (a, b) {
            console.log ('got a change in the force', a, b);
            var models = self.get('collection').models;
            self.set({models: models});
            self.updateId(models);
            console.log ('-----got a change in the force', a, b);
        }, this);

        this.set ({collection: col, models: col.models});
        Media.Model.prototype.initialize.call (this);
    },
    hashSeed: function () {
        return this.get('name');
    },
    updateId: function (models) {
        if (server)
            return;
        var spark = new SparkMD5();
        spark.append (this.hashSeed() || 'NULL');

        console.log ('(MODEL) about to calculate MD5 for', models);

        models.forEach(function (e) {spark.append(e);});
        this.set_id(spark.end());
    },

    defaults: {
        collection: null,
        models: [],
        name: null,
        hash: null,
        fixed: false,
        pos: 0,
    },
});

Media.Universe = Media.Collection.extend ({
    url: 'list',
    model: Media.List,
});

if(server) module.exports = Media;
else root.Media = Media;
<commit_msg>Calculate inner-duration in Model, we need to use this in MediaList... but we'd have to deal with durationless models there<commit_after>var Media, server = false;
if (typeof exports !== 'undefined') {
    BackboneIO = require(__dirname + '/Default');
    _ = require('underscore');
    Media = exports.Media = {};
    server = true;
} else {
    Media = root.Media = {};
}

var leadingZero = function (num) {
    return (num < 10) ? "0"+num : num;
}

var toMilliseconds = function (time) {
    var t = time.match(/(\d{2}):(\d{2}):(\d{2})\.(\d*)/);
    t.shift();
    d = moment.duration ({
        hours:        t[0],
        minutes:      t[1],
        seconds:      t[2],
        milliseconds: t[3]*10
    });

    return d.asMilliseconds();
};

var prettyTime =  function (m) {
    d = moment.duration(m);
    var p = leadingZero(d.hours())   + ':'
        + leadingZero(d.minutes()) + ':'
        + leadingZero(d.seconds()) + '.'
        + leadingZero(d.milliseconds()/10);
    return p;
};

var arrayDuration = function (a) {
    return  _.reduce(a, function (m, n) {
        return m + toMilliseconds (n);}, 0);
};

Media.Model = BackboneIO.Model.extend({
    urlRoot: "media",
    idAttribute: "_id",
    validate: function (attrs) {
        console.log ("checking", attrs);
        if (attrs.file && ! attrs.file.length) {
            console.log ('NO file');
            return new Error("file must be defined");
        }
        if (attrs.stat       &&
            (! attrs.stat.mtime ||
             ! attrs.stat.size  ||
             attrs.stat.size <= 4000)) {
            console.log ('NO or BAD stat');
            return new Error("stat must be defined");
        }
    },
    defaults: {
        _id: null,
        file: "None",
        name: "",
        audio: "None",
        video: "None",
        template: 'mediaview',
    }
});

/* all methods are overriden in Default.js */
Media.Collection = BackboneIO.Collection.extend({
    model: Media.Model,
    url: 'media',
    add: function (models, opts) {
        var self = this;
        console.log ('hacked add', this, models, opts);

        if (!opts)
            opts = {};

        var index = (opts.at) ? opts.at : this.size();
        opts.at = index;

        if (! (models instanceof Array))
            models = [models]

        models.forEach (function (e, i) {
            self.set_index (e, index + i);
            console.log ('aaadododd', e, opts);
        });

        return BackboneIO.Collection.prototype.add.call (this, models.reverse(), opts);
    },
    create: function (model, opts) {
        var index = (opts && opts.at) ? opts.at : this.size();
        this.set_index (model, index);
        return Backbone.Collection.prototype.create.call (this, model, opts);
    },
});

Media.Piece = Media.Model.extend ({
    urlRoot: 'piece',
    defaults: {
        trim: {
            timein:  0,
            timeout: 0,
        },
        overlay: [],
    },
});

Media.Block = Media.Collection.extend ({
    model: Media.Piece,
    url: 'piece',
    set_index: function (model, index) {
        console.log ('BLOCK set_index');
        console.trace();
        var id = this._get_id(model);
        this._set_id (model, id.split('-')[0] + '-' + index);

        return Media.Collection.prototype.set_index.call (this, model, index);
    },
});

Media.List = Media.Model.extend ({
    urlRoot: 'list',
    newCol: function (models, opts) {
        return new Media.Block (models, opts);
    },
    initialize: function () {
        var models = this.get('models')
        var col    = this.get('collection')
        console.log ("initing media list", models, col);
        if (!col || col instanceof Array) {
            col = this.newCol(models, {connectable: true});
            console.log ('col is array ! recreating as collection', col);
        }

        var self = this;
        col.wrapper = this;

        col.bind('all', function (a, b) {
            console.log ('got a change in the force', a, b);
            var models = self.get('collection').models;
            self.set({models: models});
            self.updateId(models);
            self.update_duration(col);
            console.log ('-----got a change in the force', a, b);
        }, this);

        this.set ({collection: col, models: col.models});
        Media.Model.prototype.initialize.call (this);
    },
    update_duration: function (col) {
        console.log ('TOTAL TIME IN MODEL', col.pluck('durationraw'));
        this.set({duration : arrayDuration(col.pluck('durationraw'))});
        console.log ('TOTAL TIME IN MODEL->', this.pretty_duration());
    },
    pretty_duration: function () {
        return prettyTime (this.get('duration'));
    },
    hashSeed: function () {
        return this.get('name');
    },
    updateId: function (models) {
        if (server)
            return;
        var spark = new SparkMD5();
        spark.append (this.hashSeed() || 'NULL');

        console.log ('(MODEL) about to calculate MD5 for', models);

        models.forEach(function (e) {spark.append(e);});
        this.set_id(spark.end());
    },

    defaults: {
        collection: null,
        models: [],
        name: null,
        hash: null,
        fixed: false,
        duration: 0,
        pos: 0,
    },
});

Media.Universe = Media.Collection.extend ({
    url: 'list',
    model: Media.List,
});

if(server) module.exports = Media;
else root.Media = Media;
<|endoftext|>


<commit_before>/*!
 * parser.js - packet parser for bcoin
 * Copyright (c) 2014-2015, Fedor Indutny (MIT License)
 * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
 * https://github.com/bcoin-org/bcoin
 */

'use strict';

var Network = require('../protocol/network');
var EventEmitter = require('events').EventEmitter;
var utils = require('../utils/utils');
var crypto = require('../crypto/crypto');
var assert = require('assert');
var constants = require('../protocol/constants');
var packets = require('./packets');

/**
 * Protocol packet parser
 * @exports Parser
 * @constructor
 * @param {Object?} options
 * @emits Parser#error
 * @emits Parser#packet
 */

function Parser(options) {
  if (!(this instanceof Parser))
    return new Parser(options);

  if (!options)
    options = {};

  EventEmitter.call(this);

  this.network = Network.get(options.network);
  this.bip151 = options.bip151;

  this.pending = [];
  this.total = 0;
  this.waiting = 24;
  this.header = null;

  this._init();
}

utils.inherits(Parser, EventEmitter);

/**
 * Initialize. Bind to events.
 * @private
 * @param {String} str
 */

Parser.prototype._init = function _init(str) {
  var self = this;

  if (!this.bip151)
    return;

  this.bip151.on('packet', function(cmd, body) {
    var payload;
    try {
      payload = self.parsePayload(cmd, body);
    } catch (e) {
      return self.error(e);
    }
    self.emit('packet', payload);
  });
};

/**
 * Emit an error.
 * @private
 * @param {...String} msg
 */

Parser.prototype.error = function error() {
  var msg = utils.fmt.apply(utils, arguments);
  this.emit('error', new Error(msg));
};

/**
 * Feed data to the parser.
 * @param {Buffer} data
 */

Parser.prototype.feed = function feed(data) {
  var chunk, off, len;

  if (this.bip151 && this.bip151.handshake)
    return this.bip151.feed(data);

  this.total += data.length;
  this.pending.push(data);

  while (this.total >= this.waiting) {
    chunk = new Buffer(this.waiting);
    off = 0;
    len = 0;

    while (off < chunk.length) {
      len = this.pending[0].copy(chunk, off);
      if (len === this.pending[0].length)
        this.pending.shift();
      else
        this.pending[0] = this.pending[0].slice(len);
      off += len;
    }

    assert.equal(off, chunk.length);

    this.total -= chunk.length;
    this.parse(chunk);
  }
};

/**
 * Parse a fully-buffered chunk.
 * @param {Buffer} chunk
 */

Parser.prototype.parse = function parse(data) {
  var payload, checksum;

  assert(data.length <= constants.MAX_MESSAGE);

  if (!this.header) {
    this.header = this.parseHeader(data);
    return;
  }

  checksum = crypto.hash256(data).readUInt32LE(0, true);

  if (checksum !== this.header.checksum) {
    this.waiting = 24;
    this.header = null;
    return this.error(
      'Invalid checksum: %d != %d',
      utils.hex32(checksum),
      utils.hex32(this.header.checksum));
  }

  try {
    payload = this.parsePayload(this.header.cmd, data);
  } catch (e) {
    this.waiting = 24;
    this.header = null;
    this.emit('error', e);
    return;
  }

  this.waiting = 24;
  this.header = null;

  this.emit('packet', payload);
};

/**
 * Parse buffered packet header.
 * @param {Buffer} data - Header.
 * @returns {Header}
 */

Parser.prototype.parseHeader = function parseHeader(data) {
  var i, magic, cmd, size, checksum;

  magic = data.readUInt32LE(0, true);

  if (magic !== this.network.magic)
    return this.error('Invalid magic value: %s.', utils.hex32(magic));

  // Count length of the cmd
  for (i = 0; data[i + 4] !== 0 && i < 12; i++);

  if (i === 12)
    return this.error('Non NULL-terminated command.');

  cmd = data.toString('ascii', 4, 4 + i);

  size = data.readUInt32LE(16, true);

  if (size > constants.MAX_MESSAGE) {
    this.waiting = 24;
    return this.error('Packet length too large: %dmb.', utils.mb(size));
  }

  this.waiting = size;

  checksum = data.readUInt32LE(20, true);

  return new Header(cmd, size, checksum);
};

/**
 * Parse a payload.
 * @param {String} cmd - Packet type.
 * @param {Buffer} data - Payload.
 * @returns {Object}
 */

Parser.prototype.parsePayload = function parsePayload(cmd, data) {
  return packets.fromRaw(cmd, data);
};

/**
 * Packet Header
 * @constructor
 * @private
 */

function Header(cmd, size, checksum) {
  this.cmd = cmd;
  this.size = size;
  this.checksum = checksum;
}

/*
 * Expose
 */

module.exports = Parser;
<commit_msg>net: fix packet checksum error handling.<commit_after>/*!
 * parser.js - packet parser for bcoin
 * Copyright (c) 2014-2015, Fedor Indutny (MIT License)
 * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
 * https://github.com/bcoin-org/bcoin
 */

'use strict';

var Network = require('../protocol/network');
var EventEmitter = require('events').EventEmitter;
var utils = require('../utils/utils');
var crypto = require('../crypto/crypto');
var assert = require('assert');
var constants = require('../protocol/constants');
var packets = require('./packets');

/**
 * Protocol packet parser
 * @exports Parser
 * @constructor
 * @param {Object?} options
 * @emits Parser#error
 * @emits Parser#packet
 */

function Parser(options) {
  if (!(this instanceof Parser))
    return new Parser(options);

  if (!options)
    options = {};

  EventEmitter.call(this);

  this.network = Network.get(options.network);
  this.bip151 = options.bip151;

  this.pending = [];
  this.total = 0;
  this.waiting = 24;
  this.header = null;

  this._init();
}

utils.inherits(Parser, EventEmitter);

/**
 * Initialize. Bind to events.
 * @private
 * @param {String} str
 */

Parser.prototype._init = function _init(str) {
  var self = this;

  if (!this.bip151)
    return;

  this.bip151.on('packet', function(cmd, body) {
    var payload;
    try {
      payload = self.parsePayload(cmd, body);
    } catch (e) {
      return self.error(e);
    }
    self.emit('packet', payload);
  });
};

/**
 * Emit an error.
 * @private
 * @param {...String} msg
 */

Parser.prototype.error = function error() {
  var msg = utils.fmt.apply(utils, arguments);
  this.emit('error', new Error(msg));
};

/**
 * Feed data to the parser.
 * @param {Buffer} data
 */

Parser.prototype.feed = function feed(data) {
  var chunk, off, len;

  if (this.bip151 && this.bip151.handshake)
    return this.bip151.feed(data);

  this.total += data.length;
  this.pending.push(data);

  while (this.total >= this.waiting) {
    chunk = new Buffer(this.waiting);
    off = 0;
    len = 0;

    while (off < chunk.length) {
      len = this.pending[0].copy(chunk, off);
      if (len === this.pending[0].length)
        this.pending.shift();
      else
        this.pending[0] = this.pending[0].slice(len);
      off += len;
    }

    assert.equal(off, chunk.length);

    this.total -= chunk.length;
    this.parse(chunk);
  }
};

/**
 * Parse a fully-buffered chunk.
 * @param {Buffer} chunk
 */

Parser.prototype.parse = function parse(data) {
  var payload, checksum;

  assert(data.length <= constants.MAX_MESSAGE);

  if (!this.header) {
    this.header = this.parseHeader(data);
    return;
  }

  checksum = crypto.hash256(data).readUInt32LE(0, true);

  if (checksum !== this.header.checksum) {
    this.waiting = 24;
    this.header = null;
    return this.error('Invalid checksum: %d.', utils.hex32(checksum));
  }

  try {
    payload = this.parsePayload(this.header.cmd, data);
  } catch (e) {
    this.waiting = 24;
    this.header = null;
    this.emit('error', e);
    return;
  }

  this.waiting = 24;
  this.header = null;

  this.emit('packet', payload);
};

/**
 * Parse buffered packet header.
 * @param {Buffer} data - Header.
 * @returns {Header}
 */

Parser.prototype.parseHeader = function parseHeader(data) {
  var i, magic, cmd, size, checksum;

  magic = data.readUInt32LE(0, true);

  if (magic !== this.network.magic)
    return this.error('Invalid magic value: %s.', utils.hex32(magic));

  // Count length of the cmd
  for (i = 0; data[i + 4] !== 0 && i < 12; i++);

  if (i === 12)
    return this.error('Non NULL-terminated command.');

  cmd = data.toString('ascii', 4, 4 + i);

  size = data.readUInt32LE(16, true);

  if (size > constants.MAX_MESSAGE) {
    this.waiting = 24;
    return this.error('Packet length too large: %dmb.', utils.mb(size));
  }

  this.waiting = size;

  checksum = data.readUInt32LE(20, true);

  return new Header(cmd, size, checksum);
};

/**
 * Parse a payload.
 * @param {String} cmd - Packet type.
 * @param {Buffer} data - Payload.
 * @returns {Object}
 */

Parser.prototype.parsePayload = function parsePayload(cmd, data) {
  return packets.fromRaw(cmd, data);
};

/**
 * Packet Header
 * @constructor
 * @private
 */

function Header(cmd, size, checksum) {
  this.cmd = cmd;
  this.size = size;
  this.checksum = checksum;
}

/*
 * Expose
 */

module.exports = Parser;
<|endoftext|>