summaryrefslogtreecommitdiff
path: root/node_modules/mongoose/lib
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/mongoose/lib')
-rw-r--r--node_modules/mongoose/lib/collection.js167
-rw-r--r--node_modules/mongoose/lib/connection.js517
-rw-r--r--node_modules/mongoose/lib/document.js1223
-rw-r--r--node_modules/mongoose/lib/drivers/node-mongodb-native/binary.js8
-rw-r--r--node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js176
-rw-r--r--node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js106
-rw-r--r--node_modules/mongoose/lib/drivers/node-mongodb-native/objectid.js43
-rw-r--r--node_modules/mongoose/lib/error.js25
-rw-r--r--node_modules/mongoose/lib/index.js368
-rw-r--r--node_modules/mongoose/lib/model.js917
-rw-r--r--node_modules/mongoose/lib/namedscope.js70
-rw-r--r--node_modules/mongoose/lib/promise.js145
-rw-r--r--node_modules/mongoose/lib/query.js1527
-rw-r--r--node_modules/mongoose/lib/querystream.js179
-rw-r--r--node_modules/mongoose/lib/schema.js565
-rw-r--r--node_modules/mongoose/lib/schema/array.js232
-rw-r--r--node_modules/mongoose/lib/schema/boolean.js59
-rw-r--r--node_modules/mongoose/lib/schema/buffer.js106
-rw-r--r--node_modules/mongoose/lib/schema/date.js116
-rw-r--r--node_modules/mongoose/lib/schema/documentarray.js141
-rw-r--r--node_modules/mongoose/lib/schema/index.js22
-rw-r--r--node_modules/mongoose/lib/schema/mixed.js63
-rw-r--r--node_modules/mongoose/lib/schema/number.js142
-rw-r--r--node_modules/mongoose/lib/schema/objectid.js126
-rw-r--r--node_modules/mongoose/lib/schema/string.js180
-rw-r--r--node_modules/mongoose/lib/schemadefault.js32
-rw-r--r--node_modules/mongoose/lib/schematype.js428
-rw-r--r--node_modules/mongoose/lib/statemachine.js179
-rw-r--r--node_modules/mongoose/lib/types/array.js422
-rw-r--r--node_modules/mongoose/lib/types/buffer.js171
-rw-r--r--node_modules/mongoose/lib/types/documentarray.js133
-rw-r--r--node_modules/mongoose/lib/types/embedded.js103
-rw-r--r--node_modules/mongoose/lib/types/index.js14
-rw-r--r--node_modules/mongoose/lib/types/number.js84
-rw-r--r--node_modules/mongoose/lib/types/objectid.js12
-rw-r--r--node_modules/mongoose/lib/utils.js434
-rw-r--r--node_modules/mongoose/lib/virtualtype.js74
37 files changed, 9309 insertions, 0 deletions
diff --git a/node_modules/mongoose/lib/collection.js b/node_modules/mongoose/lib/collection.js
new file mode 100644
index 0000000..c4d5e79
--- /dev/null
+++ b/node_modules/mongoose/lib/collection.js
@@ -0,0 +1,167 @@
+
+/**
+ * Collection constructor
+ *
+ * @param {String} collection name
+ * @param {Collection} connection object
+ * @api public
+ */
+
+function Collection (name, conn) {
+ this.name = name;
+ this.conn = conn;
+ this.buffer = true;
+ this.queue = [];
+ if (this.conn.readyState == 1) this.onOpen();
+};
+
+/**
+ * The collection name
+ *
+ * @api public
+ */
+
+Collection.prototype.name;
+
+/**
+ * The Connection instance
+ *
+ * @api public
+ */
+
+Collection.prototype.conn;
+
+/**
+ * Called when the database connects
+ *
+ * @api private
+ */
+
+Collection.prototype.onOpen = function () {
+ var self = this;
+ this.buffer = false;
+ self.doQueue();
+};
+
+/**
+ * Called when the database disconnects
+ *
+ * @api private
+ */
+
+Collection.prototype.onClose = function () {
+ this.buffer = true;
+};
+
+/**
+ * Adds a callback to the queue
+ *
+ * @param {String} method name
+ * @param {Array} arguments
+ * @api private
+ */
+
+Collection.prototype.addQueue = function (name, args) {
+ this.queue.push([name, args]);
+ return this;
+};
+
+/**
+ * Executes the current queue
+ *
+ * @api private
+ */
+
+Collection.prototype.doQueue = function () {
+ for (var i = 0, l = this.queue.length; i < l; i++){
+ this[this.queue[i][0]].apply(this, this.queue[i][1]);
+ }
+ this.queue = [];
+ return this;
+};
+
+/**
+ * Ensure index function
+ *
+ * @api private
+ */
+
+Collection.prototype.ensureIndex = function(){
+ throw new Error('Collection#ensureIndex unimplemented by driver');
+};
+
+/**
+ * FindAndModify command
+ *
+ * @api private
+ */
+
+Collection.prototype.findAndModify = function(){
+ throw new Error('Collection#findAndModify unimplemented by driver');
+};
+
+/**
+ * FindOne command
+ *
+ * @api private
+ */
+
+Collection.prototype.findOne = function(){
+ throw new Error('Collection#findOne unimplemented by driver');
+};
+
+/**
+ * Find command
+ *
+ * @api private
+ */
+
+Collection.prototype.find = function(){
+ throw new Error('Collection#find unimplemented by driver');
+};
+
+/**
+ * Insert command
+ *
+ * @api private
+ */
+
+Collection.prototype.insert = function(){
+ throw new Error('Collection#insert unimplemented by driver');
+};
+
+/**
+ * Update command
+ *
+ * @api private
+ */
+
+Collection.prototype.save = function(){
+ throw new Error('Collection#save unimplemented by driver');
+};
+
+/**
+ * Insert command
+ *
+ * @api private
+ */
+
+Collection.prototype.update = function(){
+ throw new Error('Collection#update unimplemented by driver');
+};
+
+/**
+ * getIndexes command
+ *
+ * @api private
+ */
+
+Collection.prototype.getIndexes = function(){
+ throw new Error('Collection#getIndexes unimplemented by driver');
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = Collection;
diff --git a/node_modules/mongoose/lib/connection.js b/node_modules/mongoose/lib/connection.js
new file mode 100644
index 0000000..37f7e2a
--- /dev/null
+++ b/node_modules/mongoose/lib/connection.js
@@ -0,0 +1,517 @@
+/**
+ * Module dependencies.
+ */
+
+var url = require('url')
+ , utils = require('./utils')
+ , EventEmitter = utils.EventEmitter
+ , driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native'
+ , Model = require('./model')
+ , Schema = require('./schema')
+ , Collection = require(driver + '/collection');
+
+/**
+ * Connection constructor. For practical reasons, a Connection equals a Db
+ *
+ * @param {Mongoose} mongoose base
+ * @api public
+ */
+
+function Connection (base) {
+ this.base = base;
+ this.collections = {};
+ this.models = {};
+};
+
+/**
+ * Inherit from EventEmitter.
+ *
+ */
+
+Connection.prototype.__proto__ = EventEmitter.prototype;
+
+/**
+ * Connection ready state:
+ * 0 = Disconnected
+ * 1 = Connected
+ * 2 = Connecting
+ * 3 = Disconnecting
+ *
+ * @api public
+ */
+
+Connection.prototype.readyState = 0;
+
+/**
+ * A hash of the collections associated with this connection
+ */
+
+Connection.prototype.collections;
+
+/**
+ * The mongodb.Db instance, set when the connection is opened
+ *
+ * @api public
+ */
+
+Connection.prototype.db;
+
+/**
+ * Establishes the connection
+ *
+ * `options` is a hash with the following optional properties:
+ *
+ * options.db - passed to the connection db instance
+ * options.server - passed to the connection server instance(s)
+ * options.replset - passed to the connection ReplSetServer instance
+ * options.user - username for authentication
+ * options.pass - password for authentication
+ *
+ * Notes:
+ *
+ * Mongoose forces the db option `forceServerObjectId` false and cannot
+ * be overridden.
+ *
+ * Mongoose defaults the server `auto_reconnect` options to true which
+ * can be overridden.
+ *
+ * See the node-mongodb-native driver instance for options that it
+ * understands.
+ *
+ * @param {String} mongodb://uri
+ * @return {Connection} self
+ * @see https://github.com/christkv/node-mongodb-native
+ * @api public
+ */
+
+Connection.prototype.open = function (host, database, port, options, callback) {
+ var self = this
+ , uri;
+
+ if ('string' === typeof database) {
+ switch (arguments.length) {
+ case 2:
+ port = 27017;
+ case 3:
+ switch (typeof port) {
+ case 'function':
+ callback = port, port = 27017;
+ break;
+ case 'object':
+ options = port, port = 27017;
+ break;
+ }
+ break;
+ case 4:
+ if ('function' === typeof options)
+ callback = options, options = {};
+ }
+ } else {
+ switch (typeof database) {
+ case 'function':
+ callback = database, database = undefined;
+ break;
+ case 'object':
+ options = database;
+ database = undefined;
+ callback = port;
+ break;
+ }
+
+ uri = url.parse(host);
+ host = uri.hostname;
+ port = uri.port || 27017;
+ database = uri.pathname && uri.pathname.replace(/\//g, '');
+ }
+
+ callback = callback || noop;
+ this.options = this.defaultOptions(options);
+
+ // make sure we can open
+ if (0 !== this.readyState) {
+ var err = new Error('Trying to open unclosed connection.');
+ err.state = this.readyState;
+ callback(err);
+ return this;
+ }
+
+ if (!host) {
+ callback(new Error('Missing connection hostname.'));
+ return this;
+ }
+
+ if (!database) {
+ callback(new Error('Missing connection database.'));
+ return this;
+ }
+
+ // handle authentication
+ if (uri && uri.auth) {
+ var auth = uri.auth.split(':');
+ this.user = auth[0];
+ this.pass = auth[1];
+
+ // Check hostname for user/pass
+ } else if (/@/.test(host) && /:/.test(host.split('@')[0])) {
+ host = host.split('@');
+ var auth = host.shift().split(':');
+ host = host.pop();
+ this.user = auth[0];
+ this.pass = auth[1];
+
+ // user/pass options
+ } else if (options && options.user && options.pass) {
+ this.user = options.user;
+ this.pass = options.pass;
+
+ } else {
+ this.user = this.pass = undefined;
+ }
+
+ this.name = database;
+ this.host = host;
+ this.port = port;
+
+ // signal connecting
+ this.readyState = 2;
+ this.emit('opening');
+
+ // open connection
+ this.doOpen(function (err) {
+ if (err) {
+ if (self._events && self._events.error &&
+ ('function' == typeof self._events.error || self._events.error.length)) {
+ self.emit("error", err);
+ }
+ self.readyState = 0;
+ } else {
+ self.onOpen();
+ }
+
+ callback(err || null);
+ });
+
+ return this;
+};
+
+/**
+ * Connects to a replica set.
+ *
+ * Supply a comma-separted list of mongodb:// URIs. You only need to specify
+ * the database name and/or auth to one of them.
+ *
+ * The options parameter is passed to the low level connection. See the
+ * node-mongodb-native driver instance for detail.
+ *
+ * @param {String} comma-separated mongodb:// URIs
+ * @param {String} optional database name
+ * @param {Object} optional options
+ * @param {Function} optional callback
+ */
+
+Connection.prototype.openSet = function (uris, database, options, callback) {
+ var uris = uris.split(',')
+ , self = this;
+
+ switch (arguments.length) {
+ case 3:
+ this.name = database;
+ if ('function' === typeof options) callback = options, options = {};
+ break;
+ case 2:
+ switch (typeof database) {
+ case 'string':
+ this.name = database;
+ case 'function':
+ callback = database, database = null;
+ break;
+ case 'object':
+ options = database, database = null;
+ break;
+ }
+ }
+
+ this.options = options = this.defaultOptions(options);
+ callback = callback || noop;
+
+ if (uris.length < 2) {
+ callback(new Error('Please provide comma-separated URIs'));
+ return this;
+ }
+
+ this.host = [];
+ this.port = [];
+
+ uris.forEach(function (uri) {
+ var uri = url.parse(uri);
+
+ self.host.push(uri.hostname);
+ self.port.push(uri.port || 27017);
+
+ if (!self.name && uri.pathname.replace(/\//g, ''))
+ self.name = uri.pathname.replace(/\//g, '');
+
+ if (!self.user && uri.auth) {
+ var auth = uri.auth.split(':');
+ self.user = auth[0];
+ self.pass = auth[1];
+ }
+ });
+
+ if (!this.name) {
+ callback(new Error('No database name provided for replica set'));
+ return this;
+ }
+
+ this.readyState = 2;
+ this.emit('opening');
+
+ // open connection
+ this.doOpenSet(function (err) {
+ if (err) {
+ if (self._events && self._events.error && self._events.error.length) {
+ self.emit("error", err);
+ }
+ self.readyState = 0;
+ } else {
+ self.onOpen();
+ }
+
+ callback(err || null);
+ });
+};
+
+/**
+ * Called when the connection is opened
+ *
+ * @api private
+ */
+
+Connection.prototype.onOpen = function () {
+ var self = this;
+
+ function open () {
+ self.readyState = 1;
+
+ // avoid having the collection subscribe to our event emitter
+ // to prevent 0.3 warning
+ for (var i in self.collections)
+ self.collections[i].onOpen();
+
+ self.emit('open');
+ };
+
+ // re-authenticate
+ if (self.user && self.pass)
+ self.db.authenticate(self.user, self.pass, open);
+ else
+ open();
+};
+
+/**
+ * Closes the connection
+ *
+ * @param {Function} optional callback
+ * @return {Connection} self
+ * @api public
+ */
+
+Connection.prototype.close = function (callback) {
+ var self = this
+ , callback = callback || function(){};
+
+ switch (this.readyState){
+ case 0: // disconnected
+ callback(null);
+ break;
+
+ case 1: // connected
+ this.readyState = 3;
+ this.doClose(function(err){
+ if (err){
+ callback(err);
+ } else {
+ self.onClose();
+ callback(null);
+ }
+ });
+ break;
+
+ case 2: // connecting
+ this.once('open', function(){
+ self.close(callback);
+ });
+ break;
+
+ case 3: // disconnecting
+ this.once('close', function () {
+ callback(null);
+ });
+ break;
+ }
+
+ return this;
+};
+
+/**
+ * Called when the connection closes
+ *
+ * @api private
+ */
+
+Connection.prototype.onClose = function () {
+ this.readyState = 0;
+
+ // avoid having the collection subscribe to our event emitter
+ // to prevent 0.3 warning
+ for (var i in this.collections)
+ this.collections[i].onClose();
+
+ this.emit('close');
+};
+
+/**
+ * Retrieves a collection, creating it if not cached.
+ *
+ * @param {String} collection name
+ * @return {Collection} collection instance
+ * @api public
+ */
+
+Connection.prototype.collection = function (name) {
+ if (!(name in this.collections))
+ this.collections[name] = new Collection(name, this);
+ return this.collections[name];
+};
+
+/**
+ * Defines a model or retrieves it
+ *
+ * @param {String} model name
+ * @param {Schema} schema object
+ * @param {String} collection name (optional, induced from model name)
+ * @api public
+ */
+
+Connection.prototype.model = function (name, schema, collection) {
+ if (!this.models[name]) {
+ var model = this.base.model(name, schema, collection, true)
+ , Model
+
+ if (this != model.prototype.connection) {
+ // subclass model using this connection and collection name
+ Model = function Model () {
+ model.apply(this, arguments);
+ };
+
+ Model.__proto__ = model;
+ Model.prototype.__proto__ = model.prototype;
+ Model.prototype.db = this;
+
+ // collection name discovery
+ if ('string' === typeof schema) {
+ collection = schema;
+ }
+
+ if (!collection) {
+ collection = model.prototype.schema.set('collection') || utils.toCollectionName(name);
+ }
+
+ Model.prototype.collection = this.collection(collection);
+ Model.init();
+ }
+
+ this.models[name] = Model || model;
+ }
+
+ return this.models[name];
+};
+
+/**
+ * Set profiling level.
+ *
+ * @param {Int|String} level - Either off (0), slow (1), or all (2)
+ * @param {Int} [ms] If profiling `level` is set to 1, this determines
+ * the threshold in milliseconds above which queries
+ * will be logged. Defaults to 100. (optional)
+ * @param {Function} callback
+ * @api public
+ */
+
+Connection.prototype.setProfiling = function (level, ms, callback) {
+ if (1 !== this.readyState) {
+ return this.on('open', this.setProfiling.bind(this, level, ms, callback));
+ }
+
+ if (!callback) callback = ms, ms = 100;
+
+ var cmd = {};
+
+ switch (level) {
+ case 0:
+ case 'off':
+ cmd.profile = 0;
+ break;
+ case 1:
+ case 'slow':
+ cmd.profile = 1;
+ if ('number' !== typeof ms) {
+ ms = parseInt(ms, 10);
+ if (isNaN(ms)) ms = 100;
+ }
+ cmd.slowms = ms;
+ break;
+ case 2:
+ case 'all':
+ cmd.profile = 2;
+ break;
+ default:
+ return callback(new Error('Invalid profiling level: '+ level));
+ }
+
+ this.db.executeDbCommand(cmd, function (err, resp) {
+ if (err) return callback(err);
+
+ var doc = resp.documents[0];
+
+ err = 1 === doc.ok
+ ? null
+ : new Error('Could not set profiling level to: '+ level)
+
+ callback(err, doc);
+ });
+};
+
+/**
+ * Prepares default connection options.
+ *
+ * @param {Object} options
+ * @api private
+ */
+
+Connection.prototype.defaultOptions = function (options) {
+ var o = options || {};
+
+ o.server = o.server || {};
+
+ if (!('auto_reconnect' in o.server)) {
+ o.server.auto_reconnect = true;
+ }
+
+ o.db = o.db || {};
+ o.db.forceServerObjectId = false;
+
+ return o;
+}
+
+/**
+ * Noop.
+ */
+
+function noop () {}
+
+/**
+ * Module exports.
+ */
+
+module.exports = Connection;
diff --git a/node_modules/mongoose/lib/document.js b/node_modules/mongoose/lib/document.js
new file mode 100644
index 0000000..0c80765
--- /dev/null
+++ b/node_modules/mongoose/lib/document.js
@@ -0,0 +1,1223 @@
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('events').EventEmitter
+ , MongooseError = require('./error')
+ , MixedSchema = require('./schema/mixed')
+ , Schema = require('./schema')
+ , ValidatorError = require('./schematype').ValidatorError
+ , utils = require('./utils')
+ , clone = utils.clone
+ , isMongooseObject = utils.isMongooseObject
+ , inspect = require('util').inspect
+ , StateMachine = require('./statemachine')
+ , ActiveRoster = StateMachine.ctor('require', 'modify', 'init')
+ , deepEqual = utils.deepEqual
+ , hooks = require('hooks')
+ , DocumentArray
+
+/**
+ * Document constructor.
+ *
+ * @param {Object} values to set
+ * @api private
+ */
+
+function Document (obj, fields) {
+ // node <0.4.3 bug
+ if (!this._events) this._events = {};
+ this.setMaxListeners(0);
+
+ this._strictMode = this.schema.options && this.schema.options.strict;
+
+ if ('boolean' === typeof fields) {
+ this._strictMode = fields;
+ fields = undefined;
+ } else {
+ this._selected = fields;
+ }
+
+ this._doc = this.buildDoc(fields);
+ this._activePaths = new ActiveRoster();
+ var self = this;
+ this.schema.requiredPaths.forEach(function (path) {
+ self._activePaths.require(path);
+ });
+
+ this._saveError = null;
+ this._validationError = null;
+ this.isNew = true;
+
+ if (obj) this.set(obj, undefined, true);
+
+ this._registerHooks();
+ this.doQueue();
+
+ this.errors = undefined;
+ this._shardval = undefined;
+};
+
+/**
+ * Inherit from EventEmitter.
+ */
+
+Document.prototype.__proto__ = EventEmitter.prototype;
+
+/**
+ * Base Mongoose instance for the model. Set by the Mongoose instance upon
+ * pre-compilation.
+ *
+ * @api public
+ */
+
+Document.prototype.base;
+
+/**
+ * Document schema as a nested structure.
+ *
+ * @api public
+ */
+
+Document.prototype.schema;
+
+/**
+ * Whether the document is new.
+ *
+ * @api public
+ */
+
+Document.prototype.isNew;
+
+/**
+ * Validation errors.
+ *
+ * @api public
+ */
+
+Document.prototype.errors;
+
+/**
+ * Builds the default doc structure
+ *
+ * @api private
+ */
+
+Document.prototype.buildDoc = function (fields) {
+ var doc = {}
+ , self = this
+ , exclude
+ , keys
+ , key
+ , ki
+
+ // determine if this doc is a result of a query with
+ // excluded fields
+ if (fields && 'Object' === fields.constructor.name) {
+ keys = Object.keys(fields);
+ ki = keys.length;
+
+ while (ki--) {
+ if ('_id' !== keys[ki]) {
+ exclude = 0 === fields[keys[ki]];
+ break;
+ }
+ }
+ }
+
+ var paths = Object.keys(this.schema.paths)
+ , plen = paths.length
+ , ii = 0
+
+ for (; ii < plen; ++ii) {
+ var p = paths[ii]
+ , type = this.schema.paths[p]
+ , path = p.split('.')
+ , len = path.length
+ , last = len-1
+ , doc_ = doc
+ , i = 0
+
+ for (; i < len; ++i) {
+ var piece = path[i]
+ , def
+
+ if (i === last) {
+ if (fields) {
+ if (exclude) {
+ // apply defaults to all non-excluded fields
+ if (p in fields) continue;
+
+ def = type.getDefault(self);
+ if ('undefined' !== typeof def) doc_[piece] = def;
+
+ } else {
+ // do nothing. only the fields specified in
+ // the query will be populated
+ }
+ } else {
+ def = type.getDefault(self);
+ if ('undefined' !== typeof def) doc_[piece] = def;
+ }
+ } else {
+ doc_ = doc_[piece] || (doc_[piece] = {});
+ }
+ }
+ };
+
+ return doc;
+};
+
+/**
+ * Inits (hydrates) the document without setters.
+ *
+ * Called internally after a document is returned
+ * from mongodb.
+ *
+ * @param {Object} document returned by mongo
+ * @param {Function} callback
+ * @api private
+ */
+
+Document.prototype.init = function (doc, fn) {
+ this.isNew = false;
+
+ init(this, doc, this._doc);
+ this._storeShard();
+
+ this.emit('init');
+ if (fn) fn(null);
+ return this;
+};
+
+/**
+ * Init helper.
+ * @param {Object} instance
+ * @param {Object} obj - raw mongodb doc
+ * @param {Object} doc - object we are initializing
+ * @private
+ */
+
+function init (self, obj, doc, prefix) {
+ prefix = prefix || '';
+
+ var keys = Object.keys(obj)
+ , len = keys.length
+ , schema
+ , path
+ , i;
+
+ while (len--) {
+ i = keys[len];
+ path = prefix + i;
+ schema = self.schema.path(path);
+
+ if (!schema && obj[i] && 'Object' === obj[i].constructor.name) {
+ // assume nested object
+ doc[i] = {};
+ init(self, obj[i], doc[i], path + '.');
+ } else {
+ if (obj[i] === null) {
+ doc[i] = null;
+ } else if (obj[i] !== undefined) {
+ if (schema) {
+ self.try(function(){
+ doc[i] = schema.cast(obj[i], self, true);
+ });
+ } else {
+ doc[i] = obj[i];
+ }
+ }
+ // mark as hydrated
+ self._activePaths.init(path);
+ }
+ }
+};
+
+/**
+ * _storeShard
+ *
+ * Stores the current values of the shard keys
+ * for use later in the doc.save() where clause.
+ *
+ * Shard key values do not / are not allowed to change.
+ *
+ * @param {Object} document
+ * @private
+ */
+
+Document.prototype._storeShard = function _storeShard () {
+ var key = this.schema.options.shardkey;
+ if (!(key && 'Object' == key.constructor.name)) return;
+
+ var orig = this._shardval = {}
+ , paths = Object.keys(key)
+ , len = paths.length
+ , val
+
+ for (var i = 0; i < len; ++i) {
+ val = this.getValue(paths[i]);
+ if (isMongooseObject(val)) {
+ orig[paths[i]] = val.toObject({ depopulate: true })
+ } else if (val.valueOf) {
+ orig[paths[i]] = val.valueOf();
+ } else {
+ orig[paths[i]] = val;
+ }
+ }
+}
+
+// Set up middleware support
+for (var k in hooks) {
+ Document.prototype[k] = Document[k] = hooks[k];
+}
+
+/**
+ * Sets a path, or many paths
+ *
+ * Examples:
+ * // path, value
+ * doc.set(path, value)
+ *
+ * // object
+ * doc.set({
+ * path : value
+ * , path2 : {
+ * path : value
+ * }
+ * }
+ *
+ * @param {String|Object} key path, or object
+ * @param {Object} value, or undefined or a prefix if first parameter is an object
+ * @param @optional {Schema|String|...} specify a type if this is an on-the-fly attribute
+ * @api public
+ */
+
+Document.prototype.set = function (path, val, type) {
+ var constructing = true === type
+ , adhoc = type && true !== type
+ , adhocs
+
+ if (adhoc) {
+ adhocs = this._adhocPaths || (this._adhocPaths = {});
+ adhocs[path] = Schema.interpretAsType(path, type);
+ }
+
+ if ('string' !== typeof path) {
+ // new Document({ key: val })
+
+ if (null === path || undefined === path) {
+ var _ = path;
+ path = val;
+ val = _;
+
+ } else {
+ var prefix = val
+ ? val + '.'
+ : '';
+
+ if (path instanceof Document) path = path._doc;
+
+ var keys = Object.keys(path)
+ , i = keys.length
+ , pathtype
+ , key
+
+ while (i--) {
+ key = keys[i];
+ if (null != path[key] && 'Object' === path[key].constructor.name
+ && !(this._path(prefix + key) instanceof MixedSchema)) {
+ this.set(path[key], prefix + key, constructing);
+ } else if (this._strictMode) {
+ pathtype = this.schema.pathType(prefix + key);
+ if ('real' === pathtype || 'virtual' === pathtype) {
+ this.set(prefix + key, path[key], constructing);
+ }
+ } else if (undefined !== path[key]) {
+ this.set(prefix + key, path[key], constructing);
+ }
+ }
+
+ return this;
+ }
+ }
+
+ var schema;
+ if ('virtual' === this.schema.pathType(path)) {
+ schema = this.schema.virtualpath(path);
+ schema.applySetters(val, this);
+ return this;
+ } else {
+ schema = this._path(path);
+ }
+
+ var parts = path.split('.')
+ , obj = this._doc
+ , self = this
+ , pathToMark
+ , subpaths
+ , subpath
+
+ // When using the $set operator the path to the field must already exist.
+ // Else mongodb throws: "LEFT_SUBFIELD only supports Object"
+
+ if (parts.length <= 1) {
+ pathToMark = path;
+ } else {
+ subpaths = parts.map(function (part, i) {
+ return parts.slice(0, i).concat(part).join('.');
+ });
+
+ for (var i = 0, l = subpaths.length; i < l; i++) {
+ subpath = subpaths[i];
+ if (this.isDirectModified(subpath) // earlier prefixes that are already
+ // marked as dirty have precedence
+ || this.get(subpath) === null) {
+ pathToMark = subpath;
+ break;
+ }
+ }
+
+ if (!pathToMark) pathToMark = path;
+ }
+
+ if ((!schema || null === val || undefined === val) ||
+ this.try(function(){
+ // if this doc is being constructed we should not
+ // trigger getters.
+ var cur = constructing ? undefined : self.get(path);
+ var casted = schema.cast(val, self, false, cur);
+ val = schema.applySetters(casted, self);
+ })) {
+
+ if (this.isNew) {
+ this.markModified(pathToMark);
+ } else {
+ var priorVal = this.get(path);
+
+ if (!this.isDirectModified(pathToMark)) {
+ if (undefined === val && !this.isSelected(path)) {
+ // special case:
+ // when a path is not selected in a query its initial
+ // value will be undefined.
+ this.markModified(pathToMark);
+ } else if (!deepEqual(val, priorVal)) {
+ this.markModified(pathToMark);
+ }
+ }
+ }
+
+ for (var i = 0, l = parts.length; i < l; i++) {
+ var next = i + 1
+ , last = next === l;
+
+ if (last) {
+ obj[parts[i]] = val;
+ } else {
+ if (obj[parts[i]] && 'Object' === obj[parts[i]].constructor.name) {
+ obj = obj[parts[i]];
+ } else if (obj[parts[i]] && Array.isArray(obj[parts[i]])) {
+ obj = obj[parts[i]];
+ } else {
+ obj = obj[parts[i]] = {};
+ }
+ }
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Gets a raw value from a path (no getters)
+ *
+ * @param {String} path
+ * @api private
+ */
+
+Document.prototype.getValue = function (path) {
+ var parts = path.split('.')
+ , obj = this._doc
+ , part;
+
+ for (var i = 0, l = parts.length; i < l-1; i++) {
+ part = parts[i];
+ path = convertIfInt(path);
+ obj = obj.getValue
+ ? obj.getValue(part) // If we have an embedded array document member
+ : obj[part];
+ if (!obj) return obj;
+ }
+
+ part = parts[l-1];
+ path = convertIfInt(path);
+
+ return obj.getValue
+ ? obj.getValue(part) // If we have an embedded array document member
+ : obj[part];
+};
+
+function convertIfInt (string) {
+ if (/^\d+$/.test(string)) {
+ return parseInt(string, 10);
+ }
+ return string;
+}
+
+/**
+ * Sets a raw value for a path (no casting, setters, transformations)
+ *
+ * @param {String} path
+ * @param {Object} value
+ * @api private
+ */
+
+Document.prototype.setValue = function (path, val) {
+ var parts = path.split('.')
+ , obj = this._doc;
+
+ for (var i = 0, l = parts.length; i < l-1; i++) {
+ obj = obj[parts[i]];
+ }
+
+ obj[parts[l-1]] = val;
+ return this;
+};
+
+/**
+ * Triggers casting on a specific path
+ *
+ * @todo - deprecate? not used anywhere
+ * @param {String} path
+ * @api public
+ */
+
+Document.prototype.doCast = function (path) {
+ var schema = this.schema.path(path);
+ if (schema)
+ this.setValue(path, this.getValue(path));
+};
+
+/**
+ * Gets a path
+ *
+ * @param {String} key path
+ * @param @optional {Schema|String|...} specify a type if this is an on-the-fly attribute
+ * @api public
+ */
+
+Document.prototype.get = function (path, type) {
+ var adhocs;
+ if (type) {
+ adhocs = this._adhocPaths || (this._adhocPaths = {});
+ adhocs[path] = Schema.interpretAsType(path, type);
+ }
+
+ var schema = this._path(path) || this.schema.virtualpath(path)
+ , pieces = path.split('.')
+ , obj = this._doc;
+
+ for (var i = 0, l = pieces.length; i < l; i++) {
+ obj = null == obj ? null : obj[pieces[i]];
+ }
+
+ if (schema) {
+ obj = schema.applyGetters(obj, this);
+ }
+
+ return obj;
+};
+
+/**
+ * Finds the path in the ad hoc type schema list or
+ * in the schema's list of type schemas
+ * @param {String} path
+ * @api private
+ */
+
+Document.prototype._path = function (path) {
+ var adhocs = this._adhocPaths
+ , adhocType = adhocs && adhocs[path];
+
+ if (adhocType) {
+ return adhocType;
+ } else {
+ return this.schema.path(path);
+ }
+};
+
+/**
+ * Commits a path, marking as modified if needed. Useful for mixed keys
+ *
+ * @api public
+ */
+
+Document.prototype.commit =
+Document.prototype.markModified = function (path) {
+ this._activePaths.modify(path);
+};
+
+/**
+ * Captures an exception that will be bubbled to `save`
+ *
+ * @param {Function} function to execute
+ * @param {Object} scope
+ */
+
+Document.prototype.try = function (fn, scope) {
+ var res;
+ try {
+ fn.call(scope);
+ res = true;
+ } catch (e) {
+ this.error(e);
+ res = false;
+ }
+ return res;
+};
+
+/**
+ * modifiedPaths
+ *
+ * Returns the list of paths that have been modified.
+ *
+ * If we set `documents.0.title` to 'newTitle'
+ * then `documents`, `documents.0`, and `documents.0.title`
+ * are modified.
+ *
+ * @api public
+ * @returns Boolean
+ */
+
+Document.prototype.__defineGetter__('modifiedPaths', function () {
+ var directModifiedPaths = Object.keys(this._activePaths.states.modify);
+
+ return directModifiedPaths.reduce(function (list, path) {
+ var parts = path.split('.');
+ return list.concat(parts.reduce(function (chains, part, i) {
+ return chains.concat(parts.slice(0, i).concat(part).join('.'));
+ }, []));
+ }, []);
+});
+
+/**
+ * Checks if a path or any full path containing path as part of
+ * its path chain has been directly modified.
+ *
+ * e.g., if we set `documents.0.title` to 'newTitle'
+ * then we have directly modified `documents.0.title`
+ * but not directly modified `documents` or `documents.0`.
+ * Nonetheless, we still say `documents` and `documents.0`
+ * are modified. They just are not considered direct modified.
+ * The distinction is important because we need to distinguish
+ * between what has been directly modified and what hasn't so
+ * that we can determine the MINIMUM set of dirty data
+ * that we want to send to MongoDB on a Document save.
+ *
+ * @param {String} path
+ * @returns Boolean
+ * @api public
+ */
+
+Document.prototype.isModified = function (path) {
+ return !!~this.modifiedPaths.indexOf(path);
+};
+
+/**
+ * Checks if a path has been directly set and modified. False if
+ * the path is only part of a larger path that was directly set.
+ *
+ * e.g., if we set `documents.0.title` to 'newTitle'
+ * then we have directly modified `documents.0.title`
+ * but not directly modified `documents` or `documents.0`.
+ * Nonetheless, we still say `documents` and `documents.0`
+ * are modified. They just are not considered direct modified.
+ * The distinction is important because we need to distinguish
+ * between what has been directly modified and what hasn't so
+ * that we can determine the MINIMUM set of dirty data
+ * that we want to send to MongoDB on a Document save.
+ *
+ * @param {String} path
+ * @returns Boolean
+ * @api public
+ */
+
+Document.prototype.isDirectModified = function (path) {
+ return (path in this._activePaths.states.modify);
+};
+
+/**
+ * Checks if a certain path was initialized
+ *
+ * @param {String} path
+ * @returns Boolean
+ * @api public
+ */
+
+Document.prototype.isInit = function (path) {
+ return (path in this._activePaths.states.init);
+};
+
+/**
+ * Checks if a path was selected.
+ * @param {String} path
+ * @return Boolean
+ * @api public
+ */
+
+Document.prototype.isSelected = function isSelected (path) {
+ if (this._selected) {
+
+ if ('_id' === path) {
+ return 0 !== this._selected._id;
+ }
+
+ var paths = Object.keys(this._selected)
+ , i = paths.length
+ , inclusive = false
+ , cur
+
+ while (i--) {
+ cur = paths[i];
+ if ('_id' == cur) continue;
+ inclusive = !! this._selected[cur];
+ break;
+ }
+
+ if (path in this._selected) {
+ return inclusive;
+ }
+
+ i = paths.length;
+
+ while (i--) {
+ cur = paths[i];
+ if ('_id' == cur) continue;
+
+ if (0 === cur.indexOf(path + '.')) {
+ return inclusive;
+ }
+
+ if (0 === (path + '.').indexOf(cur)) {
+ return inclusive;
+ }
+ }
+
+ return ! inclusive;
+ }
+
+ return true;
+}
+
+/**
+ * Validation middleware
+ *
+ * @param {Function} next
+ * @api public
+ */
+
+Document.prototype.validate = function (next) {
+ var total = 0
+ , self = this
+ , validating = {}
+
+ if (!this._activePaths.some('require', 'init', 'modify')) {
+ return complete();
+ }
+
+ function complete () {
+ next(self._validationError);
+ self._validationError = null;
+ }
+
+ this._activePaths.forEach('require', 'init', 'modify', function validatePath (path) {
+ if (validating[path]) return;
+
+ validating[path] = true;
+ total++;
+
+ process.nextTick(function(){
+ var p = self.schema.path(path);
+ if (!p) return --total || complete();
+
+ p.doValidate(self.getValue(path), function (err) {
+ if (err) self.invalidate(path, err);
+ --total || complete();
+ }, self);
+ });
+ });
+
+ return this;
+};
+
+/**
+ * Marks a path as invalid, causing a subsequent validation to fail.
+ *
+ * @param {String} path of the field to invalidate
+ * @param {String/Error} error of the path.
+ * @api public
+ */
+
+Document.prototype.invalidate = function (path, err) {
+ if (!this._validationError) {
+ this._validationError = new ValidationError(this);
+ }
+
+ if (!err || 'string' === typeof err) {
+ err = new ValidatorError(path, err);
+ }
+
+ this._validationError.errors[path] = err;
+}
+
+/**
+ * Resets the atomics and modified states of this document.
+ *
+ * @private
+ * @return {this}
+ */
+
+Document.prototype._reset = function reset () {
+ var self = this;
+ DocumentArray || (DocumentArray = require('./types/documentarray'));
+
+ this._activePaths
+ .map('init', 'modify', function (i) {
+ return self.getValue(i);
+ })
+ .filter(function (val) {
+ return (val && val instanceof DocumentArray && val.length);
+ })
+ .forEach(function (array) {
+ array.forEach(function (doc) {
+ doc._reset();
+ });
+ });
+
+ // clear atomics
+ this._dirty().forEach(function (dirt) {
+ var type = dirt.value;
+ if (type && type._path && type.doAtomics) {
+ type._atomics = {};
+ }
+ });
+
+ // Clear 'modify'('dirty') cache
+ this._activePaths.clear('modify');
+ var self = this;
+ this.schema.requiredPaths.forEach(function (path) {
+ self._activePaths.require(path);
+ });
+
+ return this;
+}
+
+/**
+ * Returns the dirty paths / vals
+ *
+ * @api private
+ */
+
+Document.prototype._dirty = function _dirty () {
+ var self = this;
+
+ var all = this._activePaths.map('modify', function (path) {
+ return { path: path
+ , value: self.getValue(path)
+ , schema: self._path(path) };
+ });
+
+ // Sort dirty paths in a flat hierarchy.
+ all.sort(function (a, b) {
+ return (a.path < b.path ? -1 : (a.path > b.path ? 1 : 0));
+ });
+
+ // Ignore "foo.a" if "foo" is dirty already.
+ var minimal = []
+ , lastReference = null;
+
+ all.forEach(function (item, i) {
+ if (item.path.indexOf(lastReference) !== 0) {
+ lastReference = item.path + '.';
+ minimal.push(item);
+ }
+ });
+
+ return minimal;
+}
+
+/**
+ * Returns if the document has been modified
+ *
+ * @return {Boolean}
+ * @api public
+ */
+
+Document.prototype.__defineGetter__('modified', function () {
+ return this._activePaths.some('modify');
+});
+
+/**
+ * Compiles schemas.
+ * @api private
+ */
+
+function compile (tree, proto, prefix) {
+ var keys = Object.keys(tree)
+ , i = keys.length
+ , limb
+ , key;
+
+ while (i--) {
+ key = keys[i];
+ limb = tree[key];
+
+ define(key
+ , (('Object' === limb.constructor.name
+ && Object.keys(limb).length)
+ && (!limb.type || limb.type.type)
+ ? limb
+ : null)
+ , proto
+ , prefix
+ , keys);
+ }
+};
+
+/**
+ * Defines the accessor named prop on the incoming prototype.
+ * @api private
+ */
+
+function define (prop, subprops, prototype, prefix, keys) {
+ var prefix = prefix || ''
+ , path = (prefix ? prefix + '.' : '') + prop;
+
+ if (subprops) {
+
+ Object.defineProperty(prototype, prop, {
+ enumerable: true
+ , get: function () {
+ if (!this.__getters)
+ this.__getters = {};
+
+ if (!this.__getters[path]) {
+ var nested = Object.create(this);
+
+ // save scope for nested getters/setters
+ if (!prefix) nested._scope = this;
+
+ // shadow inherited getters from sub-objects so
+ // thing.nested.nested.nested... doesn't occur (gh-366)
+ var i = 0
+ , len = keys.length;
+
+ for (; i < len; ++i) {
+ // over-write the parents getter without triggering it
+ Object.defineProperty(nested, keys[i], {
+ enumerable: false // It doesn't show up.
+ , writable: true // We can set it later.
+ , configurable: true // We can Object.defineProperty again.
+ , value: undefined // It shadows its parent.
+ });
+ }
+
+ nested.toObject = function () {
+ return this.get(path);
+ };
+
+ compile(subprops, nested, path);
+ this.__getters[path] = nested;
+ }
+
+ return this.__getters[path];
+ }
+ , set: function (v) {
+ return this.set(v, path);
+ }
+ });
+
+ } else {
+
+ Object.defineProperty(prototype, prop, {
+ enumerable: true
+ , get: function ( ) { return this.get.call(this._scope || this, path); }
+ , set: function (v) { return this.set.call(this._scope || this, path, v); }
+ });
+ }
+};
+
+/**
+ * We override the schema setter to compile accessors
+ *
+ * @api private
+ */
+
+Document.prototype.__defineSetter__('schema', function (schema) {
+ compile(schema.tree, this);
+ this._schema = schema;
+});
+
+/**
+ * We override the schema getter to return the internal reference
+ *
+ * @api private
+ */
+
+Document.prototype.__defineGetter__('schema', function () {
+ return this._schema;
+});
+
+/**
+ * Register default hooks
+ *
+ * @api private
+ */
+
+Document.prototype._registerHooks = function _registerHooks () {
+ if (!this.save) return;
+
+ DocumentArray || (DocumentArray = require('./types/documentarray'));
+
+ this.pre('save', function (next) {
+ // we keep the error semaphore to make sure we don't
+ // call `save` unnecessarily (we only need 1 error)
+ var subdocs = 0
+ , error = false
+ , self = this;
+
+ var arrays = this._activePaths
+ .map('init', 'modify', function (i) {
+ return self.getValue(i);
+ })
+ .filter(function (val) {
+ return (val && val instanceof DocumentArray && val.length);
+ });
+
+ if (!arrays.length)
+ return next();
+
+ arrays.forEach(function (array) {
+ subdocs += array.length;
+ array.forEach(function (value) {
+ if (!error)
+ value.save(function (err) {
+ if (!error) {
+ if (err) {
+ error = true;
+ next(err);
+ } else
+ --subdocs || next();
+ }
+ });
+ });
+ });
+ }, function (err) {
+ this.db.emit('error', err);
+ }).pre('save', function checkForExistingErrors (next) {
+ if (this._saveError) {
+ next(this._saveError);
+ this._saveError = null;
+ } else {
+ next();
+ }
+ }).pre('save', function validation (next) {
+ return this.validate(next);
+ });
+};
+
+/**
+ * Registers an error
+ *
+ * @TODO underscore this method
+ * @param {Error} error
+ * @api private
+ */
+
+Document.prototype.error = function (err) {
+ this._saveError = err;
+ return this;
+};
+
+/**
+ * Executes methods queued from the Schema definition
+ *
+ * @TODO underscore this method
+ * @api private
+ */
+
+Document.prototype.doQueue = function () {
+ if (this.schema && this.schema.callQueue)
+ for (var i = 0, l = this.schema.callQueue.length; i < l; i++) {
+ this[this.schema.callQueue[i][0]].apply(this, this.schema.callQueue[i][1]);
+ }
+ return this;
+};
+
+/**
+ * Gets the document
+ *
+ * Available options:
+ *
+ * - getters: apply all getters (path and virtual getters)
+ * - virtuals: apply virtual getters (can override `getters` option)
+ *
+ * Example of only applying path getters:
+ *
+ * doc.toObject({ getters: true, virtuals: false })
+ *
+ * Example of only applying virtual getters:
+ *
+ * doc.toObject({ virtuals: true })
+ *
+ * Example of applying both path and virtual getters:
+ *
+ * doc.toObject({ getters: true })
+ *
+ * @return {Object} plain object
+ * @api public
+ */
+
+Document.prototype.toObject = function (options) {
+ options || (options = {});
+ options.minimize = true;
+
+ var ret = clone(this._doc, options);
+
+ if (options.virtuals || options.getters && false !== options.virtuals) {
+ applyGetters(this, ret, 'virtuals');
+ }
+
+ if (options.getters) {
+ applyGetters(this, ret, 'paths');
+ }
+
+ return ret;
+};
+
+/**
+ * Applies virtuals properties to `json`.
+ *
+ * @param {Document} self
+ * @param {Object} json
+ * @param {String} either `virtuals` or `paths`
+ * @return json
+ * @private
+ */
+
+function applyGetters (self, json, type) {
+ var schema = self.schema
+ , paths = Object.keys(schema[type])
+ , i = paths.length
+ , path
+
+ while (i--) {
+ path = paths[i];
+
+ var parts = path.split('.')
+ , plen = parts.length
+ , last = plen - 1
+ , branch = json
+ , part
+
+ for (var ii = 0; ii < plen; ++ii) {
+ part = parts[ii];
+ if (ii === last) {
+ branch[part] = self.get(path);
+ } else {
+ branch = branch[part] || (branch[part] = {});
+ }
+ }
+ }
+
+ return json;
+}
+
+/**
+ * JSON.stringify helper.
+ *
+ * Implicitly called when a document is passed
+ * to JSON.stringify()
+ *
+ * @return {Object}
+ * @api public
+ */
+
+Document.prototype.toJSON = function (options) {
+ if ('undefined' === typeof options) options = {};
+ options.json = true;
+ return this.toObject(options);
+};
+
+/**
+ * Helper for console.log
+ *
+ * @api public
+ */
+
+Document.prototype.toString =
+Document.prototype.inspect = function (options) {
+ return inspect(this.toObject(options));
+};
+
+/**
+ * Returns true if the Document stores the same data as doc.
+ * @param {Document} doc to compare to
+ * @return {Boolean}
+ * @api public
+ */
+
+Document.prototype.equals = function (doc) {
+ return this.get('_id') === doc.get('_id');
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = Document;
+
+/**
+ * Document Validation Error
+ */
+
+function ValidationError (instance) {
+ MongooseError.call(this, "Validation failed");
+ Error.captureStackTrace(this, arguments.callee);
+ this.name = 'ValidationError';
+ this.errors = instance.errors = {};
+};
+
+ValidationError.prototype.toString = function () {
+ return this.name + ': ' + Object.keys(this.errors).map(function (key) {
+ return String(this.errors[key]);
+ }, this).join(', ');
+};
+
+/**
+ * Inherits from MongooseError.
+ */
+
+ValidationError.prototype.__proto__ = MongooseError.prototype;
+
+Document.ValidationError = ValidationError;
+
+/**
+ * Document Error
+ *
+ * @param text
+ */
+
+function DocumentError () {
+ MongooseError.call(this, msg);
+ Error.captureStackTrace(this, arguments.callee);
+ this.name = 'DocumentError';
+};
+
+/**
+ * Inherits from MongooseError.
+ */
+
+DocumentError.prototype.__proto__ = MongooseError.prototype;
+
+exports.Error = DocumentError;
diff --git a/node_modules/mongoose/lib/drivers/node-mongodb-native/binary.js b/node_modules/mongoose/lib/drivers/node-mongodb-native/binary.js
new file mode 100644
index 0000000..52e6a03
--- /dev/null
+++ b/node_modules/mongoose/lib/drivers/node-mongodb-native/binary.js
@@ -0,0 +1,8 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Binary = require('mongodb').BSONPure.Binary;
+
+module.exports = exports = Binary;
diff --git a/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js b/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js
new file mode 100644
index 0000000..06176da
--- /dev/null
+++ b/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js
@@ -0,0 +1,176 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Collection = require('../../collection')
+ , NativeCollection = require('mongodb').Collection
+ , utils = require('../../utils')
+
+/**
+ * Native collection
+ *
+ * @api private
+ */
+
+function MongooseCollection () {
+ Collection.apply(this, arguments);
+};
+
+/**
+ * Inherit from abstract Collection.
+ */
+
+MongooseCollection.prototype.__proto__ = Collection.prototype;
+
+/**
+ * Called when the connection opens
+ *
+ * @api private
+ */
+
+MongooseCollection.prototype.onOpen = function () {
+ var self = this;
+ this.conn.db.collection(this.name, function (err, collection) {
+ if (err) {
+ // likely a strict mode error
+ self.conn.emit('error', err);
+ } else {
+ self.collection = collection;
+ Collection.prototype.onOpen.call(self);
+ }
+ });
+};
+
+/**
+ * Called when the connection closes
+ *
+ * @api private
+ */
+
+MongooseCollection.prototype.onClose = function () {
+ Collection.prototype.onClose.call(this);
+};
+
+/**
+ * Copy the collection methods and make them subject to queues
+ */
+
+for (var i in NativeCollection.prototype)
+ (function(i){
+ MongooseCollection.prototype[i] = function () {
+ // BENCHMARKME: is it worth caching the prototype methods? probably
+ if (!this.buffer) {
+ var collection = this.collection
+ , args = arguments
+ , self = this;
+
+ process.nextTick(function(){
+ var debug = self.conn.base.options.debug;
+
+ if (debug) {
+ if ('function' === typeof debug) {
+ debug.apply(debug
+ , [self.name, i].concat(utils.args(args, 0, args.length-1)));
+ } else {
+ console.error('\x1B[0;36mMongoose:\x1B[0m %s.%s(%s) %s %s %s'
+ , self.name
+ , i
+ , print(args[0])
+ , print(args[1])
+ , print(args[2])
+ , print(args[3]))
+ }
+ }
+
+ collection[i].apply(collection, args);
+ });
+ } else {
+ this.addQueue(i, arguments);
+ }
+ };
+ })(i);
+
+/**
+ * Debug print helper
+ * @private
+ */
+
+function print (arg) {
+ var type = typeof arg;
+ if ('function' === type || 'undefined' === type) return '';
+ return format(arg);
+}
+
+/**
+ * Debug print helper
+ * @private
+ */
+
+function format (obj, sub) {
+ var x = utils.clone(obj);
+ if (x) {
+ if ('Binary' === x.constructor.name) {
+ x = '[object Buffer]';
+ } else if ('Object' === x.constructor.name) {
+ var keys = Object.keys(x)
+ , i = keys.length
+ , key
+ while (i--) {
+ key = keys[i];
+ if (x[key]) {
+ if ('Binary' === x[key].constructor.name) {
+ x[key] = '[object Buffer]';
+ } else if ('Object' === x[key].constructor.name) {
+ x[key] = format(x[key], true);
+ } else if (Array.isArray(x[key])) {
+ x[key] = x[key].map(function (o) {
+ return format(o, true)
+ });
+ }
+ }
+ }
+ }
+ if (sub) return x;
+ }
+
+ return require('util')
+ .inspect(x, false, 10, true)
+ .replace(/\n/g, '')
+ .replace(/\s{2,}/g, ' ')
+}
+
+/**
+ * Implement getIndexes
+ *
+ * @param {Function} callback
+ * @api private
+ */
+
+MongooseCollection.prototype.getIndexes =
+MongooseCollection.prototype.indexInformation;
+
+/**
+ * Override signature of ensureIndex. -native one is not standard.
+ *
+ * @param {Object} spec
+ * @param {Object} options
+ * @param {Function} callback
+ * @api public
+ */
+
+var oldEnsureIndex = NativeCollection.prototype.ensureIndex;
+
+function noop () {};
+
+NativeCollection.prototype.ensureIndex = function(fields, options, fn){
+ if (!this.buffer) {
+ return oldEnsureIndex.apply(this, arguments);
+ }
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = MongooseCollection;
diff --git a/node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js b/node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js
new file mode 100644
index 0000000..3becd1b
--- /dev/null
+++ b/node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js
@@ -0,0 +1,106 @@
+/**
+ * Module dependencies.
+ */
+
+var Connection = require('../../connection')
+ , mongo = require('mongodb')
+ , Server = mongo.Server
+ , ReplSetServers = mongo.ReplSetServers;
+
+/**
+ * Connection for mongodb-native driver
+ *
+ * @api private
+ */
+
+function NativeConnection() {
+ Connection.apply(this, arguments);
+};
+
+/**
+ * Inherits from Connection.
+ */
+
+NativeConnection.prototype.__proto__ = Connection.prototype;
+
+/**
+ * Opens the connection.
+ *
+ * Example server options:
+ * auto_reconnect (default: false)
+ * poolSize (default: 1)
+ *
+ * Example db options:
+ * pk - custom primary key factory to generate `_id` values
+ *
+ * Some of these may break Mongoose. Use at your own risk. You have been warned.
+ *
+ * @param {Function} callback
+ * @api private
+ */
+
+NativeConnection.prototype.doOpen = function (fn) {
+ var server;
+
+ if (!this.db) {
+ server = new mongo.Server(this.host, Number(this.port), this.options.server);
+ this.db = new mongo.Db(this.name, server, this.options.db);
+ }
+
+ this.db.open(fn);
+
+ return this;
+};
+
+/**
+ * Opens a set connection
+ *
+ * See description of doOpen for server options. In this case options.replset
+ * is also passed to ReplSetServers. Some additional options there are
+ *
+ * reconnectWait (default: 1000)
+ * retries (default: 30)
+ * rs_name (default: false)
+ * read_secondary (default: false) Are reads allowed from secondaries?
+ *
+ * @param {Function} fn
+ * @api private
+ */
+
+NativeConnection.prototype.doOpenSet = function (fn) {
+ if (!this.db) {
+ var servers = []
+ , ports = this.port
+ , self = this
+
+ this.host.forEach(function (host, i) {
+ servers.push(new mongo.Server(host, Number(ports[i]), self.options.server));
+ });
+
+ var server = new ReplSetServers(servers, this.options.replset);
+ this.db = new mongo.Db(this.name, server, this.options.db);
+ }
+
+ this.db.open(fn);
+
+ return this;
+};
+
+/**
+ * Closes the connection
+ *
+ * @param {Function} callback
+ * @api private
+ */
+
+NativeConnection.prototype.doClose = function (fn) {
+ this.db.close();
+ if (fn) fn();
+ return this;
+}
+
+/**
+ * Module exports.
+ */
+
+module.exports = NativeConnection;
diff --git a/node_modules/mongoose/lib/drivers/node-mongodb-native/objectid.js b/node_modules/mongoose/lib/drivers/node-mongodb-native/objectid.js
new file mode 100644
index 0000000..ee6d598
--- /dev/null
+++ b/node_modules/mongoose/lib/drivers/node-mongodb-native/objectid.js
@@ -0,0 +1,43 @@
+
+/**
+ * Module dependencies.
+ */
+
+var ObjectId = require('mongodb').BSONPure.ObjectID;
+
+/**
+ * Constructor export
+ *
+ * @api private
+ */
+
+var ObjectIdToString = ObjectId.toString.bind(ObjectId);
+
+module.exports = exports = ObjectId;
+/**
+ * Creates an ObjectID for this driver
+ *
+ * @param {Object} hex string or ObjectId
+ * @api private
+ */
+
+exports.fromString = function(str){
+ // patch native driver bug in V0.9.6.4
+ if (!('string' === typeof str && 24 === str.length)) {
+ throw new Error("Invalid ObjectId");
+ }
+
+ return ObjectId.createFromHexString(str);
+};
+
+/**
+ * Gets an ObjectId and converts it to string.
+ *
+ * @param {ObjectId} -native objectid
+ * @api private
+ */
+
+exports.toString = function(oid){
+ if (!arguments.length) return ObjectIdToString();
+ return oid.toHexString();
+};
diff --git a/node_modules/mongoose/lib/error.js b/node_modules/mongoose/lib/error.js
new file mode 100644
index 0000000..bd4ee61
--- /dev/null
+++ b/node_modules/mongoose/lib/error.js
@@ -0,0 +1,25 @@
+
+/**
+ * Mongoose error
+ *
+ * @api private
+ */
+
+function MongooseError (msg) {
+ Error.call(this);
+ Error.captureStackTrace(this, arguments.callee);
+ this.message = msg;
+ this.name = 'MongooseError';
+};
+
+/**
+ * Inherits from Error.
+ */
+
+MongooseError.prototype.__proto__ = Error.prototype;
+
+/**
+ * Module exports.
+ */
+
+module.exports = MongooseError;
diff --git a/node_modules/mongoose/lib/index.js b/node_modules/mongoose/lib/index.js
new file mode 100644
index 0000000..6fd449e
--- /dev/null
+++ b/node_modules/mongoose/lib/index.js
@@ -0,0 +1,368 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Schema = require('./schema')
+ , SchemaType = require('./schematype')
+ , VirtualType = require('./virtualtype')
+ , SchemaTypes = Schema.Types
+ , SchemaDefaults = require('./schemadefault')
+ , Types = require('./types')
+ , Query = require('./query')
+ , Promise = require('./promise')
+ , Model = require('./model')
+ , Document = require('./document')
+ , utils = require('./utils');
+
+/**
+ * Mongoose constructor. Most apps will only use one instance.
+ *
+ * @api public
+ */
+
+function Mongoose () {
+ this.connections = [];
+ this.plugins = [];
+ this.models = {};
+ this.modelSchemas = {};
+ this.options = {};
+ this.createConnection(); // default connection
+};
+
+/**
+ * Sets/gets mongoose options
+ *
+ * Examples:
+ * mongoose.set('test') // returns the 'test' value
+ * mongoose.set('test', value) // sets the 'test' value
+ *
+ * @param {String} key
+ * @param {String} value
+ * @api public
+ */
+
+Mongoose.prototype.set =
+Mongoose.prototype.get = function (key, value) {
+ if (arguments.length == 1)
+ return this.options[key];
+ this.options[key] = value;
+ return this;
+};
+
+/**
+ * Creates a Connection instance.
+ *
+ * Examples:
+ *
+ * // with mongodb:// URI
+ * db = mongoose.createConnection('mongodb://localhost:port/database');
+ *
+ * // with [host, database_name[, port] signature
+ * db = mongoose.createConnection('localhost', 'database', port)
+ *
+ * // initialize now, connect later
+ * db = mongoose.createConnection();
+ * db.open('localhost', 'database', port);
+ *
+ * @param {String} mongodb:// URI
+ * @return {Connection} the created Connection object
+ * @api public
+ */
+
+Mongoose.prototype.createConnection = function () {
+ var conn = new Connection(this);
+ this.connections.push(conn);
+ if (arguments.length)
+ conn.open.apply(conn, arguments);
+ return conn;
+};
+
+/**
+ * Creates a replica set connection
+ *
+ * @see {Mongoose#createConnection}
+ * @api public
+ */
+
+Mongoose.prototype.createSetConnection = function () {
+ var conn = new Connection(this);
+ this.connections.push(conn);
+ if (arguments.length)
+ conn.openSet.apply(conn, arguments);
+ return conn;
+};
+
+/**
+ * Connects the default mongoose connection
+ *
+ * @see {Mongoose#createConnection}
+ * @api public
+ */
+
+Mongoose.prototype.connect = function (){
+ this.connection.open.apply(this.connection, arguments);
+ return this;
+};
+
+/**
+ * Connects the default mongoose connection to a replica set
+ *
+ * @see {Mongoose#createConnection}
+ * @api public
+ */
+
+Mongoose.prototype.connectSet = function (){
+ this.connection.openSet.apply(this.connection, arguments);
+ return this;
+};
+
+/**
+ * Disconnects from all connections.
+ *
+ * @param {Function} optional callback
+ * @api public
+ */
+
+Mongoose.prototype.disconnect = function (fn) {
+ var count = this.connections.length;
+ this.connections.forEach(function(conn){
+ conn.close(function(err){
+ if (err) return fn(err);
+ if (fn)
+ --count || fn();
+ });
+ });
+ return this;
+};
+
+/**
+ * Defines a model or retrieves it
+ *
+ * @param {String} model name
+ * @param {Schema} schema object
+ * @param {String} collection name (optional, induced from model name)
+ * @param {Boolean} whether to skip initialization (defaults to false)
+ * @api public
+ */
+
+Mongoose.prototype.model = function (name, schema, collection, skipInit) {
+ // normalize collection
+ if (!(schema instanceof Schema)) {
+ collection = schema;
+ schema = false;
+ }
+
+ if ('boolean' === typeof collection) {
+ skipInit = collection;
+ collection = null;
+ }
+
+ // look up models for the collection
+ if (!this.modelSchemas[name]) {
+ if (!schema && name in SchemaDefaults) {
+ schema = SchemaDefaults[name];
+ }
+
+ if (schema) {
+ this.modelSchemas[name] = schema;
+ for (var i = 0, l = this.plugins.length; i < l; i++) {
+ schema.plugin(this.plugins[i][0], this.plugins[i][1]);
+ }
+ } else {
+ throw new Error('Schema hasn\'t been registered for model "' + name + '".\n'
+ + 'Use mongoose.model(name, schema)');
+ }
+ }
+
+ if (!schema) {
+ schema = this.modelSchemas[name];
+ }
+
+ if (!collection) {
+ collection = schema.set('collection') || utils.toCollectionName(name);
+ }
+
+ if (!this.models[name]) {
+ var model = Model.compile(name
+ , this.modelSchemas[name]
+ , collection
+ , this.connection
+ , this);
+
+ if (!skipInit) model.init();
+
+ this.models[name] = model;
+ }
+
+ return this.models[name];
+};
+
+/**
+ * Declares a plugin executed on Schemas. Equivalent to calling `.plugin(fn)`
+ * on each Schema you create.
+ *
+ * @param {Function} plugin callback
+ * @api public
+ */
+
+Mongoose.prototype.plugin = function (fn, opts) {
+ this.plugins.push([fn, opts]);
+ return this;
+};
+
+/**
+ * Default connection
+ *
+ * @api public
+ */
+
+Mongoose.prototype.__defineGetter__('connection', function(){
+ return this.connections[0];
+});
+
+/**
+ * Driver depentend APIs
+ */
+
+var driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native';
+
+/**
+ * Connection
+ *
+ * @api public
+ */
+
+var Connection = require(driver + '/connection');
+
+/**
+ * Collection
+ *
+ * @api public
+ */
+
+var Collection = require(driver + '/collection');
+
+/**
+ * Export default singleton.
+ *
+ * @api public
+ */
+
+module.exports = exports = new Mongoose();
+
+/**
+ * Collection
+ *
+ * @api public
+ */
+
+exports.Collection = Collection;
+
+/**
+ * Connection
+ *
+ * @api public
+ */
+
+exports.Connection = Connection;
+
+/**
+ * Exports Mongoose version
+ *
+ * @param version
+ */
+
+exports.version = JSON.parse(
+ require('fs').readFileSync(__dirname + '/../package.json', 'utf8')
+).version;
+
+/**
+ * Export Mongoose constructor
+ *
+ * @api public
+ */
+
+exports.Mongoose = Mongoose;
+
+/**
+ * Export Schema constructor
+ *
+ * @api public
+ */
+
+exports.Schema = Schema;
+
+/**
+ * Export SchemaType constructor.
+ *
+ * @api public
+ */
+
+exports.SchemaType = SchemaType;
+
+/**
+ * Export VirtualType constructor.
+ *
+ * @api public
+ */
+
+exports.VirtualType = VirtualType;
+
+/**
+ * Export Schema types
+ *
+ * @api public
+ */
+
+exports.SchemaTypes = SchemaTypes;
+
+/**
+ * Export types
+ *
+ * @api public
+ */
+
+exports.Types = Types;
+
+/**
+ * Export Query
+ *
+ * @api public
+ */
+
+exports.Query = Query;
+
+/**
+ * Export Promise
+ *
+ * @api public
+ */
+
+exports.Promise = Promise;
+
+/**
+ * Export Model constructor
+ *
+ * @api public
+ */
+
+exports.Model = Model;
+
+/**
+ * Export Document constructor
+ *
+ * @api public
+ */
+
+exports.Document = Document;
+
+/**
+ * Export MongooseError
+ *
+ * @api public
+ */
+
+exports.Error = require('./error');
+
+exports.mongo = require('mongodb');
diff --git a/node_modules/mongoose/lib/model.js b/node_modules/mongoose/lib/model.js
new file mode 100644
index 0000000..75bfda3
--- /dev/null
+++ b/node_modules/mongoose/lib/model.js
@@ -0,0 +1,917 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Document = require('./document')
+ , MongooseArray = require('./types/array')
+ , MongooseBuffer = require('./types/buffer')
+ , MongooseError = require('./error')
+ , Query = require('./query')
+ , utils = require('./utils')
+ , isMongooseObject = utils.isMongooseObject
+ , EventEmitter = utils.EventEmitter
+ , merge = utils.merge
+ , Promise = require('./promise')
+ , tick = utils.tick
+
+/**
+ * Model constructor
+ *
+ * @param {Object} values to set
+ * @api public
+ */
+
+function Model (doc, fields) {
+ Document.call(this, doc, fields);
+};
+
+/**
+ * Inherits from Document.
+ */
+
+Model.prototype.__proto__ = Document.prototype;
+
+/**
+ * Connection the model uses. Set by the Connection or if absent set to the
+ * default mongoose connection;
+ *
+ * @api public
+ */
+
+Model.prototype.db;
+
+/**
+ * Collection the model uses. Set by Mongoose instance
+ *
+ * @api public
+ */
+
+Model.prototype.collection;
+
+/**
+ * Model name.
+ *
+ * @api public
+ */
+
+Model.prototype.modelName;
+
+/**
+ * Returns what paths can be populated
+ *
+ * @param {query} query object
+ * @return {Object] population paths
+ * @api private
+ */
+
+Model.prototype._getPopulationKeys = function getPopulationKeys (query) {
+ if (!(query && query.options.populate)) return;
+
+ var names = Object.keys(query.options.populate)
+ , n = names.length
+ , name
+ , paths = {}
+ , hasKeys
+ , schema
+
+ while (n--) {
+ name = names[n];
+ schema = this.schema.path(name);
+ hasKeys = true;
+
+ if (!schema) {
+ // if the path is not recognized, it's potentially embedded docs
+ // walk path atoms from right to left to find a matching path
+ var pieces = name.split('.')
+ , i = pieces.length;
+
+ while (i--) {
+ var path = pieces.slice(0, i).join('.')
+ , pathSchema = this.schema.path(path);
+
+ // loop until we find an array schema
+ if (pathSchema && pathSchema.caster) {
+ if (!paths[path]) {
+ paths[path] = { sub: {} };
+ }
+
+ paths[path].sub[pieces.slice(i).join('.')] = query.options.populate[name];
+ hasKeys || (hasKeys = true);
+ break;
+ }
+ }
+ } else {
+ paths[name] = query.options.populate[name];
+ hasKeys || (hasKeys = true);
+ }
+ }
+
+ return hasKeys && paths;
+};
+
+/**
+ * Populates an object
+ *
+ * @param {SchemaType} schema type for the oid
+ * @param {Object} object id or array of object ids
+ * @param {Object} object specifying query conditions, fields, and options
+ * @param {Function} callback
+ * @api private
+ */
+
+Model.prototype._populate = function populate (schema, oid, query, fn) {
+ if (!Array.isArray(oid)) {
+ var conditions = query.conditions || {};
+ conditions._id = oid;
+
+ return this
+ .model(schema.options.ref)
+ .findOne(conditions, query.fields, query.options, fn);
+ }
+
+ if (!oid.length) {
+ return fn(null, oid);
+ }
+
+ var model = this.model(schema.caster.options.ref)
+ , conditions = query && query.conditions || {};
+ conditions._id || (conditions._id = { $in: oid });
+
+ model.find(conditions, query.fields, query.options, function (err, docs) {
+ if (err) return fn(err);
+
+ // user specified sort order?
+ if (query.options && query.options.sort) {
+ return fn(null, docs);
+ }
+
+ // put back in original id order (using a hash reduces complexity from n*n to 2n)
+ var docHash = {};
+ docs.forEach(function (doc) {
+ docHash[doc._id] = doc;
+ });
+
+ var arr = [];
+ oid.forEach(function (id) {
+ if (id in docHash) arr.push(docHash[id]);
+ });
+
+ fn(null, arr);
+ });
+};
+
+/**
+ * Performs auto-population of relations.
+ *
+ * @param {Object} document returned by mongo
+ * @param {Query} query that originated the initialization
+ * @param {Function} callback
+ * @api private
+ */
+
+Model.prototype.init = function init (doc, query, fn) {
+ if ('function' == typeof query) {
+ fn = query;
+ query = null;
+ }
+
+ var populate = this._getPopulationKeys(query);
+
+ if (!populate) {
+ return Document.prototype.init.call(this, doc, fn);
+ }
+
+ // population from other models is necessary
+ var self = this;
+
+ init(doc, '', function (err) {
+ if (err) return fn(err);
+ Document.prototype.init.call(self, doc, fn);
+ });
+
+ return this;
+
+ function init (obj, prefix, fn) {
+ prefix = prefix || '';
+
+ var keys = Object.keys(obj)
+ , len = keys.length;
+
+ function next () {
+ if (--len < 0) return fn();
+
+ var i = keys[len]
+ , path = prefix + i
+ , schema = self.schema.path(path)
+ , total = 0
+ , poppath
+
+ if (!schema && obj[i] && 'Object' === obj[i].constructor.name) {
+ // assume nested object
+ return init(obj[i], path + '.', next);
+ }
+
+ if (!(obj[i] && schema && populate[path])) return next();
+
+ // this query object is re-used and passed around. we clone
+ // it to prevent query condition contamination between
+ // one populate call to the next.
+ poppath = utils.clone(populate[path]);
+
+ if (poppath.sub) {
+ obj[i].forEach(function (subobj) {
+ var pkeys = Object.keys(poppath.sub)
+ , pi = pkeys.length
+ , key
+
+ while (pi--) {
+ key = pkeys[pi];
+
+ if (subobj[key]) (function (key) {
+
+ total++;
+ self._populate(schema.schema.path(key), subobj[key], poppath.sub[key], done);
+ function done (err, doc) {
+ if (err) return error(err);
+ subobj[key] = doc;
+ --total || next();
+ }
+ })(key);
+ }
+ });
+
+ if (0 === total) return next();
+
+ } else {
+ self._populate(schema, obj[i], poppath, function (err, doc) {
+ if (err) return error(err);
+ obj[i] = doc;
+ next();
+ });
+ }
+ };
+
+ next();
+ };
+
+ function error (err) {
+ if (error.err) return;
+ fn(error.err = err);
+ }
+};
+
+function handleSave (promise, self) {
+ return tick(function handleSave (err, result) {
+ if (err) return promise.error(err);
+
+ self._storeShard();
+
+ var numAffected;
+ if (result) {
+ numAffected = result.length
+ ? result.length
+ : result;
+ } else {
+ numAffected = 0;
+ }
+
+ self.emit('save', self, numAffected);
+ promise.complete(self, numAffected);
+ promise = null;
+ self = null;
+ });
+}
+
+/**
+ * Saves this document.
+ *
+ * @see Model#registerHooks
+ * @param {Function} fn
+ * @api public
+ */
+
+Model.prototype.save = function save (fn) {
+ var promise = new Promise(fn)
+ , complete = handleSave(promise, this)
+ , options = {}
+
+ if (this.options.safe) {
+ options.safe = this.options.safe;
+ }
+
+ if (this.isNew) {
+ // send entire doc
+ this.collection.insert(this.toObject({ depopulate: 1 }), options, complete);
+ this._reset();
+ this.isNew = false;
+ this.emit('isNew', false);
+
+ } else {
+ var delta = this._delta();
+ this._reset();
+
+ if (delta) {
+ var where = this._where();
+ this.collection.update(where, delta, options, complete);
+ } else {
+ complete(null);
+ }
+
+ this.emit('isNew', false);
+ }
+};
+
+/**
+ * Produces a special query document of the modified properties.
+ * @api private
+ */
+
+Model.prototype._delta = function _delta () {
+ var dirty = this._dirty();
+
+ if (!dirty.length) return;
+
+ var self = this
+ , useSet = this.options['use$SetOnSave'];
+
+ return dirty.reduce(function (delta, data) {
+ var type = data.value
+ , schema = data.schema
+ , atomics
+ , val
+ , obj
+
+ if (type === undefined) {
+ if (!delta.$unset) delta.$unset = {};
+ delta.$unset[data.path] = 1;
+
+ } else if (type === null) {
+ if (!delta.$set) delta.$set = {};
+ delta.$set[data.path] = type;
+
+ } else if (type._path && type.doAtomics) {
+ // a MongooseArray or MongooseNumber
+ atomics = type._atomics;
+
+ var ops = Object.keys(atomics)
+ , i = ops.length
+ , op;
+
+ while (i--) {
+ op = ops[i]
+
+ if (op === '$pushAll' || op === '$pullAll') {
+ if (atomics[op].length === 1) {
+ val = atomics[op][0];
+ delete atomics[op];
+ op = op.replace('All', '');
+ atomics[op] = val;
+ }
+ }
+
+ val = atomics[op];
+ obj = delta[op] = delta[op] || {};
+
+ if (op === '$pull' || op === '$push') {
+ if ('Object' !== val.constructor.name) {
+ if (Array.isArray(val)) val = [val];
+ // TODO Should we place pull and push casting into the pull and push methods?
+ val = schema.cast(val)[0];
+ }
+ }
+
+ obj[data.path] = isMongooseObject(val)
+ ? val.toObject({ depopulate: 1 }) // MongooseArray
+ : Array.isArray(val)
+ ? val.map(function (mem) {
+ return isMongooseObject(mem)
+ ? mem.toObject({ depopulate: 1 })
+ : mem.valueOf
+ ? mem.valueOf()
+ : mem;
+ })
+ : val.valueOf
+ ? val.valueOf() // Numbers
+ : val;
+
+ if ('$addToSet' === op) {
+ if (val.length > 1) {
+ obj[data.path] = { $each: obj[data.path] };
+ } else {
+ obj[data.path] = obj[data.path][0];
+ }
+ }
+ }
+ } else {
+ if (type instanceof MongooseArray ||
+ type instanceof MongooseBuffer) {
+ type = type.toObject({ depopulate: 1 });
+ } else if (type._path) {
+ type = type.valueOf();
+ } else {
+ // nested object literal
+ type = utils.clone(type);
+ }
+
+ if (useSet) {
+ if (!('$set' in delta))
+ delta['$set'] = {};
+
+ delta['$set'][data.path] = type;
+ } else
+ delta[data.path] = type;
+ }
+
+ return delta;
+ }, {});
+}
+
+/**
+ * _where
+ *
+ * Returns a query object which applies shardkeys if
+ * they exist.
+ *
+ * @private
+ */
+
+Model.prototype._where = function _where () {
+ var where = {};
+
+ if (this._shardval) {
+ var paths = Object.keys(this._shardval)
+ , len = paths.length
+
+ for (var i = 0; i < len; ++i) {
+ where[paths[i]] = this._shardval[paths[i]];
+ }
+ }
+
+ var id = this._doc._id.valueOf // MongooseNumber
+ ? this._doc._id.valueOf()
+ : this._doc._id;
+
+ where._id = id;
+ return where;
+}
+
+/**
+ * Remove the document
+ *
+ * @param {Function} callback
+ * @api public
+ */
+
+Model.prototype.remove = function remove (fn) {
+ if (this._removing) return this;
+
+ var promise = this._removing = new Promise(fn)
+ , where = this._where()
+ , self = this;
+
+ this.collection.remove(where, tick(function (err) {
+ if (err) {
+ this._removing = null;
+ return promise.error(err);
+ }
+ promise.complete();
+ self.emit('remove', self);
+ }));
+
+ return this;
+};
+
+/**
+ * Register hooks override
+ *
+ * @api private
+ */
+
+Model.prototype._registerHooks = function registerHooks () {
+ Document.prototype._registerHooks.call(this);
+};
+
+/**
+ * Shortcut to access another model.
+ *
+ * @param {String} model name
+ * @api public
+ */
+
+Model.prototype.model = function model (name) {
+ return this.db.model(name);
+};
+
+/**
+ * Access the options defined in the schema
+ *
+ * @api private
+ */
+
+Model.prototype.__defineGetter__('options', function () {
+ return this.schema ? this.schema.options : {};
+});
+
+/**
+ * Give the constructor the ability to emit events.
+ */
+
+for (var i in EventEmitter.prototype)
+ Model[i] = EventEmitter.prototype[i];
+
+/**
+ * Called when the model compiles
+ *
+ * @api private
+ */
+
+Model.init = function init () {
+ // build indexes
+ var self = this
+ , indexes = this.schema.indexes
+ , safe = this.schema.options.safe
+ , count = indexes.length;
+
+ indexes.forEach(function (index) {
+ var options = index[1];
+ options.safe = safe;
+ self.collection.ensureIndex(index[0], options, tick(function (err) {
+ if (err) return self.db.emit('error', err);
+ --count || self.emit('index');
+ }));
+ });
+
+ this.schema.emit('init', this);
+};
+
+/**
+ * Document schema
+ *
+ * @api public
+ */
+
+Model.schema;
+
+/**
+ * Database instance the model uses.
+ *
+ * @api public
+ */
+
+Model.db;
+
+/**
+ * Collection the model uses.
+ *
+ * @api public
+ */
+
+Model.collection;
+
+/**
+ * Define properties that access the prototype.
+ */
+
+['db', 'collection', 'schema', 'options', 'model'].forEach(function(prop){
+ Model.__defineGetter__(prop, function(){
+ return this.prototype[prop];
+ });
+});
+
+/**
+ * Module exports.
+ */
+
+module.exports = exports = Model;
+
+Model.remove = function remove (conditions, callback) {
+ if ('function' === typeof conditions) {
+ callback = conditions;
+ conditions = {};
+ }
+
+ var query = new Query(conditions).bind(this, 'remove');
+
+ if ('undefined' === typeof callback)
+ return query;
+
+ this._applyNamedScope(query);
+ return query.remove(callback);
+};
+
+/**
+ * Finds documents
+ *
+ * Examples:
+ * // retrieve only certain keys
+ * MyModel.find({ name: /john/i }, ['name', 'friends'], function () { })
+ *
+ * // pass options
+ * MyModel.find({ name: /john/i }, [], { skip: 10 } )
+ *
+ * @param {Object} conditions
+ * @param {Object/Function} (optional) fields to hydrate or callback
+ * @param {Function} callback
+ * @api public
+ */
+
+Model.find = function find (conditions, fields, options, callback) {
+ if ('function' == typeof conditions) {
+ callback = conditions;
+ conditions = {};
+ fields = null;
+ options = null;
+ } else if ('function' == typeof fields) {
+ callback = fields;
+ fields = null;
+ options = null;
+ } else if ('function' == typeof options) {
+ callback = options;
+ options = null;
+ }
+
+ var query = new Query(conditions, options);
+ query.bind(this, 'find');
+ query.select(fields);
+
+ if ('undefined' === typeof callback)
+ return query;
+
+ this._applyNamedScope(query);
+ return query.find(callback);
+};
+
+/**
+ * Merges the current named scope query into `query`.
+ *
+ * @param {Query} query
+ * @api private
+ */
+
+Model._applyNamedScope = function _applyNamedScope (query) {
+ var cQuery = this._cumulativeQuery;
+
+ if (cQuery) {
+ merge(query._conditions, cQuery._conditions);
+ if (query._fields && cQuery._fields)
+ merge(query._fields, cQuery._fields);
+ if (query.options && cQuery.options)
+ merge(query.options, cQuery.options);
+ delete this._cumulativeQuery;
+ }
+
+ return query;
+}
+
+/**
+ * Finds by id
+ *
+ * @param {ObjectId/Object} objectid, or a value that can be casted to it
+ * @api public
+ */
+
+Model.findById = function findById (id, fields, options, callback) {
+ return this.findOne({ _id: id }, fields, options, callback);
+};
+
+/**
+ * Finds one document
+ *
+ * @param {Object} conditions
+ * @param {Object/Function} (optional) fields to hydrate or callback
+ * @param {Function} callback
+ * @api public
+ */
+
+Model.findOne = function findOne (conditions, fields, options, callback) {
+ if ('function' == typeof options) {
+ // TODO Handle all 3 of the following scenarios
+ // Hint: Only some of these scenarios are possible if cQuery is present
+ // Scenario: findOne(conditions, fields, callback);
+ // Scenario: findOne(fields, options, callback);
+ // Scenario: findOne(conditions, options, callback);
+ callback = options;
+ options = null;
+ } else if ('function' == typeof fields) {
+ // TODO Handle all 2 of the following scenarios
+ // Scenario: findOne(conditions, callback)
+ // Scenario: findOne(fields, callback)
+ // Scenario: findOne(options, callback);
+ callback = fields;
+ fields = null;
+ options = null;
+ } else if ('function' == typeof conditions) {
+ callback = conditions;
+ conditions = {};
+ fields = null;
+ options = null;
+ }
+
+ var query = new Query(conditions, options).select(fields).bind(this, 'findOne');
+
+ if ('undefined' == typeof callback)
+ return query;
+
+ this._applyNamedScope(query);
+ return query.findOne(callback);
+};
+
+/**
+ * Counts documents
+ *
+ * @param {Object} conditions
+ * @param {Function} optional callback
+ * @api public
+ */
+
+Model.count = function count (conditions, callback) {
+ if ('function' === typeof conditions)
+ callback = conditions, conditions = {};
+
+ var query = new Query(conditions).bind(this, 'count');
+ if ('undefined' == typeof callback)
+ return query;
+
+ this._applyNamedScope(query);
+ return query.count(callback);
+};
+
+Model.distinct = function distinct (field, conditions, callback) {
+ var query = new Query(conditions).bind(this, 'distinct');
+ if ('undefined' == typeof callback) {
+ query._distinctArg = field;
+ return query;
+ }
+
+ this._applyNamedScope(query);
+ return query.distinct(field, callback);
+};
+
+/**
+ * `where` enables a very nice sugary api for doing your queries.
+ * For example, instead of writing:
+ * User.find({age: {$gte: 21, $lte: 65}}, callback);
+ * we can instead write more readably:
+ * User.where('age').gte(21).lte(65);
+ * Moreover, you can also chain a bunch of these together like:
+ * User
+ * .where('age').gte(21).lte(65)
+ * .where('name', /^b/i) // All names that begin where b or B
+ * .where('friends').slice(10);
+ * @param {String} path
+ * @param {Object} val (optional)
+ * @return {Query}
+ * @api public
+ */
+
+Model.where = function where (path, val) {
+ var q = new Query().bind(this, 'find');
+ return q.where.apply(q, arguments);
+};
+
+/**
+ * Sometimes you need to query for things in mongodb using a JavaScript
+ * expression. You can do so via find({$where: javascript}), or you can
+ * use the mongoose shortcut method $where via a Query chain or from
+ * your mongoose Model.
+ *
+ * @param {String|Function} js is a javascript string or anonymous function
+ * @return {Query}
+ * @api public
+ */
+
+Model.$where = function $where () {
+ var q = new Query().bind(this, 'find');
+ return q.$where.apply(q, arguments);
+};
+
+/**
+ * Shortcut for creating a new Document that is automatically saved
+ * to the db if valid.
+ *
+ * @param {Object} doc
+ * @param {Function} callback
+ * @api public
+ */
+
+Model.create = function create (doc, fn) {
+ if (1 === arguments.length) {
+ return 'function' === typeof doc && doc(null);
+ }
+
+ var self = this
+ , docs = [null]
+ , promise
+ , count
+ , args
+
+ if (Array.isArray(doc)) {
+ args = doc;
+ } else {
+ args = utils.args(arguments, 0, arguments.length - 1);
+ fn = arguments[arguments.length - 1];
+ }
+
+ if (0 === args.length) return fn(null);
+
+ promise = new Promise(fn);
+ count = args.length;
+
+ args.forEach(function (arg, i) {
+ var doc = new self(arg);
+ docs[i+1] = doc;
+ doc.save(function (err) {
+ if (err) return promise.error(err);
+ --count || fn.apply(null, docs);
+ });
+ });
+
+ // TODO
+ // utilize collection.insertAll for batch processing?
+};
+
+/**
+ * Updates documents.
+ *
+ * Examples:
+ *
+ * MyModel.update({ age: { $gt: 18 } }, { oldEnough: true }, fn);
+ * MyModel.update({ name: 'Tobi' }, { ferret: true }, { multi: true }, fn);
+ *
+ * Valid options:
+ *
+ * - safe (boolean) safe mode (defaults to value set in schema (true))
+ * - upsert (boolean) whether to create the doc if it doesn't match (false)
+ * - multi (boolean) whether multiple documents should be updated (false)
+ *
+ * @param {Object} conditions
+ * @param {Object} doc
+ * @param {Object} options
+ * @param {Function} callback
+ * @return {Query}
+ * @api public
+ */
+
+Model.update = function update (conditions, doc, options, callback) {
+ if (arguments.length < 4) {
+ if ('function' === typeof options) {
+ // Scenario: update(conditions, doc, callback)
+ callback = options;
+ options = null;
+ } else if ('function' === typeof doc) {
+ // Scenario: update(doc, callback);
+ callback = doc;
+ doc = conditions;
+ conditions = {};
+ options = null;
+ }
+ }
+
+ var query = new Query(conditions, options).bind(this, 'update', doc);
+
+ if ('undefined' == typeof callback)
+ return query;
+
+ this._applyNamedScope(query);
+ return query.update(doc, callback);
+};
+
+/**
+ * Compiler utility.
+ *
+ * @param {String} model name
+ * @param {Schema} schema object
+ * @param {String} collection name
+ * @param {Connection} connection to use
+ * @param {Mongoose} mongoose instance
+ * @api private
+ */
+
+Model.compile = function compile (name, schema, collectionName, connection, base) {
+ // generate new class
+ function model () {
+ Model.apply(this, arguments);
+ };
+
+ model.modelName = name;
+ model.__proto__ = Model;
+ model.prototype.__proto__ = Model.prototype;
+ model.prototype.base = base;
+ model.prototype.schema = schema;
+ model.prototype.db = connection;
+ model.prototype.collection = connection.collection(collectionName);
+
+ // apply methods
+ for (var i in schema.methods)
+ model.prototype[i] = schema.methods[i];
+
+ // apply statics
+ for (var i in schema.statics)
+ model[i] = schema.statics[i];
+
+ // apply named scopes
+ if (schema.namedScopes) schema.namedScopes.compile(model);
+
+ return model;
+};
diff --git a/node_modules/mongoose/lib/namedscope.js b/node_modules/mongoose/lib/namedscope.js
new file mode 100644
index 0000000..1b3f5d4
--- /dev/null
+++ b/node_modules/mongoose/lib/namedscope.js
@@ -0,0 +1,70 @@
+var Query = require('./query');
+function NamedScope () {}
+
+NamedScope.prototype.query;
+
+NamedScope.prototype.where = function () {
+ var q = this.query || (this.query = new Query());
+ q.where.apply(q, arguments);
+ return q;
+};
+
+/**
+ * Decorate
+ *
+ * @param {NamedScope} target
+ * @param {Object} getters
+ * @api private
+ */
+
+NamedScope.prototype.decorate = function (target, getters) {
+ var name = this.name
+ , block = this.block
+ , query = this.query;
+ if (block) {
+ if (block.length === 0) {
+ Object.defineProperty(target, name, {
+ get: getters.block0(block)
+ });
+ } else {
+ target[name] = getters.blockN(block);
+ }
+ } else {
+ Object.defineProperty(target, name, {
+ get: getters.basic(query)
+ });
+ }
+};
+
+NamedScope.prototype.compile = function (model) {
+ var allScopes = this.scopesByName
+ , scope;
+ for (var k in allScopes) {
+ scope = allScopes[k];
+ scope.decorate(model, {
+ block0: function (block) {
+ return function () {
+ var cquery = this._cumulativeQuery || (this._cumulativeQuery = new Query().bind(this));
+ block.call(cquery);
+ return this;
+ };
+ },
+ blockN: function (block) {
+ return function () {
+ var cquery = this._cumulativeQuery || (this._cumulativeQuery = new Query().bind(this));
+ block.apply(cquery, arguments);
+ return this;
+ };
+ },
+ basic: function (query) {
+ return function () {
+ var cquery = this._cumulativeQuery || (this._cumulativeQuery = new Query().bind(this));
+ cquery.find(query);
+ return this;
+ };
+ }
+ });
+ }
+};
+
+module.exports = NamedScope;
diff --git a/node_modules/mongoose/lib/promise.js b/node_modules/mongoose/lib/promise.js
new file mode 100644
index 0000000..c632a03
--- /dev/null
+++ b/node_modules/mongoose/lib/promise.js
@@ -0,0 +1,145 @@
+
+/**
+ * Module dependencies.
+ */
+
+var util = require('./utils');
+var EventEmitter = util.EventEmitter;
+
+/**
+ * Promise constructor.
+ *
+ * @param {Function} a callback+errback that takes err, ... as signature
+ * @api public
+ */
+
+function Promise (back) {
+ this.emitted = {};
+ if ('function' == typeof back)
+ this.addBack(back);
+};
+
+/**
+ * Inherits from EventEmitter.
+ */
+
+Promise.prototype.__proto__ = EventEmitter.prototype;
+
+/**
+ * Adds an event or fires the callback right away.
+ *
+ * @return promise
+ * @api public
+ */
+
+Promise.prototype.on = function (event, callback) {
+ if (this.emitted[event])
+ callback.apply(this, this.emitted[event]);
+ else
+ EventEmitter.prototype.on.call(this, event, callback);
+
+ return this;
+};
+
+/**
+ * Keeps track of emitted events to run them on `on`
+ *
+ * @api private
+ */
+
+Promise.prototype.emit = function (event) {
+ // ensures a promise can't be complete() or error() twice
+ if (event == 'err' || event == 'complete'){
+ if (this.emitted.err || this.emitted.complete) {
+ return this;
+ }
+ this.emitted[event] = util.args(arguments, 1);
+ }
+
+ return EventEmitter.prototype.emit.apply(this, arguments);
+};
+
+/**
+ * Shortcut for emitting complete event
+ *
+ * @api public
+ */
+
+Promise.prototype.complete = function () {
+ var args = util.args(arguments);
+ return this.emit.apply(this, ['complete'].concat(args));
+};
+
+/**
+ * Shortcut for emitting err event
+ *
+ * @api public
+ */
+
+Promise.prototype.error = function () {
+ var args = util.args(arguments);
+ return this.emit.apply(this, ['err'].concat(args));
+};
+
+/**
+ * Shortcut for `.on('complete', fn)`
+ *
+ * @return promise
+ * @api public
+ */
+
+Promise.prototype.addCallback = function (fn) {
+ return this.on('complete', fn);
+};
+
+/**
+ * Shortcut for `.on('err', fn)`
+ *
+ * @return promise
+ * @api public
+ */
+
+Promise.prototype.addErrback = function (fn) {
+ return this.on('err', fn);
+};
+
+/**
+ * Adds a single function that's both callback and errback
+ *
+ * @return promise
+ * @api private
+ */
+
+Promise.prototype.addBack = function (fn) {
+ this.on('err', function(err){
+ fn.call(this, err);
+ });
+
+ this.on('complete', function(){
+ var args = util.args(arguments);
+ fn.apply(this, [null].concat(args));
+ });
+
+ return this;
+};
+
+/**
+ * Sugar for handling cases where you may be
+ * resolving to either an error condition or a
+ * success condition.
+ *
+ * @param {Error} optional error or null
+ * @param {Object} value to complete the promise with
+ * @api public
+ */
+
+Promise.prototype.resolve = function (err, val) {
+ if (err) return this.error(err);
+ return this.complete(val);
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = Promise;
diff --git a/node_modules/mongoose/lib/query.js b/node_modules/mongoose/lib/query.js
new file mode 100644
index 0000000..29c03ab
--- /dev/null
+++ b/node_modules/mongoose/lib/query.js
@@ -0,0 +1,1527 @@
+/**
+ * Module dependencies.
+ */
+
+var utils = require('./utils')
+ , merge = utils.merge
+ , Promise = require('./promise')
+ , Document = require('./document')
+ , inGroupsOf = utils.inGroupsOf
+ , tick = utils.tick
+ , QueryStream = require('./querystream')
+
+/**
+ * Query constructor
+ *
+ * @api private
+ */
+
+function Query (criteria, options) {
+ options = this.options = options || {};
+ this.safe = options.safe
+
+ // normalize population options
+ var pop = this.options.populate;
+ this.options.populate = {};
+
+ if (pop && Array.isArray(pop)) {
+ for (var i = 0, l = pop.length; i < l; i++) {
+ this.options.populate[pop[i]] = {};
+ }
+ }
+
+ this._conditions = {};
+ if (criteria) this.find(criteria);
+}
+
+/**
+ * Binds this query to a model.
+ * @param {Function} param
+ * @return {Query}
+ * @api public
+ */
+
+Query.prototype.bind = function bind (model, op, updateArg) {
+ this.model = model;
+ this.op = op;
+ if (op === 'update') this._updateArg = updateArg;
+ return this;
+};
+
+/**
+ * Executes the query returning a promise.
+ *
+ * Examples:
+ * query.run();
+ * query.run(callback);
+ * query.run('update');
+ * query.run('find', callback);
+ *
+ * @param {String|Function} op (optional)
+ * @param {Function} callback (optional)
+ * @return {Promise}
+ * @api public
+ */
+
+Query.prototype.run =
+Query.prototype.exec = function (op, callback) {
+ var promise = new Promise();
+
+ switch (typeof op) {
+ case 'function':
+ callback = op;
+ op = null;
+ break;
+ case 'string':
+ this.op = op;
+ break;
+ }
+
+ if (callback) promise.addBack(callback);
+
+ if (!this.op) {
+ promise.complete();
+ return promise;
+ }
+
+ if ('update' == this.op) {
+ this.update(this._updateArg, promise.resolve.bind(promise));
+ return promise;
+ }
+
+ if ('distinct' == this.op) {
+ this.distinct(this._distinctArg, promise.resolve.bind(promise));
+ return promise;
+ }
+
+ this[this.op](promise.resolve.bind(promise));
+ return promise;
+};
+
+/**
+ * Finds documents.
+ *
+ * @param {Object} criteria
+ * @param {Function} callback
+ * @api public
+ */
+
+Query.prototype.find = function (criteria, callback) {
+ this.op = 'find';
+ if ('function' === typeof criteria) {
+ callback = criteria;
+ criteria = {};
+ } else if (criteria instanceof Query) {
+ // TODO Merge options, too
+ merge(this._conditions, criteria._conditions);
+ } else if (criteria instanceof Document) {
+ merge(this._conditions, criteria.toObject());
+ } else if (criteria && 'Object' === criteria.constructor.name) {
+ merge(this._conditions, criteria);
+ }
+ if (!callback) return this;
+ return this.execFind(callback);
+};
+
+/**
+ * Casts obj, or if obj is not present, then this._conditions,
+ * based on the model's schema.
+ *
+ * @param {Function} model
+ * @param {Object} obj (optional)
+ * @api public
+ */
+
+Query.prototype.cast = function (model, obj) {
+ obj || (obj= this._conditions);
+
+ var schema = model.schema
+ , paths = Object.keys(obj)
+ , i = paths.length
+ , any$conditionals
+ , schematype
+ , nested
+ , path
+ , type
+ , val;
+
+ while (i--) {
+ path = paths[i];
+ val = obj[path];
+
+ if ('$or' === path || '$nor' === path) {
+ var k = val.length
+ , orComponentQuery;
+
+ while (k--) {
+ orComponentQuery = new Query(val[k]);
+ orComponentQuery.cast(model);
+ val[k] = orComponentQuery._conditions;
+ }
+
+ } else if (path === '$where') {
+ type = typeof val;
+
+ if ('string' !== type && 'function' !== type) {
+ throw new Error("Must have a string or function for $where");
+ }
+
+ if ('function' === type) {
+ obj[path] = val.toString();
+ }
+
+ continue;
+
+ } else {
+
+ if (!schema) {
+ // no casting for Mixed types
+ continue;
+ }
+
+ schematype = schema.path(path);
+
+ if (!schematype) {
+ // Handle potential embedded array queries
+ var split = path.split('.')
+ , j = split.length
+ , pathFirstHalf
+ , pathLastHalf
+ , remainingConds
+ , castingQuery;
+
+ // Find the part of the var path that is a path of the Schema
+ while (j--) {
+ pathFirstHalf = split.slice(0, j).join('.');
+ schematype = schema.path(pathFirstHalf);
+ if (schematype) break;
+ }
+
+ // If a substring of the input path resolves to an actual real path...
+ if (schematype) {
+ // Apply the casting; similar code for $elemMatch in schema/array.js
+ if (schematype.caster && schematype.caster.schema) {
+ remainingConds = {};
+ pathLastHalf = split.slice(j).join('.');
+ remainingConds[pathLastHalf] = val;
+ castingQuery = new Query(remainingConds);
+ castingQuery.cast(schematype.caster);
+ obj[path] = castingQuery._conditions[pathLastHalf];
+ } else {
+ obj[path] = val;
+ }
+ }
+
+ } else if (val === null || val === undefined) {
+ continue;
+ } else if ('Object' === val.constructor.name) {
+
+ any$conditionals = Object.keys(val).some(function (k) {
+ return k.charAt(0) === '$' && k !== '$id' && k !== '$ref';
+ });
+
+ if (!any$conditionals) {
+ obj[path] = schematype.castForQuery(val);
+ } else {
+
+ var ks = Object.keys(val)
+ , k = ks.length
+ , $cond;
+
+ while (k--) {
+ $cond = ks[k];
+ nested = val[$cond];
+
+ if ('$exists' === $cond) {
+ if ('boolean' !== typeof nested) {
+ throw new Error("$exists parameter must be Boolean");
+ }
+ continue;
+ }
+
+ if ('$type' === $cond) {
+ if ('number' !== typeof nested) {
+ throw new Error("$type parameter must be Number");
+ }
+ continue;
+ }
+
+ if ('$not' === $cond) {
+ this.cast(model, nested);
+ } else {
+ val[$cond] = schematype.castForQuery($cond, nested);
+ }
+ }
+ }
+ } else {
+ obj[path] = schematype.castForQuery(val);
+ }
+ }
+ }
+};
+
+/**
+ * Returns default options.
+ * @api private
+ */
+
+Query.prototype._optionsForExec = function (model) {
+ var options = utils.clone(this.options, { retainKeyOrder: true });
+ delete options.populate;
+ if (! ('safe' in options)) options.safe = model.options.safe;
+ return options;
+};
+
+/**
+ * Applies schematype selected options to this query.
+ * @api private
+ */
+
+Query.prototype._applyPaths = function applyPaths () {
+ // determine if query is selecting or excluding fields
+
+ var fields = this._fields
+ , exclude
+ , keys
+ , ki
+
+ if (fields) {
+ keys = Object.keys(fields);
+ ki = keys.length;
+
+ while (ki--) {
+ if ('_id' == keys[ki]) continue;
+ exclude = 0 === fields[keys[ki]];
+ break;
+ }
+ }
+
+ // if selecting, apply default schematype select:true fields
+ // if excluding, apply schematype select:false fields
+ // if not specified, apply both
+
+ var selected = []
+ , excluded = []
+
+ this.model.schema.eachPath(function (path, type) {
+ if ('boolean' != typeof type.selected) return;
+ ;(type.selected ? selected : excluded).push(path);
+ });
+
+ switch (exclude) {
+ case true:
+ this.exclude(excluded);
+ break;
+ case false:
+ this.select(selected);
+ break;
+ case undefined:
+ excluded.length && this.exclude(excluded);
+ selected.length && this.select(selected);
+ break;
+ }
+}
+
+/**
+ * Sometimes you need to query for things in mongodb using a JavaScript
+ * expression. You can do so via find({$where: javascript}), or you can
+ * use the mongoose shortcut method $where via a Query chain or from
+ * your mongoose Model.
+ *
+ * @param {String|Function} js is a javascript string or anonymous function
+ * @return {Query}
+ * @api public
+ */
+
+Query.prototype.$where = function (js) {
+ this._conditions['$where'] = js;
+ return this;
+};
+
+/**
+ * `where` enables a very nice sugary api for doing your queries.
+ * For example, instead of writing:
+ *
+ * User.find({age: {$gte: 21, $lte: 65}}, callback);
+ *
+ * we can instead write more readably:
+ *
+ * User.where('age').gte(21).lte(65);
+ *
+ * Moreover, you can also chain a bunch of these together like:
+ *
+ * User
+ * .where('age').gte(21).lte(65)
+ * .where('name', /^b/i) // All names that begin where b or B
+ * .where('friends').slice(10);
+ *
+ * @param {String} path
+ * @param {Object} val (optional)
+ * @return {Query}
+ * @api public
+ */
+
+Query.prototype.where = function (path, val) {
+ if (2 === arguments.length) {
+ this._conditions[path] = val;
+ }
+ this._currPath = path;
+ return this;
+};
+
+/**
+ * `equals` sugar.
+ *
+ * User.where('age').equals(49);
+ *
+ * Same as
+ *
+ * User.where('age', 49);
+ *
+ * @param {object} val
+ * @return {Query}
+ * @api public
+ */
+
+Query.prototype.equals = function equals (val) {
+ var path = this._currPath;
+ if (!path) throw new Error('equals() must be used after where()');
+ this._conditions[path] = val;
+ return this;
+}
+
+/**
+ * $or
+ */
+
+Query.prototype.or =
+Query.prototype.$or = function $or (array) {
+ var or = this._conditions.$or || (this._conditions.$or = []);
+ if (!Array.isArray(array)) array = [array];
+ or.push.apply(or, array);
+ return this;
+}
+
+/**
+ * $nor
+ */
+
+Query.prototype.nor =
+Query.prototype.$nor = function $nor (array) {
+ var nor = this._conditions.$nor || (this._conditions.$nor = []);
+ if (!Array.isArray(array)) array = [array];
+ nor.push.apply(nor, array);
+ return this;
+}
+
+/**
+ * $gt, $gte, $lt, $lte, $ne, $in, $nin, $all, $regex, $size, $maxDistance
+ *
+ * Can be used on Numbers or Dates.
+ *
+ * Thing.where('type').$nin(array)
+ */
+
+'gt gte lt lte ne in nin all regex size maxDistance'.split(' ').forEach( function ($conditional) {
+ Query.prototype['$' + $conditional] =
+ Query.prototype[$conditional] = function (path, val) {
+ if (arguments.length === 1) {
+ val = path;
+ path = this._currPath
+ }
+ var conds = this._conditions[path] || (this._conditions[path] = {});
+ conds['$' + $conditional] = val;
+ return this;
+ };
+});
+
+/**
+ * notEqualTo
+ *
+ * alias of `query.$ne()`
+ */
+
+Query.prototype.notEqualTo = Query.prototype.ne;
+
+/**
+ * $mod, $near
+ */
+
+;['mod', 'near'].forEach( function ($conditional) {
+ Query.prototype['$' + $conditional] =
+ Query.prototype[$conditional] = function (path, val) {
+ if (arguments.length === 1) {
+ val = path;
+ path = this._currPath
+ } else if (arguments.length === 2 && !Array.isArray(val)) {
+ val = utils.args(arguments);
+ path = this._currPath;
+ } else if (arguments.length === 3) {
+ val = utils.args(arguments, 1);
+ }
+ var conds = this._conditions[path] || (this._conditions[path] = {});
+ conds['$' + $conditional] = val;
+ return this;
+ };
+});
+
+/**
+ * $exists
+ */
+
+Query.prototype.$exists =
+Query.prototype.exists = function (path, val) {
+ if (arguments.length === 0) {
+ path = this._currPath
+ val = true;
+ } else if (arguments.length === 1) {
+ if ('boolean' === typeof path) {
+ val = path;
+ path = this._currPath;
+ } else {
+ val = true;
+ }
+ }
+ var conds = this._conditions[path] || (this._conditions[path] = {});
+ conds['$exists'] = val;
+ return this;
+};
+
+/**
+ * $elemMatch
+ */
+
+Query.prototype.$elemMatch =
+Query.prototype.elemMatch = function (path, criteria) {
+ var block;
+ if ('Object' === path.constructor.name) {
+ criteria = path;
+ path = this._currPath;
+ } else if ('function' === typeof path) {
+ block = path;
+ path = this._currPath;
+ } else if ('Object' === criteria.constructor.name) {
+ } else if ('function' === typeof criteria) {
+ block = criteria;
+ } else {
+ throw new Error("Argument error");
+ }
+ var conds = this._conditions[path] || (this._conditions[path] = {});
+ if (block) {
+ criteria = new Query();
+ block(criteria);
+ conds['$elemMatch'] = criteria._conditions;
+ } else {
+ conds['$elemMatch'] = criteria;
+ }
+ return this;
+};
+
+/**
+ * @private
+ */
+
+function me () { return this }
+
+/**
+ * Spatial queries
+ */
+
+// query.within.box()
+// query.within.center()
+var within = 'within $within'.split(' ');
+within.push('wherein', '$wherein'); // deprecated, an old mistake possibly?
+within.forEach(function (getter) {
+ Object.defineProperty(Query.prototype, getter, {
+ get: me
+ });
+});
+
+Query.prototype['$box'] =
+Query.prototype.box = function (path, val) {
+ if (arguments.length === 1) {
+ val = path;
+ path = this._currPath;
+ }
+ var conds = this._conditions[path] || (this._conditions[path] = {});
+ conds['$within'] = { '$box': [val.ll, val.ur] };
+ return this;
+};
+
+Query.prototype['$center'] =
+Query.prototype.center = function (path, val) {
+ if (arguments.length === 1) {
+ val = path;
+ path = this._currPath;
+ }
+ var conds = this._conditions[path] || (this._conditions[path] = {});
+ conds['$within'] = { '$center': [val.center, val.radius] };
+ return this;
+};
+
+Query.prototype['$centerSphere'] =
+Query.prototype.centerSphere = function (path, val) {
+ if (arguments.length === 1) {
+ val = path;
+ path = this._currPath;
+ }
+ var conds = this._conditions[path] || (this._conditions[path] = {});
+ conds['$within'] = { '$centerSphere': [val.center, val.radius] };
+ return this;
+};
+
+/**
+ * select
+ *
+ * _also aliased as fields()_
+ *
+ * Chainable method for specifying which fields
+ * to include or exclude from the document that is
+ * returned from MongoDB.
+ *
+ * Examples:
+ * query.fields({a: 1, b: 1, c: 1, _id: 0});
+ * query.fields('a b c');
+ *
+ * @param {Object}
+ */
+
+Query.prototype.select =
+Query.prototype.fields = function () {
+ var arg0 = arguments[0];
+ if (!arg0) return this;
+ if ('Object' === arg0.constructor.name || Array.isArray(arg0)) {
+ this._applyFields(arg0);
+ } else if (arguments.length === 1 && typeof arg0 === 'string') {
+ this._applyFields({only: arg0});
+ } else {
+ this._applyFields({only: this._parseOnlyExcludeFields.apply(this, arguments)});
+ }
+ return this;
+};
+
+/**
+ * only
+ *
+ * Chainable method for adding the specified fields to the
+ * object of fields to only include.
+ *
+ * Examples:
+ * query.only('a b c');
+ * query.only('a', 'b', 'c');
+ * query.only(['a', 'b', 'c']);
+ *
+ * @param {String|Array} space separated list of fields OR
+ * an array of field names
+ * We can also take arguments as the "array" of field names
+ * @api public
+ */
+
+Query.prototype.only = function (fields) {
+ fields = this._parseOnlyExcludeFields.apply(this, arguments);
+ this._applyFields({ only: fields });
+ return this;
+};
+
+/**
+ * exclude
+ *
+ * Chainable method for adding the specified fields to the
+ * object of fields to exclude.
+ *
+ * Examples:
+ * query.exclude('a b c');
+ * query.exclude('a', 'b', 'c');
+ * query.exclude(['a', 'b', 'c']);
+ *
+ * @param {String|Array} space separated list of fields OR
+ * an array of field names
+ * We can also take arguments as the "array" of field names
+ * @api public
+ */
+
+Query.prototype.exclude = function (fields) {
+ fields = this._parseOnlyExcludeFields.apply(this, arguments);
+ this._applyFields({ exclude: fields });
+ return this;
+};
+
+/**
+ * $slice()
+ */
+
+Query.prototype['$slice'] =
+Query.prototype.slice = function (path, val) {
+ if (arguments.length === 1) {
+ val = path;
+ path = this._currPath
+ } else if (arguments.length === 2) {
+ if ('number' === typeof path) {
+ val = [path, val];
+ path = this._currPath;
+ }
+ } else if (arguments.length === 3) {
+ val = utils.args(arguments, 1);
+ }
+ var myFields = this._fields || (this._fields = {});
+ myFields[path] = { '$slice': val };
+ return this;
+};
+
+/**
+ * Private method for interpreting the different ways
+ * you can pass in fields to both Query.prototype.only
+ * and Query.prototype.exclude.
+ *
+ * @param {String|Array|Object} fields
+ * @api private
+ */
+
+Query.prototype._parseOnlyExcludeFields = function (fields) {
+ if (1 === arguments.length && 'string' === typeof fields) {
+ fields = fields.split(' ');
+ } else if (Array.isArray(fields)) {
+ // do nothing
+ } else {
+ fields = utils.args(arguments);
+ }
+ return fields;
+};
+
+/**
+ * Private method for interpreting and applying the different
+ * ways you can specify which fields you want to include
+ * or exclude.
+ *
+ * Example 1: Include fields 'a', 'b', and 'c' via an Array
+ * query.fields('a', 'b', 'c');
+ * query.fields(['a', 'b', 'c']);
+ *
+ * Example 2: Include fields via 'only' shortcut
+ * query.only('a b c');
+ *
+ * Example 3: Exclude fields via 'exclude' shortcut
+ * query.exclude('a b c');
+ *
+ * Example 4: Include fields via MongoDB's native format
+ * query.fields({a: 1, b: 1, c: 1})
+ *
+ * Example 5: Exclude fields via MongoDB's native format
+ * query.fields({a: 0, b: 0, c: 0});
+ *
+ * @param {Object|Array} the formatted collection of fields to
+ * include and/or exclude
+ * @api private
+ */
+
+Query.prototype._applyFields = function (fields) {
+ var $fields
+ , pathList;
+
+ if (Array.isArray(fields)) {
+ $fields = fields.reduce(function ($fields, field) {
+ $fields[field] = 1;
+ return $fields;
+ }, {});
+ } else if (pathList = fields.only || fields.exclude) {
+ $fields =
+ this._parseOnlyExcludeFields(pathList)
+ .reduce(function ($fields, field) {
+ $fields[field] = fields.only ? 1: 0;
+ return $fields;
+ }, {});
+ } else if ('Object' === fields.constructor.name) {
+ $fields = fields;
+ } else {
+ throw new Error("fields is invalid");
+ }
+
+ var myFields = this._fields || (this._fields = {});
+ for (var k in $fields) myFields[k] = $fields[k];
+};
+
+/**
+ * sort
+ *
+ * Sets the sort
+ *
+ * Examples:
+ * query.sort('test', 1)
+ * query.sort('field', -1)
+ * query.sort('field', -1, 'test', 1)
+ *
+ * @api public
+ */
+
+Query.prototype.sort = function () {
+ var sort = this.options.sort || (this.options.sort = []);
+
+ inGroupsOf(2, arguments, function (field, value) {
+ sort.push([field, value]);
+ });
+
+ return this;
+};
+
+/**
+ * asc
+ *
+ * Sorts ascending.
+ *
+ * query.asc('name', 'age');
+ */
+
+Query.prototype.asc = function () {
+ var sort = this.options.sort || (this.options.sort = []);
+ for (var i = 0, l = arguments.length; i < l; i++) {
+ sort.push([arguments[i], 1]);
+ }
+ return this;
+};
+
+/**
+ * desc
+ *
+ * Sorts descending.
+ *
+ * query.desc('name', 'age');
+ */
+
+Query.prototype.desc = function () {
+ var sort = this.options.sort || (this.options.sort = []);
+ for (var i = 0, l = arguments.length; i < l; i++) {
+ sort.push([arguments[i], -1]);
+ }
+ return this;
+};
+
+/**
+ * limit, skip, maxscan, snapshot, batchSize, comment
+ *
+ * Sets these associated options.
+ *
+ * query.comment('feed query');
+ */
+
+;['limit', 'skip', 'maxscan', 'snapshot', 'batchSize', 'comment'].forEach( function (method) {
+ Query.prototype[method] = function (v) {
+ this.options[method] = v;
+ return this;
+ };
+});
+
+/**
+ * hint
+ *
+ * Sets query hints.
+ *
+ * Examples:
+ * new Query().hint({ indexA: 1, indexB: -1})
+ * new Query().hint("indexA", 1, "indexB", -1)
+ *
+ * @param {Object|String} v
+ * @param {Int} [multi]
+ * @return {Query}
+ * @api public
+ */
+
+Query.prototype.hint = function (v, multi) {
+ var hint = this.options.hint || (this.options.hint = {})
+ , k
+
+ if (multi) {
+ inGroupsOf(2, arguments, function (field, val) {
+ hint[field] = val;
+ });
+ } else if ('Object' === v.constructor.name) {
+ // must keep object keys in order so don't use Object.keys()
+ for (k in v) {
+ hint[k] = v[k];
+ }
+ }
+
+ return this;
+};
+
+/**
+ * slaveOk
+ *
+ * Sets slaveOk option.
+ *
+ * new Query().slaveOk() <== true
+ * new Query().slaveOk(true)
+ * new Query().slaveOk(false)
+ *
+ * @param {Boolean} v (defaults to true)
+ * @api public
+ */
+
+Query.prototype.slaveOk = function (v) {
+ this.options.slaveOk = arguments.length ? !!v : true;
+ return this;
+};
+
+/**
+ * tailable
+ *
+ * Sets tailable option.
+ *
+ * new Query().tailable() <== true
+ * new Query().tailable(true)
+ * new Query().tailable(false)
+ *
+ * @param {Boolean} v (defaults to true)
+ * @api public
+ */
+
+Query.prototype.tailable = function (v) {
+ this.options.tailable = arguments.length ? !!v : true;
+ return this;
+};
+
+/**
+ * execFind
+ *
+ * @api private
+ */
+
+Query.prototype.execFind = function (callback) {
+ var model = this.model
+ , promise = new Promise(callback);
+
+ try {
+ this.cast(model);
+ } catch (err) {
+ return promise.error(err);
+ }
+
+ // apply default schematype path selections
+ this._applyPaths();
+
+ var self = this
+ , castQuery = this._conditions
+ , options = this._optionsForExec(model)
+
+ var fields = utils.clone(options.fields = this._fields);
+
+ model.collection.find(castQuery, options, function (err, cursor) {
+ if (err) return promise.error(err);
+ cursor.toArray(tick(cb));
+ });
+
+ function cb (err, docs) {
+ if (err) return promise.error(err);
+
+ var arr = []
+ , count = docs.length;
+
+ if (!count) return promise.complete([]);
+
+ for (var i = 0, l = docs.length; i < l; i++) {
+ arr[i] = new model(undefined, fields);
+
+ // skip _id for pre-init hooks
+ delete arr[i]._doc._id;
+
+ arr[i].init(docs[i], self, function (err) {
+ if (err) return promise.error(err);
+ --count || promise.complete(arr);
+ });
+ }
+ }
+
+ return this;
+};
+
+/**
+ * each()
+ *
+ * Streaming cursors.
+ *
+ * The `callback` is called repeatedly for each document
+ * found in the collection as it's streamed. If an error
+ * occurs streaming stops.
+ *
+ * Example:
+ * query.each(function (err, user) {
+ * if (err) return res.end("aww, received an error. all done.");
+ * if (user) {
+ * res.write(user.name + '\n')
+ * } else {
+ * res.end("reached end of cursor. all done.");
+ * }
+ * });
+ *
+ * A third parameter may also be used in the callback which
+ * allows you to iterate the cursor manually.
+ *
+ * Example:
+ * query.each(function (err, user, next) {
+ * if (err) return res.end("aww, received an error. all done.");
+ * if (user) {
+ * res.write(user.name + '\n')
+ * doSomethingAsync(next);
+ * } else {
+ * res.end("reached end of cursor. all done.");
+ * }
+ * });
+ *
+ * @param {Function} callback
+ * @return {Query}
+ * @api public
+ */
+
+Query.prototype.each = function (callback) {
+ var model = this.model
+ , options = this._optionsForExec(model)
+ , manual = 3 == callback.length
+ , self = this
+
+ try {
+ this.cast(model);
+ } catch (err) {
+ return callback(err);
+ }
+
+ var fields = utils.clone(options.fields = this._fields);
+
+ function complete (err, val) {
+ if (complete.ran) return;
+ complete.ran = true;
+ callback(err, val);
+ }
+
+ model.collection.find(this._conditions, options, function (err, cursor) {
+ if (err) return complete(err);
+
+ var ticks = 0;
+ next();
+
+ function next () {
+ // nextTick is necessary to avoid stack overflows when
+ // dealing with large result sets. yield occasionally.
+ if (!(++ticks % 20)) {
+ process.nextTick(function () {
+ cursor.nextObject(onNextObject);
+ });
+ } else {
+ cursor.nextObject(onNextObject);
+ }
+ }
+
+ function onNextObject (err, doc) {
+ if (err) return complete(err);
+
+ // when doc is null we hit the end of the cursor
+ if (!doc) return complete(null, null);
+
+ var instance = new model(undefined, fields);
+
+ // skip _id for pre-init hooks
+ delete instance._doc._id;
+
+ instance.init(doc, self, function (err) {
+ if (err) return complete(err);
+
+ if (manual) {
+ callback(null, instance, next);
+ } else {
+ callback(null, instance);
+ next();
+ }
+ });
+ }
+
+ });
+
+ return this;
+}
+
+/**
+ * findOne
+ *
+ * Casts the query, sends the findOne command to mongodb.
+ * Upon receiving the document, we initialize a mongoose
+ * document based on the returned document from mongodb,
+ * and then we invoke a callback on our mongoose document.
+ *
+ * @param {Function} callback function (err, found)
+ * @api public
+ */
+
+Query.prototype.findOne = function (callback) {
+ this.op = 'findOne';
+
+ if (!callback) return this;
+
+ var model = this.model;
+ var promise = new Promise(callback);
+
+ try {
+ this.cast(model);
+ } catch (err) {
+ promise.error(err);
+ return this;
+ }
+
+ // apply default schematype path selections
+ this._applyPaths();
+
+ var self = this
+ , castQuery = this._conditions
+ , options = this._optionsForExec(model)
+
+ var fields = utils.clone(options.fields = this._fields);
+
+ model.collection.findOne(castQuery, options, tick(function (err, doc) {
+ if (err) return promise.error(err);
+ if (!doc) return promise.complete(null);
+
+ var casted = new model(undefined, fields);
+
+ // skip _id for pre-init hooks
+ delete casted._doc._id;
+
+ casted.init(doc, self, function (err) {
+ if (err) return promise.error(err);
+ promise.complete(casted);
+ });
+ }));
+
+ return this;
+};
+
+/**
+ * count
+ *
+ * Casts this._conditions and sends a count
+ * command to mongodb. Invokes a callback upon
+ * receiving results
+ *
+ * @param {Function} callback fn(err, cardinality)
+ * @api public
+ */
+
+Query.prototype.count = function (callback) {
+ this.op = 'count';
+ var model = this.model;
+
+ try {
+ this.cast(model);
+ } catch (err) {
+ return callback(err);
+ }
+
+ var castQuery = this._conditions;
+ model.collection.count(castQuery, tick(callback));
+
+ return this;
+};
+
+/**
+ * distinct
+ *
+ * Casts this._conditions and sends a distinct
+ * command to mongodb. Invokes a callback upon
+ * receiving results
+ *
+ * @param {Function} callback fn(err, cardinality)
+ * @api public
+ */
+
+Query.prototype.distinct = function (field, callback) {
+ this.op = 'distinct';
+ var model = this.model;
+
+ try {
+ this.cast(model);
+ } catch (err) {
+ return callback(err);
+ }
+
+ var castQuery = this._conditions;
+ model.collection.distinct(field, castQuery, tick(callback));
+
+ return this;
+};
+
+/**
+ * These operators require casting docs
+ * to real Documents for Update operations.
+ * @private
+ */
+
+var castOps = {
+ $push: 1
+ , $pushAll: 1
+ , $addToSet: 1
+ , $set: 1
+};
+
+/**
+ * These operators should be cast to numbers instead
+ * of their path schema type.
+ * @private
+ */
+
+var numberOps = {
+ $pop: 1
+ , $unset: 1
+ , $inc: 1
+}
+
+/**
+ * update
+ *
+ * Casts the `doc` according to the model Schema and
+ * sends an update command to MongoDB.
+ *
+ * _All paths passed that are not $atomic operations
+ * will become $set ops so we retain backwards compatibility._
+ *
+ * Example:
+ * `Model.update({..}, { title: 'remove words' }, ...)`
+ *
+ * becomes
+ *
+ * `Model.update({..}, { $set: { title: 'remove words' }}, ...)`
+ *
+ *
+ * _Passing an empty object `{}` as the doc will result
+ * in a no-op. The update operation will be ignored and the
+ * callback executed without sending the command to MongoDB so as
+ * to prevent accidently overwritting the collection._
+ *
+ * @param {Object} doc - the update
+ * @param {Function} callback - fn(err)
+ * @api public
+ */
+
+Query.prototype.update = function update (doc, callback) {
+ this.op = 'update';
+ this._updateArg = doc;
+
+ var model = this.model
+ , options = this._optionsForExec(model)
+ , useSet = model.options['use$SetOnSave']
+ , castQuery
+ , castDoc
+
+ try {
+ this.cast(model);
+ castQuery = this._conditions;
+ } catch (err) {
+ return callback(err);
+ }
+
+ try {
+ castDoc = this._castUpdate(doc);
+ } catch (err) {
+ return callback(err);
+ }
+
+ if (castDoc) {
+ model.collection.update(castQuery, castDoc, options, tick(callback));
+ } else {
+ process.nextTick(function () {
+ callback(null);
+ });
+ }
+
+ return this;
+};
+
+/**
+ * Casts obj for an update command.
+ *
+ * @param {Object} obj
+ * @return {Object} obj after casting its values
+ * @api private
+ */
+
+Query.prototype._castUpdate = function _castUpdate (obj) {
+ var ops = Object.keys(obj)
+ , i = ops.length
+ , ret = {}
+ , hasKeys
+ , val
+
+ while (i--) {
+ var op = ops[i];
+ hasKeys = true;
+ if ('$' !== op[0]) {
+ // fix up $set sugar
+ if (!ret.$set) {
+ if (obj.$set) {
+ ret.$set = obj.$set;
+ } else {
+ ret.$set = {};
+ }
+ }
+ ret.$set[op] = obj[op];
+ ops.splice(i, 1);
+ if (!~ops.indexOf('$set')) ops.push('$set');
+ } else if ('$set' === op) {
+ if (!ret.$set) {
+ ret[op] = obj[op];
+ }
+ } else {
+ ret[op] = obj[op];
+ }
+ }
+
+ // cast each value
+ i = ops.length;
+
+ while (i--) {
+ op = ops[i];
+ val = ret[op];
+ if ('Object' === val.constructor.name) {
+ this._walkUpdatePath(val, op);
+ } else {
+ var msg = 'Invalid atomic update value for ' + op + '. '
+ + 'Expected an object, received ' + typeof val;
+ throw new Error(msg);
+ }
+ }
+
+ return hasKeys && ret;
+}
+
+/**
+ * Walk each path of obj and cast its values
+ * according to its schema.
+ *
+ * @param {Object} obj - part of a query
+ * @param {String} op - the atomic operator ($pull, $set, etc)
+ * @param {String} pref - path prefix (internal only)
+ * @private
+ */
+
+Query.prototype._walkUpdatePath = function _walkUpdatePath (obj, op, pref) {
+ var strict = this.model.schema.options.strict
+ , prefix = pref ? pref + '.' : ''
+ , keys = Object.keys(obj)
+ , i = keys.length
+ , schema
+ , key
+ , val
+
+ while (i--) {
+ key = keys[i];
+ val = obj[key];
+
+ if (val && 'Object' === val.constructor.name) {
+ // watch for embedded doc schemas
+ schema = this._getSchema(prefix + key);
+ if (schema && schema.caster && op in castOps) {
+ // embedded doc schema
+
+ if (strict && !schema) {
+ // path is not in our strict schema. do not include
+ delete obj[key];
+ } else {
+ if ('$each' in val) {
+ obj[key] = {
+ $each: this._castUpdateVal(schema, val.$each, op)
+ }
+ } else {
+ obj[key] = this._castUpdateVal(schema, val, op);
+ }
+ }
+ } else {
+ this._walkUpdatePath(val, op, prefix + key);
+ }
+ } else {
+ schema = '$each' === key
+ ? this._getSchema(pref)
+ : this._getSchema(prefix + key);
+
+ if (strict && !schema) {
+ delete obj[key];
+ } else {
+ obj[key] = this._castUpdateVal(schema, val, op, key);
+ }
+ }
+ }
+}
+
+/**
+ * Casts `val` according to `schema` and atomic `op`.
+ *
+ * @param {Schema} schema
+ * @param {Object} val
+ * @param {String} op - the atomic operator ($pull, $set, etc)
+ * @param {String} [$conditional]
+ * @private
+ */
+
+Query.prototype._castUpdateVal = function _castUpdateVal (schema, val, op, $conditional) {
+ if (!schema) {
+ // non-existing schema path
+ return op in numberOps
+ ? Number(val)
+ : val
+ }
+
+ if (schema.caster && op in castOps &&
+ ('Object' === val.constructor.name || Array.isArray(val))) {
+ // Cast values for ops that add data to MongoDB.
+ // Ensures embedded documents get ObjectIds etc.
+ var tmp = schema.cast(val);
+
+ if (Array.isArray(val)) {
+ val = tmp;
+ } else {
+ val = tmp[0];
+ }
+ }
+
+ if (op in numberOps) return Number(val);
+ if (/^\$/.test($conditional)) return schema.castForQuery($conditional, val);
+ return schema.castForQuery(val)
+}
+
+/**
+ * Finds the schema for `path`. This is different than
+ * calling `schema.path` as it also resolves paths with
+ * positional selectors (something.$.another.$.path).
+ *
+ * @param {String} path
+ * @private
+ */
+
+Query.prototype._getSchema = function _getSchema (path) {
+ var schema = this.model.schema
+ , pathschema = schema.path(path);
+
+ if (pathschema)
+ return pathschema;
+
+ // look for arrays
+ return (function search (parts, schema) {
+ var p = parts.length + 1
+ , foundschema
+ , trypath
+
+ while (p--) {
+ trypath = parts.slice(0, p).join('.');
+ foundschema = schema.path(trypath);
+ if (foundschema) {
+ if (foundschema.caster) {
+ // Now that we found the array, we need to check if there
+ // are remaining document paths to look up for casting.
+ // Also we need to handle array.$.path since schema.path
+ // doesn't work for that.
+ if (p !== parts.length) {
+ if ('$' === parts[p]) {
+ // comments.$.comments.$.title
+ return search(parts.slice(p+1), foundschema.schema);
+ } else {
+ // this is the last path of the selector
+ return search(parts.slice(p), foundschema.schema);
+ }
+ }
+ }
+ return foundschema;
+ }
+ }
+ })(path.split('.'), schema)
+}
+
+/**
+ * remove
+ *
+ * Casts the query, sends the remove command to
+ * mongodb where the query contents, and then
+ * invokes a callback upon receiving the command
+ * result.
+ *
+ * @param {Function} callback
+ * @api public
+ */
+
+Query.prototype.remove = function (callback) {
+ this.op = 'remove';
+
+ var model = this.model
+ , options = this._optionsForExec(model);
+
+ try {
+ this.cast(model);
+ } catch (err) {
+ return callback(err);
+ }
+
+ var castQuery = this._conditions;
+ model.collection.remove(castQuery, options, tick(callback));
+ return this;
+};
+
+/**
+ * populate
+ *
+ * Sets population options.
+ * @api public
+ */
+
+Query.prototype.populate = function (path, fields, conditions, options) {
+ // The order of fields/conditions args is opposite Model.find but
+ // necessary to keep backward compatibility (fields could be
+ // an array, string, or object literal).
+ this.options.populate[path] =
+ new PopulateOptions(fields, conditions, options);
+
+ return this;
+};
+
+/**
+ * Populate options constructor
+ * @private
+ */
+
+function PopulateOptions (fields, conditions, options) {
+ this.conditions = conditions;
+ this.fields = fields;
+ this.options = options;
+}
+
+// make it compatible with utils.clone
+PopulateOptions.prototype.constructor = Object;
+
+/**
+ * stream
+ *
+ * Returns a stream interface
+ *
+ * Example:
+ * Thing.find({ name: /^hello/ }).stream().pipe(res)
+ *
+ * @api public
+ */
+
+Query.prototype.stream = function stream () {
+ return new QueryStream(this);
+}
+
+/**
+ * @private
+ * @TODO
+ */
+
+Query.prototype.explain = function () {
+ throw new Error("Unimplemented");
+};
+
+// TODO Add being able to skip casting -- e.g., this would be nice for scenarios like
+// if you're migrating to usernames from user id numbers:
+// query.where('user_id').in([4444, 'brian']);
+// TODO "immortal" cursors - (only work on capped collections)
+// TODO geoNear command
+
+/**
+ * Exports.
+ */
+
+module.exports = Query;
+module.exports.QueryStream = QueryStream;
diff --git a/node_modules/mongoose/lib/querystream.js b/node_modules/mongoose/lib/querystream.js
new file mode 100644
index 0000000..4093e60
--- /dev/null
+++ b/node_modules/mongoose/lib/querystream.js
@@ -0,0 +1,179 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Stream = require('stream').Stream
+var utils = require('./utils')
+
+/**
+ * QueryStream
+ *
+ * Returns a stream interface for the `query`.
+ *
+ * @param {Query} query
+ * @return {Stream}
+ */
+
+function QueryStream (query) {
+ Stream.call(this);
+
+ this.query = query;
+ this.readable = true;
+ this.paused = false;
+ this._cursor = null;
+ this._destroyed = null;
+ this._fields = null;
+ this._ticks = 0;
+
+ // give time to hook up events
+ var self = this;
+ process.nextTick(function () {
+ self._init();
+ });
+}
+
+/**
+ * Inherit from Stream
+ * @private
+ */
+
+QueryStream.prototype.__proto__ = Stream.prototype;
+
+/**
+ * Flag stating whether or not this stream is readable.
+ */
+
+QueryStream.prototype.readable;
+
+/**
+ * Flag stating whether or not this stream is paused.
+ */
+
+QueryStream.prototype.paused;
+
+/**
+ * Initialize the query.
+ * @private
+ */
+
+QueryStream.prototype._init = function () {
+ if (this._destroyed) return;
+
+ var query = this.query
+ , model = query.model
+ , options = query._optionsForExec(model)
+ , self = this
+
+ try {
+ query.cast(model);
+ } catch (err) {
+ return self.destroy(err);
+ }
+
+ self._fields = utils.clone(options.fields = query._fields);
+
+ model.collection.find(query._conditions, options, function (err, cursor) {
+ if (err) return self.destroy(err);
+ self._cursor = cursor;
+ self._next();
+ });
+}
+
+/**
+ * Pull the next document from the cursor.
+ * @private
+ */
+
+QueryStream.prototype._next = function () {
+ if (this.paused || this._destroyed) return;
+
+ var self = this;
+
+ // nextTick is necessary to avoid stack overflows when
+ // dealing with large result sets. yield occasionally.
+ if (!(++this._ticks % 20)) {
+ process.nextTick(function () {
+ self._cursor.nextObject(function (err, doc) {
+ self._onNextObject(err, doc);
+ });
+ });
+ } else {
+ self._cursor.nextObject(function (err, doc) {
+ self._onNextObject(err, doc);
+ });
+ }
+}
+
+/**
+ * Handle each document as its returned from the cursor
+ * transforming the raw `doc` from -native into a model
+ * instance.
+ *
+ * @private
+ */
+
+QueryStream.prototype._onNextObject = function (err, doc) {
+ if (err) return this.destroy(err);
+
+ // when doc is null we hit the end of the cursor
+ if (!doc) {
+ return this.destroy();
+ }
+
+ var instance = new this.query.model(undefined, this._fields);
+
+ // skip _id for pre-init hooks
+ delete instance._doc._id;
+
+ var self = this;
+ instance.init(doc, this.query, function (err) {
+ if (err) return self.destroy(err);
+ self.emit('data', instance);
+ self._next();
+ });
+}
+
+/**
+ * Pauses this stream.
+ */
+
+QueryStream.prototype.pause = function () {
+ this.paused = true;
+}
+
+/**
+ * Resumes this stream.
+ */
+
+QueryStream.prototype.resume = function () {
+ this.paused = false;
+ this._next();
+}
+
+/**
+ * Destroys the stream, closing the underlying
+ * cursor. No more events will be emitted.
+ */
+
+QueryStream.prototype.destroy = function (err) {
+ if (this._destroyed) return;
+ this._destroyed = true;
+ this.readable = false;
+
+ if (this._cursor) {
+ this._cursor.close();
+ }
+
+ if (err) {
+ this.emit('error', err);
+ }
+
+ this.emit('close');
+}
+
+// TODO - maybe implement the -native raw option to pass binary?
+//QueryStream.prototype.setEncoding = function () {
+//}
+
+module.exports = exports = QueryStream;
diff --git a/node_modules/mongoose/lib/schema.js b/node_modules/mongoose/lib/schema.js
new file mode 100644
index 0000000..1dda865
--- /dev/null
+++ b/node_modules/mongoose/lib/schema.js
@@ -0,0 +1,565 @@
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('events').EventEmitter
+ , VirtualType = require('./virtualtype')
+ , utils = require('./utils')
+ , NamedScope
+ , Query
+ , Types
+
+/**
+ * Schema constructor.
+ *
+ * @param {Object} definition
+ * @api public
+ */
+
+function Schema (obj, options) {
+ this.paths = {};
+ this.virtuals = {};
+ this.inherits = {};
+ this.callQueue = [];
+ this._indexes = [];
+ this.methods = {};
+ this.statics = {};
+ this.tree = {};
+
+ // set options
+ this.options = utils.options({
+ safe: true
+ , 'use$SetOnSave': true
+ , strict: false
+ }, options);
+
+ // build paths
+ if (obj)
+ this.add(obj);
+
+ if (!this.paths['_id'] && !this.options.noId) {
+ this.add({ _id: {type: ObjectId, auto: true} });
+ }
+
+ if (!this.paths['id'] && !this.options.noVirtualId) {
+ this.virtual('id').get(function () {
+ if (this.__id) {
+ return this.__id;
+ }
+
+ return this.__id = null == this._id
+ ? null
+ : this._id.toString();
+ });
+ }
+
+ delete this.options.noVirtualId;
+};
+
+/**
+ * Inherit from EventEmitter.
+ */
+
+Schema.prototype.__proto__ = EventEmitter.prototype;
+
+/**
+ * Schema by paths
+ *
+ * Example (embedded doc):
+ * {
+ * 'test' : SchemaType,
+ * , 'test.test' : SchemaType,
+ * , 'first_name' : SchemaType
+ * }
+ *
+ * @api private
+ */
+
+Schema.prototype.paths;
+
+/**
+ * Schema as a tree
+ *
+ * Example:
+ * {
+ * '_id' : ObjectId
+ * , 'nested' : {
+ * 'key': String
+ * }
+ * }
+ *
+ * @api private
+ */
+
+Schema.prototype.tree;
+
+/**
+ * Sets the keys
+ *
+ * @param {Object} keys
+ * @param {String} prefix
+ * @api public
+ */
+
+Schema.prototype.add = function add (obj, prefix) {
+ prefix = prefix || '';
+ for (var i in obj) {
+ if (null == obj[i]) {
+ throw new TypeError('Invalid value for schema path `'+ prefix + i +'`');
+ }
+
+ if (obj[i].constructor.name == 'Object' && (!obj[i].type || obj[i].type.type)) {
+ if (Object.keys(obj[i]).length)
+ this.add(obj[i], prefix + i + '.');
+ else
+ this.path(prefix + i, obj[i]); // mixed type
+ } else
+ this.path(prefix + i, obj[i]);
+ }
+};
+
+/**
+ * Sets a path (if arity 2)
+ * Gets a path (if arity 1)
+ *
+ * @param {String} path
+ * @param {Object} constructor
+ * @api public
+ */
+
+Schema.prototype.path = function (path, obj) {
+ if (obj == undefined) {
+ if (this.paths[path]) return this.paths[path];
+
+ // Sometimes path will come in as
+ // pathNameA.4.pathNameB where 4 means the index
+ // of an embedded document in an embedded array.
+ // In this case, we need to jump to the Array's
+ // schema and call path() from there to resolve to
+ // the correct path type
+
+ var last
+ , self = this
+ , subpaths = path.split(/\.(\d+)\.?/)
+ .filter(Boolean) // removes empty strings
+
+ if (subpaths.length > 1) {
+ last = subpaths.length - 1;
+ return subpaths.reduce(function (val, subpath, i) {
+ if (val && !val.schema) {
+ if (i === last && !/\D/.test(subpath) && val instanceof Types.Array) {
+ return val.caster; // StringSchema, NumberSchema, etc
+ } else {
+ return val;
+ }
+ }
+
+ if (!/\D/.test(subpath)) { // 'path.0.subpath' on path 0
+ return val;
+ }
+
+ return val ? val.schema.path(subpath)
+ : self.path(subpath);
+ }, null);
+ }
+
+ return this.paths[subpaths[0]];
+ }
+
+ // update the tree
+ var subpaths = path.split(/\./)
+ , last = subpaths.pop()
+ , branch = this.tree;
+
+ subpaths.forEach(function(path) {
+ if (!branch[path]) branch[path] = {};
+ branch = branch[path];
+ });
+
+ branch[last] = utils.clone(obj);
+
+ this.paths[path] = Schema.interpretAsType(path, obj);
+ return this;
+};
+
+/**
+ * Converts -- e.g., Number, [SomeSchema],
+ * { type: String, enum: ['m', 'f'] } -- into
+ * the appropriate Mongoose Type, which we use
+ * later for casting, validation, etc.
+ * @param {String} path
+ * @param {Object} constructor
+ */
+
+Schema.interpretAsType = function (path, obj) {
+ if (obj.constructor.name != 'Object')
+ obj = { type: obj };
+
+ // Get the type making sure to allow keys named "type"
+ // and default to mixed if not specified.
+ // { type: { type: String, default: 'freshcut' } }
+ var type = obj.type && !obj.type.type
+ ? obj.type
+ : {};
+
+ if (type.constructor.name == 'Object') {
+ return new Types.Mixed(path, obj);
+ }
+
+ if (Array.isArray(type) || type == Array) {
+ // if it was specified through { type } look for `cast`
+ var cast = type == Array
+ ? obj.cast
+ : type[0];
+
+ if (cast instanceof Schema) {
+ return new Types.DocumentArray(path, cast, obj);
+ }
+
+ return new Types.Array(path, cast || Types.Mixed, obj);
+ }
+
+ if (undefined == Types[type.name]) {
+ throw new TypeError('Undefined type at `' + path +
+ '`\n Did you try nesting Schemas? ' +
+ 'You can only nest using refs or arrays.');
+ }
+
+ return new Types[type.name](path, obj);
+};
+
+/**
+ * Iterates through the schema's paths, passing the path string and type object
+ * to the callback.
+ *
+ * @param {Function} callback function - fn(pathstring, type)
+ * @return {Schema} this for chaining
+ * @api public
+ */
+
+Schema.prototype.eachPath = function (fn) {
+ var keys = Object.keys(this.paths)
+ , len = keys.length;
+
+ for (var i = 0; i < len; ++i) {
+ fn(keys[i], this.paths[keys[i]]);
+ }
+
+ return this;
+};
+
+/**
+ * Returns an Array of path strings that are required.
+ * @api public
+ */
+
+Object.defineProperty(Schema.prototype, 'requiredPaths', {
+ get: function () {
+ var paths = this.paths
+ , pathnames = Object.keys(paths)
+ , i = pathnames.length
+ , pathname, path
+ , requiredPaths = [];
+ while (i--) {
+ pathname = pathnames[i];
+ path = paths[pathname];
+ if (path.isRequired) requiredPaths.push(pathname);
+ }
+ return requiredPaths;
+ }
+});
+
+/**
+ * Given a path, returns whether it is a real, virtual, or
+ * ad-hoc/undefined path
+ *
+ * @param {String} path
+ * @return {String}
+ * @api public
+ */
+Schema.prototype.pathType = function (path) {
+ if (path in this.paths) return 'real';
+ if (path in this.virtuals) return 'virtual';
+ return 'adhocOrUndefined';
+};
+
+/**
+ * Adds a method call to the queue
+ *
+ * @param {String} method name
+ * @param {Array} arguments
+ * @api private
+ */
+
+Schema.prototype.queue = function(name, args){
+ this.callQueue.push([name, args]);
+ return this;
+};
+
+/**
+ * Defines a pre for the document
+ *
+ * @param {String} method
+ * @param {Function} callback
+ * @api public
+ */
+
+Schema.prototype.pre = function(){
+ return this.queue('pre', arguments);
+};
+
+/**
+ * Defines a post for the document
+ *
+ * @param {String} method
+ * @param {Function} callback
+ * @api public
+ */
+
+Schema.prototype.post = function(method, fn){
+ return this.queue('on', arguments);
+};
+
+/**
+ * Registers a plugin for this schema
+ *
+ * @param {Function} plugin callback
+ * @api public
+ */
+
+Schema.prototype.plugin = function (fn, opts) {
+ fn(this, opts);
+ return this;
+};
+
+/**
+ * Adds a method
+ *
+ * @param {String} method name
+ * @param {Function} handler
+ * @api public
+ */
+
+Schema.prototype.method = function (name, fn) {
+ if ('string' != typeof name)
+ for (var i in name)
+ this.methods[i] = name[i];
+ else
+ this.methods[name] = fn;
+ return this;
+};
+
+/**
+ * Defines a static method
+ *
+ * @param {String} name
+ * @param {Function} handler
+ * @api public
+ */
+
+Schema.prototype.static = function(name, fn) {
+ if ('string' != typeof name)
+ for (var i in name)
+ this.statics[i] = name[i];
+ else
+ this.statics[name] = fn;
+ return this;
+};
+
+/**
+ * Defines an index (most likely compound)
+ * Example:
+ * schema.index({ first: 1, last: -1 })
+ *
+ * @param {Object} field
+ * @param {Object} optional options object
+ * @api public
+ */
+
+Schema.prototype.index = function (fields, options) {
+ this._indexes.push([fields, options || {}]);
+ return this;
+};
+
+/**
+ * Sets/gets an option
+ *
+ * @param {String} key
+ * @param {Object} optional value
+ * @api public
+ */
+
+Schema.prototype.set = function (key, value) {
+ if (arguments.length == 1)
+ return this.options[key];
+ this.options[key] = value;
+ return this;
+};
+
+/**
+ * Compiles indexes from fields and schema-level indexes
+ *
+ * @api public
+ */
+
+Schema.prototype.__defineGetter__('indexes', function () {
+ var indexes = []
+ , seenSchemas = [];
+
+ collectIndexes(this);
+
+ return indexes;
+
+ function collectIndexes (schema, prefix) {
+ if (~seenSchemas.indexOf(schema)) return;
+ seenSchemas.push(schema);
+
+ var index;
+ var paths = schema.paths;
+ prefix = prefix || '';
+
+ for (var i in paths) {
+ if (paths[i]) {
+ if (paths[i] instanceof Types.DocumentArray) {
+ collectIndexes(paths[i].schema, i + '.');
+ } else {
+ index = paths[i]._index;
+
+ if (index !== false && index !== null){
+ var field = {};
+ field[prefix + i] = '2d' === index ? index : 1;
+ indexes.push([field, 'Object' === index.constructor.name ? index : {} ]);
+ }
+ }
+ }
+ }
+
+ if (prefix) {
+ fixSubIndexPaths(schema, prefix);
+ } else {
+ indexes = indexes.concat(schema._indexes);
+ }
+ }
+
+ /**
+ * Checks for indexes added to subdocs using Schema.index().
+ * These indexes need their paths prefixed properly.
+ *
+ * schema._indexes = [ [indexObj, options], [indexObj, options] ..]
+ */
+
+ function fixSubIndexPaths (schema, prefix) {
+ var subindexes = schema._indexes
+ , len = subindexes.length
+ , indexObj
+ , newindex
+ , klen
+ , keys
+ , key
+ , i = 0
+ , j
+
+ for (i = 0; i < len; ++i) {
+ indexObj = subindexes[i][0];
+ keys = Object.keys(indexObj);
+ klen = keys.length;
+ newindex = {};
+
+ // use forward iteration, order matters
+ for (j = 0; j < klen; ++j) {
+ key = keys[j];
+ newindex[prefix + key] = indexObj[key];
+ }
+
+ indexes.push([newindex, subindexes[i][1]]);
+ }
+ }
+
+});
+
+/**
+ * Retrieves or creates the virtual type with the given name.
+ *
+ * @param {String} name
+ * @return {VirtualType}
+ */
+
+Schema.prototype.virtual = function (name, options) {
+ var virtuals = this.virtuals || (this.virtuals = {});
+ var parts = name.split('.');
+ return virtuals[name] = parts.reduce(function (mem, part, i) {
+ mem[part] || (mem[part] = (i === parts.length-1)
+ ? new VirtualType(options)
+ : {});
+ return mem[part];
+ }, this.tree);
+};
+
+/**
+ * Fetches the virtual type with the given name.
+ * Should be distinct from virtual because virtual auto-defines a new VirtualType
+ * if the path doesn't exist.
+ *
+ * @param {String} name
+ * @return {VirtualType}
+ */
+
+Schema.prototype.virtualpath = function (name) {
+ return this.virtuals[name];
+};
+
+Schema.prototype.namedScope = function (name, fn) {
+ var namedScopes = this.namedScopes || (this.namedScopes = new NamedScope)
+ , newScope = Object.create(namedScopes)
+ , allScopes = namedScopes.scopesByName || (namedScopes.scopesByName = {});
+ allScopes[name] = newScope;
+ newScope.name = name;
+ newScope.block = fn;
+ newScope.query = new Query();
+ newScope.decorate(namedScopes, {
+ block0: function (block) {
+ return function () {
+ block.call(this.query);
+ return this;
+ };
+ },
+ blockN: function (block) {
+ return function () {
+ block.apply(this.query, arguments);
+ return this;
+ };
+ },
+ basic: function (query) {
+ return function () {
+ this.query.find(query);
+ return this;
+ };
+ }
+ });
+ return newScope;
+};
+
+/**
+ * ObjectId schema identifier. Not an actual ObjectId, only used for Schemas.
+ *
+ * @api public
+ */
+
+function ObjectId () {
+ throw new Error('This is an abstract interface. Its only purpose is to mark '
+ + 'fields as ObjectId in the schema creation.');
+}
+
+/**
+ * Module exports.
+ */
+
+module.exports = exports = Schema;
+
+// require down here because of reference issues
+exports.Types = Types = require('./schema/index');
+NamedScope = require('./namedscope')
+Query = require('./query');
+
+exports.ObjectId = ObjectId;
+
diff --git a/node_modules/mongoose/lib/schema/array.js b/node_modules/mongoose/lib/schema/array.js
new file mode 100644
index 0000000..6458a73
--- /dev/null
+++ b/node_modules/mongoose/lib/schema/array.js
@@ -0,0 +1,232 @@
+/**
+ * Module dependencies.
+ */
+
+var SchemaType = require('../schematype')
+ , CastError = SchemaType.CastError
+ , NumberSchema = require('./number')
+ , Types = {
+ Boolean: require('./boolean')
+ , Date: require('./date')
+ , Number: ArrayNumberSchema
+ , String: require('./string')
+ , ObjectId: require('./objectid')
+ , Buffer: require('./buffer')
+ }
+ , MongooseArray = require('../types').Array
+ , Mixed = require('./mixed')
+ , Query = require('../query')
+ , isMongooseObject = require('../utils').isMongooseObject
+
+/**
+ * Array SchemaType constructor
+ *
+ * @param {String} key
+ * @param {SchemaType} cast
+ * @api private
+ */
+
+function SchemaArray (key, cast, options) {
+ SchemaType.call(this, key, options);
+
+ if (cast) {
+ var castOptions = {};
+
+ if ('Object' === cast.constructor.name) {
+ if (cast.type) {
+ // support { type: Woot }
+ castOptions = cast;
+ cast = cast.type;
+ delete castOptions.type;
+ } else {
+ cast = Mixed;
+ }
+ }
+
+ var caster = cast.name in Types ? Types[cast.name] : cast;
+ this.casterConstructor = caster;
+ this.caster = new caster(null, castOptions);
+ }
+
+ var self = this
+ , defaultArr
+ , fn;
+
+ if (this.defaultValue) {
+ defaultArr = this.defaultValue;
+ fn = 'function' == typeof defaultArr;
+ }
+
+ this.default(function(){
+ var arr = fn ? defaultArr() : defaultArr || [];
+ return new MongooseArray(arr, self.path, this);
+ });
+};
+
+/**
+ * Inherits from SchemaType.
+ */
+
+SchemaArray.prototype.__proto__ = SchemaType.prototype;
+
+/**
+ * Check required
+ *
+ * @api private
+ */
+
+SchemaArray.prototype.checkRequired = function (value) {
+ return !!(value && value.length);
+};
+
+/**
+ * Overrides the getters application for the population special-case
+ * TODO: implement this in SchemaObjectIdArray
+ *
+ * @param {Object} value
+ * @param {Object} scope
+ * @api private
+ */
+
+SchemaArray.prototype.applyGetters = function (value, scope) {
+ if (this.caster.options && this.caster.options.ref) {
+ // means the object id was populated
+ return value;
+ }
+
+ return SchemaType.prototype.applyGetters.call(this, value, scope);
+};
+
+/**
+ * Casts contents
+ *
+ * @param {Object} value
+ * @param {Document} document that triggers the casting
+ * @param {Boolean} whether this is an initialization cast
+ * @api private
+ */
+
+SchemaArray.prototype.cast = function (value, doc, init) {
+ if (Array.isArray(value)) {
+ if (!(value instanceof MongooseArray)) {
+ value = new MongooseArray(value, this.path, doc);
+ }
+
+ if (this.caster) {
+ try {
+ for (var i = 0, l = value.length; i < l; i++) {
+ value[i] = this.caster.cast(value[i], doc, init);
+ }
+ } catch (e) {
+ // rethrow
+ throw new CastError(e.type, value);
+ }
+ }
+
+ return value;
+ } else {
+ return this.cast([value], doc, init);
+ }
+};
+
+SchemaArray.prototype.castForQuery = function ($conditional, val) {
+ var handler;
+ if (arguments.length === 2) {
+ handler = this.$conditionalHandlers[$conditional];
+ if (!handler)
+ throw new Error("Can't use " + $conditional + " with Array.");
+ val = handler.call(this, val);
+ } else {
+ val = $conditional;
+ var proto = this.casterConstructor.prototype;
+ var method = proto.castForQuery || proto.cast;
+ if (Array.isArray(val)) {
+ val = val.map(function (v) {
+ if (method) v = method.call(proto, v);
+ return isMongooseObject(v)
+ ? v.toObject()
+ : v;
+ });
+ } else if (method) {
+ val = method.call(proto, val);
+ }
+ }
+ return val && isMongooseObject(val)
+ ? val.toObject()
+ : val;
+};
+
+SchemaArray.prototype.$conditionalHandlers = {
+ '$all': function handle$all (val) {
+ if (!Array.isArray(val)) {
+ val = [val];
+ }
+
+ val = val.map(function (v) {
+ if (v && 'Object' === v.constructor.name) {
+ var o = {};
+ o[this.path] = v;
+ var query = new Query(o);
+ query.cast(this.casterConstructor);
+ return query._conditions[this.path];
+ }
+ return v;
+ }, this);
+
+ return this.castForQuery(val);
+ }
+ , '$elemMatch': function (val) {
+ var query = new Query(val);
+ query.cast(this.casterConstructor);
+ return query._conditions;
+ }
+ , '$size': function (val) {
+ return ArrayNumberSchema.prototype.cast.call(this, val);
+ }
+ , '$ne': SchemaArray.prototype.castForQuery
+ , '$in': SchemaArray.prototype.castForQuery
+ , '$nin': SchemaArray.prototype.castForQuery
+ , '$regex': SchemaArray.prototype.castForQuery
+ , '$near': SchemaArray.prototype.castForQuery
+ , '$nearSphere': SchemaArray.prototype.castForQuery
+ , '$within': function(val) {
+ var query = new Query(val);
+ query.cast(this.casterConstructor)
+ return query._conditions;
+ }
+ , '$maxDistance': function (val) {
+ return ArrayNumberSchema.prototype.cast.call(this, val);
+ }
+};
+
+/**
+ * Number casting for arrays (equivalent, but without MongoseNumber)
+ *
+ * @see GH-176
+ * @param {Object} value
+ * @api private
+ */
+
+// subclass number schema to override casting
+// to disallow non-numbers being saved
+function ArrayNumberSchema (key, options) {
+ NumberSchema.call(this, key, options);
+}
+
+ArrayNumberSchema.prototype.__proto__ = NumberSchema.prototype;
+
+ArrayNumberSchema.prototype.cast = function (value) {
+ if (!isNaN(value)) {
+ if (value instanceof Number || typeof value == 'number' ||
+ (value.toString && value.toString() == Number(value)))
+ return Number(value);
+ }
+
+ throw new CastError('number', value);
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = SchemaArray;
diff --git a/node_modules/mongoose/lib/schema/boolean.js b/node_modules/mongoose/lib/schema/boolean.js
new file mode 100644
index 0000000..574fdd8
--- /dev/null
+++ b/node_modules/mongoose/lib/schema/boolean.js
@@ -0,0 +1,59 @@
+
+/**
+ * Module dependencies.
+ */
+
+var SchemaType = require('../schematype');
+
+/**
+ * Boolean SchemaType constructor.
+ *
+ * @param {String} path
+ * @param {Object} options
+ * @api private
+ */
+
+function SchemaBoolean (path, options) {
+ SchemaType.call(this, path, options);
+};
+
+/**
+ * Inherits from SchemaType.
+ */
+SchemaBoolean.prototype.__proto__ = SchemaType.prototype;
+
+/**
+ * Required validator for date
+ *
+ * @api private
+ */
+
+SchemaBoolean.prototype.checkRequired = function (value) {
+ return value === true || value === false;
+};
+
+/**
+ * Casts to boolean
+ *
+ * @param {Object} value to cast
+ * @api private
+ */
+
+SchemaBoolean.prototype.cast = function (value) {
+ if (value === null) return value;
+ if (value === '0') return false;
+ return !!value;
+};
+
+SchemaBoolean.prototype.castForQuery = function ($conditional, val) {
+ if (arguments.length === 1) {
+ val = $conditional;
+ }
+ return this.cast(val);
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = SchemaBoolean;
diff --git a/node_modules/mongoose/lib/schema/buffer.js b/node_modules/mongoose/lib/schema/buffer.js
new file mode 100644
index 0000000..64e12a2
--- /dev/null
+++ b/node_modules/mongoose/lib/schema/buffer.js
@@ -0,0 +1,106 @@
+/**
+ * Module dependencies.
+ */
+
+var SchemaType = require('../schematype')
+ , CastError = SchemaType.CastError
+ , BufferNumberSchema = function () {}
+ , MongooseBuffer = require('../types').Buffer
+ , Binary = MongooseBuffer.Binary
+ , Query = require('../query');
+
+/**
+ * Buffer SchemaType constructor
+ *
+ * @param {String} key
+ * @param {SchemaType} cast
+ * @api private
+ */
+
+function SchemaBuffer (key, options) {
+ SchemaType.call(this, key, options, 'Buffer');
+};
+
+/**
+ * Inherits from SchemaType.
+ */
+
+SchemaBuffer.prototype.__proto__ = SchemaType.prototype;
+
+/**
+ * Check required
+ *
+ * @api private
+ */
+
+SchemaBuffer.prototype.checkRequired = function (value) {
+ return !!(value && value.length);
+};
+
+/**
+ * Casts contents
+ *
+ * @param {Object} value
+ * @param {Document} document that triggers the casting
+ * @api private
+ */
+
+SchemaBuffer.prototype.cast = function (value, doc, init) {
+ if (SchemaType._isRef(this, value, init)) return value;
+
+ if (Buffer.isBuffer(value)) {
+ if (!(value instanceof MongooseBuffer)) {
+ value = new MongooseBuffer(value, [this.path, doc]);
+ }
+
+ return value;
+ } else if (value instanceof Binary) {
+ return new MongooseBuffer(value.value(true), [this.path, doc]);
+ }
+
+ if ('string' === typeof value || Array.isArray(value)) {
+ return new MongooseBuffer(value, [this.path, doc]);
+ }
+
+ throw new CastError('buffer', value);
+};
+
+function handleSingle (val) {
+ return this.castForQuery(val);
+}
+
+function handleArray (val) {
+ var self = this;
+ return val.map( function (m) {
+ return self.castForQuery(m);
+ });
+}
+
+SchemaBuffer.prototype.$conditionalHandlers = {
+ '$ne' : handleSingle
+ , '$in' : handleArray
+ , '$nin': handleArray
+ , '$gt' : handleSingle
+ , '$lt' : handleSingle
+ , '$gte': handleSingle
+ , '$lte': handleSingle
+};
+
+SchemaBuffer.prototype.castForQuery = function ($conditional, val) {
+ var handler;
+ if (arguments.length === 2) {
+ handler = this.$conditionalHandlers[$conditional];
+ if (!handler)
+ throw new Error("Can't use " + $conditional + " with Buffer.");
+ return handler.call(this, val);
+ } else {
+ val = $conditional;
+ return this.cast(val).toObject();
+ }
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = SchemaBuffer;
diff --git a/node_modules/mongoose/lib/schema/date.js b/node_modules/mongoose/lib/schema/date.js
new file mode 100644
index 0000000..3a7bda8
--- /dev/null
+++ b/node_modules/mongoose/lib/schema/date.js
@@ -0,0 +1,116 @@
+
+/**
+ * Module requirements.
+ */
+
+var SchemaType = require('../schematype')
+ , CastError = SchemaType.CastError;
+
+/**
+ * Date SchemaType constructor.
+ *
+ * @param {String} key
+ * @param {Object} options
+ * @api private
+ */
+
+function SchemaDate (key, options) {
+ SchemaType.call(this, key, options);
+};
+
+/**
+ * Inherits from SchemaType.
+ */
+
+SchemaDate.prototype.__proto__ = SchemaType.prototype;
+
+/**
+ * Required validator for date
+ *
+ * @api private
+ */
+
+SchemaDate.prototype.checkRequired = function (value) {
+ return value instanceof Date;
+};
+
+/**
+ * Casts to date
+ *
+ * @param {Object} value to cast
+ * @api private
+ */
+
+SchemaDate.prototype.cast = function (value) {
+ if (value === null || value === '')
+ return null;
+
+ if (value instanceof Date)
+ return value;
+
+ var date;
+
+ // support for timestamps
+ if (value instanceof Number || 'number' == typeof value
+ || String(value) == Number(value))
+ date = new Date(Number(value));
+
+ // support for date strings
+ else if (value.toString)
+ date = new Date(value.toString());
+
+ if (date.toString() != 'Invalid Date')
+ return date;
+
+ throw new CastError('date', value);
+};
+
+/**
+ * Date Query casting.
+ *
+ * @api private
+ */
+
+function handleSingle (val) {
+ return this.cast(val);
+}
+
+function handleArray (val) {
+ var self = this;
+ return val.map( function (m) {
+ return self.cast(m);
+ });
+}
+
+SchemaDate.prototype.$conditionalHandlers = {
+ '$lt': handleSingle
+ , '$lte': handleSingle
+ , '$gt': handleSingle
+ , '$gte': handleSingle
+ , '$ne': handleSingle
+ , '$in': handleArray
+ , '$nin': handleArray
+ , '$all': handleArray
+};
+
+SchemaDate.prototype.castForQuery = function ($conditional, val) {
+ var handler;
+
+ if (2 !== arguments.length) {
+ return this.cast($conditional);
+ }
+
+ handler = this.$conditionalHandlers[$conditional];
+
+ if (!handler) {
+ throw new Error("Can't use " + $conditional + " with Date.");
+ }
+
+ return handler.call(this, val);
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = SchemaDate;
diff --git a/node_modules/mongoose/lib/schema/documentarray.js b/node_modules/mongoose/lib/schema/documentarray.js
new file mode 100644
index 0000000..38276ff
--- /dev/null
+++ b/node_modules/mongoose/lib/schema/documentarray.js
@@ -0,0 +1,141 @@
+
+/**
+ * Module dependencies.
+ */
+
+var SchemaType = require('../schematype')
+ , ArrayType = require('./array')
+ , MongooseDocumentArray = require('../types/documentarray')
+ , Subdocument = require('../types/embedded')
+ , CastError = SchemaType.CastError
+ , Document = require('../document');
+
+/**
+ * SubdocsArray SchemaType constructor
+ *
+ * @param {String} key
+ * @param {Schema} schema
+ * @param {Object} options
+ * @api private
+ */
+
+function DocumentArray (key, schema, options) {
+ // compile an embedded document for this schema
+ // TODO Move this into parent model compilation for performance improvement?
+ function EmbeddedDocument () {
+ Subdocument.apply(this, arguments);
+ };
+
+ EmbeddedDocument.prototype.__proto__ = Subdocument.prototype;
+ EmbeddedDocument.prototype.schema = schema;
+ EmbeddedDocument.schema = schema;
+
+ // apply methods
+ for (var i in schema.methods) {
+ EmbeddedDocument.prototype[i] = schema.methods[i];
+ }
+
+ // apply statics
+ for (var i in schema.statics)
+ EmbeddedDocument[i] = schema.statics[i];
+
+ ArrayType.call(this, key, EmbeddedDocument, options);
+
+ this.caster = EmbeddedDocument;
+ this.caster.options = options;
+
+ var self = this;
+
+ this.schema = schema;
+ this.default(function(){
+ return new MongooseDocumentArray([], self.path, this);
+ });
+};
+
+/**
+ * Inherits from ArrayType.
+ */
+
+DocumentArray.prototype.__proto__ = ArrayType.prototype;
+
+/**
+ * Performs local validations first, then validations on each embedded doc
+ *
+ * @api private
+ */
+
+DocumentArray.prototype.doValidate = function (array, fn, scope) {
+ var self = this;
+ SchemaType.prototype.doValidate.call(this, array, function(err){
+ if (err) return fn(err);
+
+ var count = array && array.length
+ , error = false;
+
+ if (!count) return fn();
+
+ array.forEach(function(doc, index){
+ doc.validate(function(err){
+ if (err && !error){
+ // rewrite they key
+ err.key = self.key + '.' + index + '.' + err.key;
+ fn(err);
+ error = true;
+ } else {
+ --count || fn();
+ }
+ });
+ });
+ }, scope);
+};
+
+/**
+ * Casts contents
+ *
+ * @param {Object} value
+ * @param {Document} document that triggers the casting
+ * @api private
+ */
+
+DocumentArray.prototype.cast = function (value, doc, init, prev) {
+ var subdoc
+ , i
+
+ if (Array.isArray(value)) {
+ if (!(value instanceof MongooseDocumentArray)) {
+ value = new MongooseDocumentArray(value, this.path, doc);
+ }
+
+ i = value.length;
+
+ while (i--) {
+ if (!(value[i] instanceof Subdocument)) {
+ if (init) {
+ subdoc = new this.caster(null, value);
+ // skip _id for pre-init hooks
+ delete subdoc._doc._id;
+ value[i] = subdoc.init(value[i]);
+ } else {
+ subdoc = prev && prev.id(value[i]._id) ||
+ new this.caster(null, value);
+ subdoc.set(value[i]);
+ // if set() is hooked it will have no return value
+ // see gh-746
+ value[i] = subdoc;
+ }
+ }
+ }
+
+ return value;
+ } else {
+ return this.cast([value], doc, init, prev);
+ }
+
+ throw new CastError('documentarray', value);
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = DocumentArray;
diff --git a/node_modules/mongoose/lib/schema/index.js b/node_modules/mongoose/lib/schema/index.js
new file mode 100644
index 0000000..ac424c3
--- /dev/null
+++ b/node_modules/mongoose/lib/schema/index.js
@@ -0,0 +1,22 @@
+
+/**
+ * Module exports.
+ */
+
+exports.String = require('./string');
+
+exports.Number = require('./number');
+
+exports.Boolean = require('./boolean');
+
+exports.DocumentArray = require('./documentarray');
+
+exports.Array = require('./array');
+
+exports.Buffer = require('./buffer');
+
+exports.Date = require('./date');
+
+exports.ObjectId = require('./objectid');
+
+exports.Mixed = require('./mixed');
diff --git a/node_modules/mongoose/lib/schema/mixed.js b/node_modules/mongoose/lib/schema/mixed.js
new file mode 100644
index 0000000..6f98be0
--- /dev/null
+++ b/node_modules/mongoose/lib/schema/mixed.js
@@ -0,0 +1,63 @@
+
+/**
+ * Module dependencies.
+ */
+
+var SchemaType = require('../schematype');
+
+/**
+ * Mixed SchemaType constructor.
+ *
+ * @param {String} path
+ * @param {Object} options
+ * @api private
+ */
+
+function Mixed (path, options) {
+ // make sure empty array defaults are handled
+ if (options &&
+ options.default &&
+ Array.isArray(options.default) &&
+ 0 === options.default.length) {
+ options.default = Array;
+ }
+
+ SchemaType.call(this, path, options);
+};
+
+/**
+ * Inherits from SchemaType.
+ */
+Mixed.prototype.__proto__ = SchemaType.prototype;
+
+/**
+ * Required validator for mixed type
+ *
+ * @api private
+ */
+
+Mixed.prototype.checkRequired = function (val) {
+ return true;
+};
+
+/**
+ * Noop casting
+ *
+ * @param {Object} value to cast
+ * @api private
+ */
+
+Mixed.prototype.cast = function (val) {
+ return val;
+};
+
+Mixed.prototype.castForQuery = function ($cond, val) {
+ if (arguments.length === 2) return val;
+ return $cond;
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = Mixed;
diff --git a/node_modules/mongoose/lib/schema/number.js b/node_modules/mongoose/lib/schema/number.js
new file mode 100644
index 0000000..75a14f6
--- /dev/null
+++ b/node_modules/mongoose/lib/schema/number.js
@@ -0,0 +1,142 @@
+/**
+ * Module requirements.
+ */
+
+var SchemaType = require('../schematype')
+ , CastError = SchemaType.CastError
+ , MongooseNumber = require('../types/number');
+
+/**
+ * Number SchemaType constructor.
+ *
+ * @param {String} key
+ * @param {Object} options
+ * @api private
+ */
+
+function SchemaNumber (key, options) {
+ SchemaType.call(this, key, options, 'Number');
+};
+
+/**
+ * Inherits from SchemaType.
+ */
+
+SchemaNumber.prototype.__proto__ = SchemaType.prototype;
+
+/**
+ * Required validator for number
+ *
+ * @api private
+ */
+
+SchemaNumber.prototype.checkRequired = function checkRequired (value) {
+ if (SchemaType._isRef(this, value, true)) {
+ return null != value;
+ } else {
+ return typeof value == 'number' || value instanceof Number;
+ }
+};
+
+/**
+ * Sets a maximum number validator
+ *
+ * @param {Number} minimum number
+ * @api public
+ */
+
+SchemaNumber.prototype.min = function (value, message) {
+ if (this.minValidator)
+ this.validators = this.validators.filter(function(v){
+ return v[1] != 'min';
+ });
+ if (value != null)
+ this.validators.push([function(v){
+ return v === null || v >= value;
+ }, 'min']);
+ return this;
+};
+
+/**
+ * Sets a maximum number validator
+ *
+ * @param {Number} maximum number
+ * @api public
+ */
+
+SchemaNumber.prototype.max = function (value, message) {
+ if (this.maxValidator)
+ this.validators = this.validators.filter(function(v){
+ return v[1] != 'max';
+ });
+ if (value != null)
+ this.validators.push([this.maxValidator = function(v){
+ return v === null || v <= value;
+ }, 'max']);
+ return this;
+};
+
+/**
+ * Casts to number
+ *
+ * @param {Object} value to cast
+ * @param {Document} document that triggers the casting
+ * @api private
+ */
+
+SchemaNumber.prototype.cast = function (value, doc, init) {
+ if (SchemaType._isRef(this, value, init)) return value;
+
+ if (!isNaN(value)){
+ if (null === value) return value;
+ if ('' === value) return null;
+ if ('string' === typeof value) value = Number(value);
+ if (value instanceof Number || typeof value == 'number' ||
+ (value.toString && value.toString() == Number(value)))
+ return new MongooseNumber(value, this.path, doc);
+ }
+
+ throw new CastError('number', value);
+};
+
+function handleSingle (val) {
+ return this.cast(val).valueOf();
+}
+
+function handleArray (val) {
+ var self = this;
+ return val.map( function (m) {
+ return self.cast(m).valueOf();
+ });
+}
+
+SchemaNumber.prototype.$conditionalHandlers = {
+ '$lt' : handleSingle
+ , '$lte': handleSingle
+ , '$gt' : handleSingle
+ , '$gte': handleSingle
+ , '$ne' : handleSingle
+ , '$in' : handleArray
+ , '$nin': handleArray
+ , '$mod': handleArray
+ , '$all': handleArray
+};
+
+SchemaNumber.prototype.castForQuery = function ($conditional, val) {
+ var handler;
+ if (arguments.length === 2) {
+ handler = this.$conditionalHandlers[$conditional];
+ if (!handler)
+ throw new Error("Can't use " + $conditional + " with Number.");
+ return handler.call(this, val);
+ } else {
+ val = this.cast($conditional);
+ return val == null ? val : val.valueOf();
+ }
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = SchemaNumber;
diff --git a/node_modules/mongoose/lib/schema/objectid.js b/node_modules/mongoose/lib/schema/objectid.js
new file mode 100644
index 0000000..a83f95d
--- /dev/null
+++ b/node_modules/mongoose/lib/schema/objectid.js
@@ -0,0 +1,126 @@
+/**
+ * Module dependencies.
+ */
+
+var SchemaType = require('../schematype')
+ , CastError = SchemaType.CastError
+ , driver = global.MONGOOSE_DRIVER_PATH || './../drivers/node-mongodb-native'
+ , oid = require('../types/objectid');
+
+
+/**
+ * ObjectId SchemaType constructor.
+ *
+ * @param {String} key
+ * @param {Object} options
+ * @api private
+ */
+
+function ObjectId (key, options) {
+ SchemaType.call(this, key, options, 'ObjectID');
+};
+
+/**
+ * Inherits from SchemaType.
+ */
+
+ObjectId.prototype.__proto__ = SchemaType.prototype;
+
+/**
+ * Check required
+ *
+ * @api private
+ */
+
+ObjectId.prototype.checkRequired = function checkRequired (value) {
+ if (SchemaType._isRef(this, value, true)) {
+ return null != value;
+ } else {
+ return value instanceof oid;
+ }
+};
+
+/**
+ * Casts to ObjectId
+ *
+ * @param {Object} value
+ * @param {Object} scope
+ * @param {Boolean} whether this is an initialization cast
+ * @api private
+ */
+
+ObjectId.prototype.cast = function (value, scope, init) {
+ if (SchemaType._isRef(this, value, init)) return value;
+
+ if (value === null) return value;
+
+ if (value instanceof oid)
+ return value;
+
+ if (value._id && value._id instanceof oid)
+ return value._id;
+
+ if (value.toString)
+ return oid.fromString(value.toString());
+
+ throw new CastError('object id', value);
+};
+
+function handleSingle (val) {
+ return this.cast(val);
+}
+
+function handleArray (val) {
+ var self = this;
+ return val.map(function (m) {
+ return self.cast(m);
+ });
+}
+
+ObjectId.prototype.$conditionalHandlers = {
+ '$ne': handleSingle
+ , '$in': handleArray
+ , '$nin': handleArray
+ , '$gt': handleSingle
+ , '$lt': handleSingle
+ , '$gte': handleSingle
+ , '$lte': handleSingle
+ , '$all': handleArray
+};
+
+ObjectId.prototype.castForQuery = function ($conditional, val) {
+ var handler;
+ if (arguments.length === 2) {
+ handler = this.$conditionalHandlers[$conditional];
+ if (!handler)
+ throw new Error("Can't use " + $conditional + " with ObjectId.");
+ return handler.call(this, val);
+ } else {
+ val = $conditional;
+ return this.cast(val);
+ }
+};
+
+/**
+ * Adds an auto-generated ObjectId default if turnOn is true.
+ * @param {Boolean} turnOn auto generated ObjectId defaults
+ * @api private
+ */
+
+ObjectId.prototype.auto = function (turnOn) {
+ if (turnOn) {
+ this.default(function(){
+ return new oid();
+ });
+ this.set(function (v) {
+ this.__id = null;
+ return v;
+ })
+ }
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = ObjectId;
diff --git a/node_modules/mongoose/lib/schema/string.js b/node_modules/mongoose/lib/schema/string.js
new file mode 100644
index 0000000..5187e4f
--- /dev/null
+++ b/node_modules/mongoose/lib/schema/string.js
@@ -0,0 +1,180 @@
+
+/**
+ * Module dependencies.
+ */
+
+var SchemaType = require('../schematype')
+ , CastError = SchemaType.CastError;
+
+/**
+ * String SchemaType constructor.
+ *
+ * @param {String} key
+ * @api private
+ */
+
+function SchemaString (key, options) {
+ this.enumValues = [];
+ this.regExp = null;
+ SchemaType.call(this, key, options, 'String');
+};
+
+/**
+ * Inherits from SchemaType.
+ */
+
+SchemaString.prototype.__proto__ = SchemaType.prototype;
+
+/**
+ * Adds enumeration values
+ *
+ * @param {multiple} enumeration values
+ * @api public
+ */
+
+SchemaString.prototype.enum = function () {
+ var len = arguments.length;
+ if (!len || undefined === arguments[0] || false === arguments[0]) {
+ if (this.enumValidator){
+ this.enumValidator = false;
+ this.validators = this.validators.filter(function(v){
+ return v[1] != 'enum';
+ });
+ }
+ return;
+ }
+
+ for (var i = 0; i < len; i++) {
+ if (undefined !== arguments[i]) {
+ this.enumValues.push(this.cast(arguments[i]));
+ }
+ }
+
+ if (!this.enumValidator) {
+ var values = this.enumValues;
+ this.enumValidator = function(v){
+ return ~values.indexOf(v);
+ };
+ this.validators.push([this.enumValidator, 'enum']);
+ }
+};
+
+/**
+ * Adds a lowercase setter
+ *
+ * @api public
+ */
+
+SchemaString.prototype.lowercase = function () {
+ return this.set(function (v) {
+ return v.toLowerCase();
+ });
+};
+
+/**
+ * Adds an uppercase setter
+ *
+ * @api public
+ */
+
+SchemaString.prototype.uppercase = function () {
+ return this.set(function (v) {
+ return v.toUpperCase();
+ });
+};
+
+/**
+ * Adds a trim setter
+ *
+ * @api public
+ */
+
+SchemaString.prototype.trim = function () {
+ return this.set(function (v) {
+ return v.trim();
+ });
+};
+
+/**
+ * Sets a regexp test
+ *
+ * @param {RegExp} regular expression to test against
+ * @param {String} optional validator message
+ * @api public
+ */
+
+SchemaString.prototype.match = function(regExp){
+ this.validators.push([function(v){
+ return regExp.test(v);
+ }, 'regexp']);
+};
+
+/**
+ * Check required
+ *
+ * @api private
+ */
+
+SchemaString.prototype.checkRequired = function checkRequired (value) {
+ if (SchemaType._isRef(this, value, true)) {
+ return null != value;
+ } else {
+ return (value instanceof String || typeof value == 'string') && value.length;
+ }
+};
+
+/**
+ * Casts to String
+ *
+ * @api private
+ */
+
+SchemaString.prototype.cast = function (value, scope, init) {
+ if (SchemaType._isRef(this, value, init)) return value;
+ if (value === null) return value;
+ if ('undefined' !== typeof value && value.toString) return value.toString();
+ throw new CastError('string', value);
+};
+
+function handleSingle (val) {
+ return this.castForQuery(val);
+}
+
+function handleArray (val) {
+ var self = this;
+ return val.map(function (m) {
+ return self.castForQuery(m);
+ });
+}
+
+SchemaString.prototype.$conditionalHandlers = {
+ '$ne' : handleSingle
+ , '$in' : handleArray
+ , '$nin': handleArray
+ , '$gt' : handleSingle
+ , '$lt' : handleSingle
+ , '$gte': handleSingle
+ , '$lte': handleSingle
+ , '$all': handleArray
+ , '$regex': handleSingle
+};
+
+SchemaString.prototype.castForQuery = function ($conditional, val) {
+ var handler;
+ if (arguments.length === 2) {
+ handler = this.$conditionalHandlers[$conditional];
+ if (!handler)
+ throw new Error("Can't use " + $conditional + " with String.");
+ return handler.call(this, val);
+ } else {
+ val = $conditional;
+ if (val instanceof RegExp) return val;
+ return this.cast(val);
+ }
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = SchemaString;
diff --git a/node_modules/mongoose/lib/schemadefault.js b/node_modules/mongoose/lib/schemadefault.js
new file mode 100644
index 0000000..a468c85
--- /dev/null
+++ b/node_modules/mongoose/lib/schemadefault.js
@@ -0,0 +1,32 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Schema = require('./schema')
+
+/**
+ * Default model for querying the system.profiles
+ * collection (it only exists when profiling is
+ * enabled.
+ */
+
+exports['system.profile'] = new Schema({
+ ts: Date
+ , info: String // deprecated
+ , millis: Number
+ , op: String
+ , ns: String
+ , query: Schema.Types.Mixed
+ , updateobj: Schema.Types.Mixed
+ , ntoreturn: Number
+ , nreturned: Number
+ , nscanned: Number
+ , responseLength: Number
+ , client: String
+ , user: String
+ , idhack: Boolean
+ , scanAndOrder: Boolean
+ , keyUpdates: Number
+ , cursorid: Number
+}, { noVirtualId: true, noId: true });
diff --git a/node_modules/mongoose/lib/schematype.js b/node_modules/mongoose/lib/schematype.js
new file mode 100644
index 0000000..f2accb6
--- /dev/null
+++ b/node_modules/mongoose/lib/schematype.js
@@ -0,0 +1,428 @@
+/**
+ * Module dependencies.
+ */
+
+var MongooseError = require('./error');
+var utils = require('./utils');
+
+/**
+ * SchemaType constructor
+ *
+ * @param {String} path
+ * @api public
+ */
+
+function SchemaType (path, options, instance) {
+ this.path = path;
+ this.instance = instance;
+ this.validators = [];
+ this.setters = [];
+ this.getters = [];
+ this.options = options;
+ this._index = null;
+ this.selected;
+
+ for (var i in options) if (this[i] && 'function' == typeof this[i]) {
+ var opts = Array.isArray(options[i])
+ ? options[i]
+ : [options[i]];
+
+ this[i].apply(this, opts);
+ }
+};
+
+/**
+ * Base schema. Set by Schema when instantiated.
+ *
+ * @api private
+ */
+
+SchemaType.prototype.base;
+
+/**
+ * Sets a default
+ *
+ * @param {Object} default value
+ * @api public
+ */
+
+SchemaType.prototype.default = function (val) {
+ if (1 === arguments.length) {
+ this.defaultValue = typeof val === 'function'
+ ? val
+ : this.cast(val);
+ return this;
+ } else if (arguments.length > 1) {
+ this.defaultValue = utils.args(arguments);
+ }
+ return this.defaultValue;
+};
+
+/**
+ * Sets index. It can be a boolean or a hash of options
+ * Example:
+ * Schema.path('my.path').index(true);
+ * Schema.path('my.path').index({ unique: true });
+ *
+ * "Direction doesn't matter for single key indexes"
+ * http://www.mongodb.org/display/DOCS/Indexes#Indexes-CompoundKeysIndexes
+ *
+ * @param {Object} true/
+ * @api public
+ */
+
+SchemaType.prototype.index = function (index) {
+ this._index = index;
+ return this;
+};
+
+/**
+ * Adds an unique index
+ *
+ * @param {Boolean}
+ * @api private
+ */
+
+SchemaType.prototype.unique = function (bool) {
+ if (!this._index || 'Object' !== this._index.constructor.name) {
+ this._index = {};
+ }
+
+ this._index.unique = bool;
+ return this;
+};
+
+/**
+ * Adds an unique index
+ *
+ * @param {Boolean}
+ * @api private
+ */
+
+SchemaType.prototype.sparse = function (bool) {
+ if (!this._index || 'Object' !== this._index.constructor.name) {
+ this._index = {};
+ }
+
+ this._index.sparse = bool;
+ return this;
+};
+
+/**
+ * Adds a setter
+ *
+ * @param {Function} setter
+ * @api public
+ */
+
+SchemaType.prototype.set = function (fn) {
+ if ('function' != typeof fn)
+ throw new Error('A setter must be a function.');
+ this.setters.push(fn);
+ return this;
+};
+
+/**
+ * Adds a getter
+ *
+ * @param {Function} getter
+ * @api public
+ */
+
+SchemaType.prototype.get = function (fn) {
+ if ('function' != typeof fn)
+ throw new Error('A getter must be a function.');
+ this.getters.push(fn);
+ return this;
+};
+
+/**
+ * ##validate
+ *
+ * Adds validators.
+ *
+ * Examples:
+ *
+ * function validator () { ... }
+ *
+ * var single = [validator, 'failed']
+ * new Schema({ name: { type: String, validate: single }});
+ *
+ * var many = [
+ * { validator: validator, msg: 'uh oh' }
+ * , { validator: fn, msg: 'failed' }
+ * ]
+ * new Schema({ name: { type: String, validate: many }});
+ *
+ * @param {Object} validator
+ * @param {String} optional error message
+ * @api public
+ */
+
+SchemaType.prototype.validate = function (obj, error) {
+ if ('function' == typeof obj || obj && 'RegExp' === obj.constructor.name) {
+ this.validators.push([obj, error]);
+ return this;
+ }
+
+ var i = arguments.length
+ , arg
+
+ while (i--) {
+ arg = arguments[i];
+ this.validators.push([arg.validator, arg.msg]);
+ }
+
+ return this;
+};
+
+/**
+ * Adds a required validator
+ *
+ * @param {Boolean} enable/disable the validator
+ * @api public
+ */
+
+SchemaType.prototype.required = function (required) {
+ var self = this;
+
+ function __checkRequired (v) {
+ // in here, `this` refers to the validating document.
+ // no validation when this path wasn't selected in the query.
+ if ('isSelected' in this &&
+ !this.isSelected(self.path) &&
+ !this.isModified(self.path)) return true;
+ return self.checkRequired(v);
+ }
+
+ if (false === required) {
+ this.isRequired = false;
+ this.validators = this.validators.filter(function (v) {
+ return v[0].name !== '__checkRequired';
+ });
+ } else {
+ this.isRequired = true;
+ this.validators.push([__checkRequired, 'required']);
+ }
+
+ return this;
+};
+
+/**
+ * Gets the default value
+ *
+ * @param {Object} scope for callback defaults
+ * @api private
+ */
+
+SchemaType.prototype.getDefault = function (scope) {
+ var ret = 'function' === typeof this.defaultValue
+ ? this.defaultValue.call(scope)
+ : this.defaultValue;
+
+ if (null !== ret && undefined !== ret) {
+ return this.cast(ret, scope);
+ } else {
+ return ret;
+ }
+};
+
+/**
+ * Applies setters
+ *
+ * @param {Object} value
+ * @param {Object} scope
+ * @api private
+ */
+
+SchemaType.prototype.applySetters = function (value, scope, init) {
+ if (SchemaType._isRef(this, value, init)) return value;
+
+ var v = value
+ , setters = this.setters
+ , len = setters.length;
+
+ for (var k = len - 1; k >= 0; k--) {
+ v = setters[k].call(scope, v, this);
+ if (null === v || undefined === v) return v;
+ v = this.cast(v, scope);
+ }
+
+ if (!len) {
+ if (null === v || undefined === v) return v;
+ if (!init) {
+ // if we just initialized we dont recast
+ v = this.cast(v, scope, init);
+ }
+ }
+
+ return v;
+};
+
+/**
+ * Applies getters to a value
+ *
+ * @param {Object} value
+ * @param {Object} scope
+ * @api private
+ */
+
+SchemaType.prototype.applyGetters = function (value, scope) {
+ if (SchemaType._isRef(this, value, true)) return value;
+
+ var v = value
+ , getters = this.getters
+ , len = getters.length;
+
+ for (var k = len - 1; k >= 0; k--) {
+ v = this.getters[k].call(scope, v, this);
+ if (null === v || undefined === v) return v;
+ v = this.cast(v, scope);
+ }
+
+ if (!len) {
+ if (null === v || undefined === v) return v;
+ v = this.cast(v, scope);
+ }
+
+ return v;
+};
+
+/**
+ * ## select
+ *
+ * Set default select() behavior for this path. True if
+ * this path should always be included in the results,
+ * false if it should be excluded by default. This setting
+ * can be overridden at the query level.
+ *
+ * T = db.model('T', new Schema({ x: { type: String, select: true }}));
+ * T.find(..); // x will always be selected ..
+ * // .. unless overridden;
+ * T.find().select({ x: 0 }).exec();
+ */
+
+SchemaType.prototype.select = function select (val) {
+ this.selected = !! val;
+}
+
+/**
+ * Performs a validation
+ *
+ * @param {Function} callback
+ * @param {Object} scope
+ * @api private
+ */
+
+SchemaType.prototype.doValidate = function (value, fn, scope) {
+ var err = false
+ , path = this.path
+ , count = this.validators.length;
+
+ if (!count) return fn(null);
+
+ function validate (val, msg) {
+ if (err) return;
+ if (val === undefined || val) {
+ --count || fn(null);
+ } else {
+ fn(err = new ValidatorError(path, msg));
+ }
+ }
+
+ this.validators.forEach(function (v) {
+ var validator = v[0]
+ , message = v[1];
+
+ if (validator instanceof RegExp) {
+ validate(validator.test(value), message);
+ } else if ('function' === typeof validator) {
+ if (2 === validator.length) {
+ validator.call(scope, value, function (val) {
+ validate(val, message);
+ });
+ } else {
+ validate(validator.call(scope, value), message);
+ }
+ }
+ });
+};
+
+/**
+ * Determines if value is a valid Reference.
+ *
+ * @param {SchemaType} self
+ * @param {object} value
+ * @param {Boolean} init
+ * @param {MongooseType} instance
+ * @return Boolean
+ * @private
+ */
+
+SchemaType._isRef = function (self, value, init) {
+ if (self.options && self.options.ref && init) {
+ if (null == value) return true;
+ if (value._id && value._id.constructor.name === self.instance) return true;
+ }
+
+ return false;
+}
+
+/**
+ * Schema validator error
+ *
+ * @param {String} path
+ * @param {String} msg
+ * @api private
+ */
+
+function ValidatorError (path, type) {
+ var msg = type
+ ? '"' + type + '" '
+ : '';
+ MongooseError.call(this, 'Validator ' + msg + 'failed for path ' + path);
+ Error.captureStackTrace(this, arguments.callee);
+ this.name = 'ValidatorError';
+ this.path = path;
+ this.type = type;
+};
+
+ValidatorError.prototype.toString = function () {
+ return this.message;
+}
+
+/**
+ * Inherits from MongooseError
+ */
+
+ValidatorError.prototype.__proto__ = MongooseError.prototype;
+
+/**
+ * Cast error
+ *
+ * @api private
+ */
+
+function CastError (type, value) {
+ MongooseError.call(this, 'Cast to ' + type + ' failed for value "' + value + '"');
+ Error.captureStackTrace(this, arguments.callee);
+ this.name = 'CastError';
+ this.type = type;
+ this.value = value;
+};
+
+/**
+ * Inherits from MongooseError.
+ */
+
+CastError.prototype.__proto__ = MongooseError.prototype;
+
+/**
+ * Module exports.
+ */
+
+module.exports = exports = SchemaType;
+
+exports.CastError = CastError;
+
+exports.ValidatorError = ValidatorError;
diff --git a/node_modules/mongoose/lib/statemachine.js b/node_modules/mongoose/lib/statemachine.js
new file mode 100644
index 0000000..fb8ceb5
--- /dev/null
+++ b/node_modules/mongoose/lib/statemachine.js
@@ -0,0 +1,179 @@
+
+/**
+ * Module dependencies.
+ */
+
+var utils = require('./utils');
+
+/**
+ * StateMachine represents a minimal `interface` for the
+ * constructors it builds via StateMachine.ctor(...).
+ *
+ * @api private
+ */
+
+var StateMachine = module.exports = exports = function StateMachine () {
+ this.paths = {};
+ this.states = {};
+}
+
+/**
+ * StateMachine.ctor('state1', 'state2', ...)
+ * A factory method for subclassing StateMachine.
+ * The arguments are a list of states. For each state,
+ * the constructor's prototype gets state transition
+ * methods named after each state. These transition methods
+ * place their path argument into the given state.
+ *
+ * @param {String} state
+ * @param {String} [state]
+ * @return {Function} subclass constructor
+ * @private
+ */
+
+StateMachine.ctor = function () {
+ var states = utils.args(arguments);
+
+ var ctor = function () {
+ StateMachine.apply(this, arguments);
+ this.stateNames = states;
+
+ var i = states.length
+ , state;
+
+ while (i--) {
+ state = states[i];
+ this.states[state] = {};
+ }
+ };
+
+ ctor.prototype.__proto__ = StateMachine.prototype;
+
+ states.forEach(function (state) {
+ // Changes the `path`'s state to `state`.
+ ctor.prototype[state] = function (path) {
+ this._changeState(path, state);
+ }
+ });
+
+ return ctor;
+};
+
+/**
+ * This function is wrapped by the state change functions:
+ * - `require(path)`
+ * - `modify(path)`
+ * - `init(path)`
+ * @api private
+ */
+
+StateMachine.prototype._changeState = function _changeState (path, nextState) {
+ var prevState = this.paths[path]
+ , prevBucket = this.states[prevState];
+
+ delete this.paths[path];
+ if (prevBucket) delete prevBucket[path];
+
+ this.paths[path] = nextState;
+ this.states[nextState][path] = true;
+}
+
+StateMachine.prototype.stateOf = function stateOf (path) {
+ return this.paths[path];
+}
+
+StateMachine.prototype.clear = function clear (state) {
+ var keys = Object.keys(this.states[state])
+ , i = keys.length
+ , path
+
+ while (i--) {
+ path = keys[i];
+ delete this.states[state][path];
+ delete this.paths[path];
+ }
+}
+
+/**
+ * Checks to see if at least one path is in the states passed in via `arguments`
+ * e.g., this.some('required', 'inited')
+ * @param {String} state that we want to check for.
+ * @private
+ */
+
+StateMachine.prototype.some = function some () {
+ var self = this;
+ var what = arguments.length ? arguments : this.stateNames;
+ return Array.prototype.some.call(what, function (state) {
+ return Object.keys(self.states[state]).length;
+ });
+}
+
+/**
+ * This function builds the functions that get assigned to `forEach` and `map`,
+ * since both of those methods share a lot of the same logic.
+ *
+ * @param {String} iterMethod is either 'forEach' or 'map'
+ * @return {Function}
+ * @api private
+ */
+
+StateMachine.prototype._iter = function _iter (iterMethod) {
+ return function () {
+ var numArgs = arguments.length
+ , states = utils.args(arguments, 0, numArgs-1)
+ , callback = arguments[numArgs-1];
+
+ if (!states.length) states = this.stateNames;
+
+ var self = this;
+
+ var paths = states.reduce(function (paths, state) {
+ return paths.concat(Object.keys(self.states[state]));
+ }, []);
+
+ return paths[iterMethod](function (path, i, paths) {
+ return callback(path, i, paths);
+ });
+ };
+}
+
+/**
+ * Iterates over the paths that belong to one of the parameter states.
+ *
+ * The function profile can look like:
+ * this.forEach(state1, fn); // iterates over all paths in state1
+ * this.forEach(state1, state2, fn); // iterates over all paths in state1 or state2
+ * this.forEach(fn); // iterates over all paths in all states
+ *
+ * @param {String} [state]
+ * @param {String} [state]
+ * @param {Function} callback
+ * @private
+ */
+
+StateMachine.prototype.forEach = function forEach () {
+ this.forEach = this._iter('forEach');
+ return this.forEach.apply(this, arguments);
+}
+
+/**
+ * Maps over the paths that belong to one of the parameter states.
+ *
+ * The function profile can look like:
+ * this.forEach(state1, fn); // iterates over all paths in state1
+ * this.forEach(state1, state2, fn); // iterates over all paths in state1 or state2
+ * this.forEach(fn); // iterates over all paths in all states
+ *
+ * @param {String} [state]
+ * @param {String} [state]
+ * @param {Function} callback
+ * @return {Array}
+ * @private
+ */
+
+StateMachine.prototype.map = function map () {
+ this.map = this._iter('map');
+ return this.map.apply(this, arguments);
+}
+
diff --git a/node_modules/mongoose/lib/types/array.js b/node_modules/mongoose/lib/types/array.js
new file mode 100644
index 0000000..67f88b6
--- /dev/null
+++ b/node_modules/mongoose/lib/types/array.js
@@ -0,0 +1,422 @@
+
+/**
+ * Module dependencies.
+ */
+
+var EmbeddedDocument = require('./embedded');
+var Document = require('../document');
+var ObjectId = require('./objectid');
+
+/**
+ * Mongoose Array constructor.
+ * Values always have to be passed to the constructor to initialize, since
+ * otherwise MongooseArray#push will mark the array as modified to the parent.
+ *
+ * @param {Array} values
+ * @param {String} key path
+ * @param {Document} parent document
+ * @api private
+ * @see http://bit.ly/f6CnZU
+ */
+
+function MongooseArray (values, path, doc) {
+ var arr = [];
+ arr.push.apply(arr, values);
+ arr.__proto__ = MongooseArray.prototype;
+
+ arr._atomics = {};
+ arr.validators = [];
+ arr._path = path;
+
+ if (doc) {
+ arr._parent = doc;
+ arr._schema = doc.schema.path(path);
+ }
+
+ return arr;
+};
+
+/**
+ * Inherit from Array
+ */
+
+MongooseArray.prototype = new Array;
+
+/**
+ * Stores a queue of atomic operations to perform
+ *
+ * @api private
+ */
+
+MongooseArray.prototype._atomics;
+
+/**
+ * Parent owner document
+ *
+ * @api private
+ */
+
+MongooseArray.prototype._parent;
+
+/**
+ * Casts a member
+ *
+ * @api private
+ */
+
+MongooseArray.prototype._cast = function (value) {
+ var cast = this._schema.caster.cast
+ , doc = this._parent;
+
+ return cast.call(null, value, doc);
+};
+
+/**
+ * Marks this array as modified.
+ * It is called during a nonAtomicPush, an atomic opteration,
+ * or by an existing embedded document that is modified.
+ *
+ * If it bubbles up from an embedded document change,
+ * then it takes the following arguments (otherwise, takes
+ * 0 arguments)
+ * @param {EmbeddedDocument} embeddedDoc that invokes this method on the Array
+ * @param {String} embeddedPath is what changed inthe embeddedDoc
+ *
+ * @api public
+ */
+
+MongooseArray.prototype._markModified = function (embeddedDoc, embeddedPath) {
+ var parent = this._parent
+ , dirtyPath;
+
+ if (parent) {
+ if (arguments.length) {
+ // If an embedded doc bubbled up the change
+ dirtyPath = [this._path, this.indexOf(embeddedDoc), embeddedPath].join('.');
+ } else {
+ dirtyPath = this._path;
+ }
+ parent.markModified(dirtyPath);
+ }
+
+ return this;
+};
+
+/**
+ * Register an atomic operation with the parent
+ *
+ * @param {Array} operation
+ * @api private
+ */
+
+MongooseArray.prototype._registerAtomic = function (op, val) {
+ var atomics = this._atomics
+ if (op === '$pullAll' || op === '$pushAll' || op === '$addToSet') {
+ atomics[op] || (atomics[op] = []);
+ atomics[op] = atomics[op].concat(val);
+ } else if (op === '$pullDocs') {
+ var pullOp = atomics['$pull'] || (atomics['$pull'] = {})
+ , selector = pullOp['_id'] || (pullOp['_id'] = {'$in' : [] });
+ selector['$in'] = selector['$in'].concat(val);
+ } else {
+ atomics[op] = val;
+ }
+ this._markModified();
+ return this;
+};
+
+/**
+ * Returns true if we have to perform atomics for this, and no normal
+ * operations
+ *
+ * @api public
+ */
+
+MongooseArray.prototype.__defineGetter__('doAtomics', function () {
+ if (!(this._atomics && 'Object' === this._atomics.constructor.name)) {
+ return 0;
+ }
+
+ return Object.keys(this._atomics).length;
+});
+
+/**
+ * Pushes item/s to the array atomically. Overrides Array#push
+ *
+ * @param {Object} value
+ * @api public
+ */
+
+MongooseArray.prototype.$push =
+MongooseArray.prototype.push = function () {
+ var values = [].map.call(arguments, this._cast, this)
+ , ret = [].push.apply(this, values);
+
+ // $pushAll might be fibbed (could be $push). But it makes it easier to
+ // handle what could have been $push, $pushAll combos
+ this._registerAtomic('$pushAll', values);
+ return ret;
+};
+
+/**
+ * Pushes item/s to the array non-atomically
+ *
+ * @param {Object} value
+ * @api public
+ */
+
+MongooseArray.prototype.nonAtomicPush = function () {
+ var values = [].map.call(arguments, this._cast, this)
+ , ret = [].push.apply(this, values);
+ this._markModified();
+ return ret;
+};
+
+/**
+ * Pushes several items at once to the array atomically
+ *
+ * @param {Array} values
+ * @api public
+ */
+
+MongooseArray.prototype.$pushAll = function (value) {
+ var length = this.length;
+ this.nonAtomicPush.apply(this, value);
+ // make sure we access the casted elements
+ this._registerAtomic('$pushAll', this.slice(length));
+ return this;
+};
+
+/**
+ * Pops the array atomically
+ *
+ * @api public
+ */
+
+MongooseArray.prototype.$pop = function () {
+ this._registerAtomic('$pop', 1);
+ return this.pop();
+};
+
+/**
+ * Atomically shifts the array.
+ *
+ * Only works once per doc.save(). Calling this mulitple
+ * times on an array before saving is the same as calling
+ * it once.
+ *
+ * @api public
+ */
+
+MongooseArray.prototype.$shift = function () {
+ this._registerAtomic('$pop', -1);
+ return this.shift();
+};
+
+/**
+ * Removes items from an array atomically
+ *
+ * Examples:
+ * doc.array.remove(ObjectId)
+ * doc.array.remove('tag 1', 'tag 2')
+ *
+ * @param {Object} value to remove
+ * @api public
+ */
+
+MongooseArray.prototype.remove = function () {
+ var args = [].map.call(arguments, this._cast, this);
+ if (args.length == 1)
+ this.$pull(args[0]);
+ else
+ this.$pullAll(args);
+ return args;
+};
+
+/**
+ * Pulls from the array
+ *
+ * @api public
+ */
+
+MongooseArray.prototype.pull =
+MongooseArray.prototype.$pull = function () {
+ var values = [].map.call(arguments, this._cast, this)
+ , oldArr = this._parent.get(this._path)
+ , i = oldArr.length
+ , mem;
+
+ while (i--) {
+ mem = oldArr[i];
+ if (mem instanceof EmbeddedDocument) {
+ if (values.some(function (v) { return v.equals(mem); } )) {
+ oldArr.splice(i, 1);
+ }
+ } else if (~values.indexOf(mem)) {
+ oldArr.splice(i, 1);
+ }
+ }
+
+ if (values[0] instanceof EmbeddedDocument) {
+ this._registerAtomic('$pullDocs', values.map( function (v) { return v._id; } ));
+ } else {
+ this._registerAtomic('$pullAll', values);
+ }
+
+ return this;
+};
+
+/**
+ * Pulls many items from an array
+ *
+ * @api public
+ */
+
+MongooseArray.prototype.$pullAll = function (values) {
+ if (values && values.length) {
+ var oldArr = this._parent.get(this._path)
+ , i = oldArr.length, mem;
+ while (i--) {
+ mem = oldArr[i];
+ if (mem instanceof EmbeddedDocument) {
+ if (values.some( function (v) { return v.equals(mem); } )) {
+ oldArr.splice(i, 1);
+ }
+ } else if (~values.indexOf(mem)) oldArr.splice(i, 1);
+ }
+ if (values[0] instanceof EmbeddedDocument) {
+ this._registerAtomic('$pullDocs', values.map( function (v) { return v._id; } ));
+ } else {
+ this._registerAtomic('$pullAll', values);
+ }
+ }
+ return this;
+};
+
+/**
+ * Splices the array.
+ *
+ * Note: marks the _entire_ array as modified which
+ * will pass the entire thing to $set potentially
+ * overwritting any changes that happen between
+ * when you retrieved the object and when you save
+ * it.
+ *
+ * @api public
+ */
+
+MongooseArray.prototype.splice = function () {
+ var result = [].splice.apply(this, arguments);
+ this._markModified();
+ return result;
+};
+
+/**
+ * Non-atomically unshifts onto the array.
+ *
+ * Note: marks the _entire_ array as modified which
+ * will pass the entire thing to $set potentially
+ * overwritting any changes that happen between
+ * when you retrieved the object and when you save
+ * it.
+ *
+ * @api public
+ */
+
+MongooseArray.prototype.unshift = function () {
+ var values = [].map.call(arguments, this._cast, this);
+ [].unshift.apply(this, values);
+ this._markModified();
+ return this.length;
+};
+
+/**
+ * Adds values to the array if not already present.
+ * @api public
+ */
+
+MongooseArray.prototype.$addToSet =
+MongooseArray.prototype.addToSet = function addToSet () {
+ var values = [].map.call(arguments, this._cast, this)
+ , added = []
+ , type = values[0] instanceof EmbeddedDocument ? 'doc' :
+ values[0] instanceof Date ? 'date' :
+ '';
+
+ values.forEach(function (v) {
+ var found;
+ switch (type) {
+ case 'doc':
+ found = this.some(function(doc){ return doc.equals(v) });
+ break;
+ case 'date':
+ var val = +v;
+ found = this.some(function(d){ return +d === val });
+ break;
+ default:
+ found = ~this.indexOf(v);
+ }
+
+ if (!found) {
+ [].push.call(this, v);
+ this._registerAtomic('$addToSet', v);
+ [].push.call(added, v);
+ }
+ }, this);
+
+ return added;
+};
+
+/**
+ * Returns an Array
+ *
+ * @return {Array}
+ * @api public
+ */
+
+MongooseArray.prototype.toObject = function (options) {
+ if (options && options.depopulate && this[0] instanceof Document) {
+ return this.map(function (doc) {
+ return doc._id;
+ });
+ }
+
+ return this.map(function (doc) {
+ return doc;
+ });
+};
+
+/**
+ * Helper for console.log
+ *
+ * @api public
+ */
+
+MongooseArray.prototype.inspect = function () {
+ return '[' + this.map(function (doc) {
+ return ' ' + doc;
+ }) + ' ]';
+};
+
+/**
+ * Return the index of `obj` or `-1.`
+ *
+ * @param {Object} obj
+ * @return {Number}
+ * @api public
+ */
+
+MongooseArray.prototype.indexOf = function indexOf (obj) {
+ if (obj instanceof ObjectId) obj = obj.toString();
+ for (var i = 0, len = this.length; i < len; ++i) {
+ if (obj == this[i])
+ return i;
+ }
+ return -1;
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = exports = MongooseArray;
diff --git a/node_modules/mongoose/lib/types/buffer.js b/node_modules/mongoose/lib/types/buffer.js
new file mode 100644
index 0000000..9092f20
--- /dev/null
+++ b/node_modules/mongoose/lib/types/buffer.js
@@ -0,0 +1,171 @@
+
+/**
+ * Access driver.
+ */
+
+var driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native';
+
+/**
+ * Module dependencies.
+ */
+
+var Binary = require(driver + '/binary');
+
+/**
+ * Mongoose Buffer constructor.
+ * Values always have to be passed to the constructor to initialize, since
+ * otherwise MongooseBuffer#push will mark the buffer as modified to the parent.
+ *
+ * @param {Buffer} value
+ * @param {String} key path
+ * @param {Document} parent document
+ * @api private
+ * @see http://bit.ly/f6CnZU
+ */
+
+function MongooseBuffer (value, encode, offset) {
+ var length = arguments.length;
+ var val;
+
+ if (0 === length || null === arguments[0] || undefined === arguments[0]) {
+ val = 0;
+ } else {
+ val = value;
+ }
+
+ var encoding;
+ var path;
+ var doc;
+
+ if (Array.isArray(encode)) {
+ // internal casting
+ path = encode[0];
+ doc = encode[1];
+ } else {
+ encoding = encode;
+ }
+
+ var buf = new Buffer(val, encoding, offset);
+ buf.__proto__ = MongooseBuffer.prototype;
+
+ // make sure these internal props don't show up in Object.keys()
+ Object.defineProperties(buf, {
+ validators: { value: [] }
+ , _path: { value: path }
+ , _parent: { value: doc }
+ });
+
+ if (doc && "string" === typeof path) {
+ Object.defineProperty(buf, '_schema', {
+ value: doc.schema.path(path)
+ });
+ }
+
+ return buf;
+};
+
+/**
+ * Inherit from Buffer.
+ */
+
+MongooseBuffer.prototype = new Buffer(0);
+
+/**
+ * Parent owner document
+ *
+ * @api private
+ */
+
+MongooseBuffer.prototype._parent;
+
+
+/**
+* Marks this buffer as modified.
+*
+* @api public
+*/
+
+MongooseBuffer.prototype._markModified = function () {
+ var parent = this._parent;
+
+ if (parent) {
+ parent.markModified(this._path);
+ }
+ return this;
+};
+
+/**
+* Writes the buffer.
+*/
+
+MongooseBuffer.prototype.write = function () {
+ var written = Buffer.prototype.write.apply(this, arguments);
+
+ if (written > 0) {
+ this._markModified();
+ }
+
+ return written;
+};
+
+/**
+* Copy the buffer.
+*
+* Note: Buffer#copy will not mark target as modified so
+* you must copy from a MongooseBuffer for it to work
+* as expected.
+*
+* Work around since copy modifies the target, not this.
+*/
+
+MongooseBuffer.prototype.copy = function (target) {
+ var ret = Buffer.prototype.copy.apply(this, arguments);
+
+ if (target instanceof MongooseBuffer) {
+ target._markModified();
+ }
+
+ return ret;
+};
+
+/**
+ * Compile other Buffer methods marking this buffer as modified.
+ */
+
+;(
+// node < 0.5
+'writeUInt8 writeUInt16 writeUInt32 writeInt8 writeInt16 writeInt32 ' +
+'writeFloat writeDouble fill ' +
+'utf8Write binaryWrite asciiWrite set ' +
+
+// node >= 0.5
+'writeUInt16LE writeUInt16BE writeUInt32LE writeUInt32BE ' +
+'writeInt16LE writeInt16BE writeInt32LE writeInt32BE ' +
+'writeFloatLE writeFloatBE writeDoubleLE writeDoubleBE'
+).split(' ').forEach(function (method) {
+ if (!Buffer.prototype[method]) return;
+ MongooseBuffer.prototype[method] = new Function(
+ 'var ret = Buffer.prototype.'+method+'.apply(this, arguments);' +
+ 'this._markModified();' +
+ 'return ret;'
+ )
+});
+
+/**
+ * Returns a Binary.
+ *
+ * @return {Buffer}
+ * @api public
+ */
+
+MongooseBuffer.prototype.toObject = function () {
+ return new Binary(this, 0x00);
+};
+
+/**
+ * Module exports.
+ */
+
+MongooseBuffer.Binary = Binary;
+
+module.exports = MongooseBuffer;
diff --git a/node_modules/mongoose/lib/types/documentarray.js b/node_modules/mongoose/lib/types/documentarray.js
new file mode 100644
index 0000000..f3c66bb
--- /dev/null
+++ b/node_modules/mongoose/lib/types/documentarray.js
@@ -0,0 +1,133 @@
+
+/**
+ * Module dependencies.
+ */
+
+var MongooseArray = require('./array')
+ , driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native'
+ , ObjectId = require(driver + '/objectid')
+ , ObjectIdSchema = require('../schema/objectid');
+
+/**
+ * Array of embedded documents
+ * Values always have to be passed to the constructor to initialize, since
+ * otherwise MongooseArray#push will mark the array as modified to the parent.
+ *
+ * @param {Array} values
+ * @param {String} key path
+ * @param {Document} parent document
+ * @api private
+ * @see http://bit.ly/f6CnZU
+ */
+
+function MongooseDocumentArray (values, path, doc) {
+ var arr = [];
+ arr.push.apply(arr, values);
+ arr.__proto__ = MongooseDocumentArray.prototype;
+
+ arr._atomics = {};
+ arr.validators = [];
+ arr._path = path;
+
+ if (doc) {
+ arr._parent = doc;
+ arr._schema = doc.schema.path(path);
+ doc.on('save', arr.notify('save'));
+ doc.on('isNew', arr.notify('isNew'));
+ }
+
+ return arr;
+};
+
+/**
+ * Inherits from MongooseArray
+ */
+
+MongooseDocumentArray.prototype.__proto__ = MongooseArray.prototype;
+
+/**
+ * Overrides cast
+ *
+ * @api private
+ */
+
+MongooseDocumentArray.prototype._cast = function (value) {
+ var doc = new this._schema.caster(value, this);
+ return doc;
+};
+
+/**
+ * Filters items by id
+ *
+ * @param {Object} id
+ * @api public
+ */
+
+MongooseDocumentArray.prototype.id = function (id) {
+ try {
+ var casted = ObjectId.toString(ObjectIdSchema.prototype.cast.call({}, id));
+ } catch (e) {
+ var casted = null;
+ }
+
+ for (var i = 0, l = this.length; i < l; i++) {
+ if (!(this[i].get('_id') instanceof ObjectId)) {
+ if (String(id) == this[i].get('_id').toString())
+ return this[i];
+ } else {
+ if (casted == this[i].get('_id').toString())
+ return this[i];
+ }
+ }
+
+ return null;
+};
+
+/**
+ * Returns an Array and converts any Document
+ * members toObject.
+ *
+ * @return {Array}
+ * @api public
+ */
+
+MongooseDocumentArray.prototype.toObject = function () {
+ return this.map(function (doc) {
+ return doc && doc.toObject() || null;
+ });
+};
+
+/**
+ * Helper for console.log
+ *
+ * @api public
+ */
+
+MongooseDocumentArray.prototype.inspect = function () {
+ return '[' + this.map(function (doc) {
+ return doc && doc.inspect() || 'null';
+ }).join('\n') + ']';
+};
+
+/**
+ * Create fn that notifies all child docs of event.
+ *
+ * @param {String} event
+ * @api private
+ */
+
+MongooseDocumentArray.prototype.notify = function notify (event) {
+ var self = this;
+ return function notify (val) {
+ var i = self.length;
+ while (i--) {
+ self[i].emit(event, val);
+ }
+ }
+}
+
+/**
+ * Module exports.
+ */
+
+module.exports = MongooseDocumentArray;
diff --git a/node_modules/mongoose/lib/types/embedded.js b/node_modules/mongoose/lib/types/embedded.js
new file mode 100644
index 0000000..dff1fe3
--- /dev/null
+++ b/node_modules/mongoose/lib/types/embedded.js
@@ -0,0 +1,103 @@
+
+/**
+ * Module dependencies.
+ */
+
+var Document = require('../document')
+ , inspect = require('util').inspect;
+
+/**
+ * EmbeddedDocument constructor.
+ *
+ * @param {Object} object from db
+ * @param {MongooseDocumentArray} parent array
+ * @api private
+ */
+
+function EmbeddedDocument (obj, parentArr) {
+ this.parentArray = parentArr;
+ this.parent = parentArr._parent;
+ Document.call(this, obj);
+
+ var self = this;
+ this.on('isNew', function (val) {
+ self.isNew = val;
+ });
+};
+
+/**
+ * Inherit from Document
+ */
+
+EmbeddedDocument.prototype.__proto__ = Document.prototype;
+
+/**
+ * Marks parent array as modified
+ *
+ * @api private
+ */
+
+EmbeddedDocument.prototype.commit =
+EmbeddedDocument.prototype.markModified = function (path) {
+ this._activePaths.modify(path);
+
+ if (this.isNew) {
+ // Mark the WHOLE parent array as modified
+ // if this is a new document (i.e., we are initializing
+ // a document),
+ this.parentArray._markModified();
+ } else
+ this.parentArray._markModified(this, path);
+};
+
+/**
+ * Noop. Does not actually save the doc to the db.
+ *
+ * @api public
+ */
+
+EmbeddedDocument.prototype.save = function(fn) {
+ if (fn)
+ fn(null);
+ return this;
+};
+
+/**
+ * Remove the subdocument
+ *
+ * @api public
+ */
+
+EmbeddedDocument.prototype.remove = function (fn) {
+ var _id;
+ if (!this.willRemove) {
+ _id = this._doc._id;
+ if (!_id) {
+ throw new Error('For your own good, Mongoose does not know ' +
+ 'how to remove an EmbeddedDocument that has no _id');
+ }
+ this.parentArray.$pull({ _id: _id });
+ this.willRemove = true;
+ }
+
+ if (fn)
+ fn(null);
+
+ return this;
+};
+
+/**
+ * Helper for console.log
+ *
+ * @api public
+ */
+
+EmbeddedDocument.prototype.inspect = function () {
+ return inspect(this.toObject());
+};
+
+/**
+ * Module exports.
+ */
+
+module.exports = EmbeddedDocument;
diff --git a/node_modules/mongoose/lib/types/index.js b/node_modules/mongoose/lib/types/index.js
new file mode 100644
index 0000000..d07878f
--- /dev/null
+++ b/node_modules/mongoose/lib/types/index.js
@@ -0,0 +1,14 @@
+
+/**
+ * Module exports.
+ */
+
+exports.Array = require('./array');
+exports.Buffer = require('./buffer');
+
+exports.Document = // @deprecate
+exports.Embedded = require('./embedded');
+
+exports.DocumentArray = require('./documentarray');
+exports.Number = require('./number');
+exports.ObjectId = require('./objectid');
diff --git a/node_modules/mongoose/lib/types/number.js b/node_modules/mongoose/lib/types/number.js
new file mode 100644
index 0000000..b2a69b6
--- /dev/null
+++ b/node_modules/mongoose/lib/types/number.js
@@ -0,0 +1,84 @@
+
+/**
+ * Module dependencies.
+ */
+
+/**
+ * MongooseNumber constructor.
+ *
+ * @param {Object} value to pass to Number
+ * @param {Document} parent document
+ * @deprecated (remove in 3.x)
+ * @api private
+ */
+
+function MongooseNumber (value, path, doc) {
+ var number = new Number(value);
+ number.__proto__ = MongooseNumber.prototype;
+ number._atomics = {};
+ number._path = path;
+ number._parent = doc;
+ return number;
+};
+
+/**
+ * Inherits from Number.
+ */
+
+MongooseNumber.prototype = new Number();
+
+/**
+ * Atomic increment
+ *
+ * @api public
+ */
+
+MongooseNumber.prototype.$inc =
+MongooseNumber.prototype.increment = function increment (value) {
+ var schema = this._parent.schema.path(this._path)
+ , value = Number(value) || 1;
+ if (isNaN(value)) value = 1;
+ this._parent.setValue(this._path, schema.cast(this + value));
+ this._parent.getValue(this._path)._atomics['$inc'] = value || 1;
+ this._parent._activePaths.modify(this._path);
+ return this;
+};
+
+/**
+ * Returns true if we have to perform atomics for this, and no normal
+ * operations
+ *
+ * @api public
+ */
+
+MongooseNumber.prototype.__defineGetter__('doAtomics', function () {
+ return Object.keys(this._atomics).length;
+});
+
+/**
+ * Atomic decrement
+ *
+ * @api public
+ */
+
+MongooseNumber.prototype.decrement = function(){
+ this.increment(-1);
+};
+
+/**
+ * Re-declare toString (for `console.log`)
+ *
+ * @api public
+ */
+
+MongooseNumber.prototype.inspect =
+MongooseNumber.prototype.toString = function () {
+ return String(this.valueOf());
+};
+
+
+/**
+ * Module exports
+ */
+
+module.exports = MongooseNumber;
diff --git a/node_modules/mongoose/lib/types/objectid.js b/node_modules/mongoose/lib/types/objectid.js
new file mode 100644
index 0000000..e811fdf
--- /dev/null
+++ b/node_modules/mongoose/lib/types/objectid.js
@@ -0,0 +1,12 @@
+
+/**
+ * Access driver.
+ */
+
+var driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native';
+
+/**
+ * Module exports.
+ */
+
+module.exports = require(driver + '/objectid');
diff --git a/node_modules/mongoose/lib/utils.js b/node_modules/mongoose/lib/utils.js
new file mode 100644
index 0000000..2d8f8ee
--- /dev/null
+++ b/node_modules/mongoose/lib/utils.js
@@ -0,0 +1,434 @@
+/**
+ * Module dependencies.
+ */
+
+var EventEmitter = require('events').EventEmitter
+ , ObjectId = require('./types/objectid')
+ , MongooseBuffer
+ , MongooseArray
+ , Document
+
+/**
+ * Produces a collection name from a model name
+ *
+ * @param {String} model name
+ * @return {String} collection name
+ * @api private
+ */
+
+exports.toCollectionName = function (name) {
+ if ('system.profile' === name) return name;
+ if ('system.indexes' === name) return name;
+ return pluralize(name.toLowerCase());
+};
+
+/**
+ * Pluralization rules.
+ */
+
+var rules = [
+ [/(m)an$/gi, '$1en'],
+ [/(pe)rson$/gi, '$1ople'],
+ [/(child)$/gi, '$1ren'],
+ [/^(ox)$/gi, '$1en'],
+ [/(ax|test)is$/gi, '$1es'],
+ [/(octop|vir)us$/gi, '$1i'],
+ [/(alias|status)$/gi, '$1es'],
+ [/(bu)s$/gi, '$1ses'],
+ [/(buffal|tomat|potat)o$/gi, '$1oes'],
+ [/([ti])um$/gi, '$1a'],
+ [/sis$/gi, 'ses'],
+ [/(?:([^f])fe|([lr])f)$/gi, '$1$2ves'],
+ [/(hive)$/gi, '$1s'],
+ [/([^aeiouy]|qu)y$/gi, '$1ies'],
+ [/(x|ch|ss|sh)$/gi, '$1es'],
+ [/(matr|vert|ind)ix|ex$/gi, '$1ices'],
+ [/([m|l])ouse$/gi, '$1ice'],
+ [/(quiz)$/gi, '$1zes'],
+ [/s$/gi, 's'],
+ [/$/gi, 's']
+];
+
+/**
+ * Uncountable words.
+ */
+
+var uncountables = [
+ 'advice',
+ 'energy',
+ 'excretion',
+ 'digestion',
+ 'cooperation',
+ 'health',
+ 'justice',
+ 'labour',
+ 'machinery',
+ 'equipment',
+ 'information',
+ 'pollution',
+ 'sewage',
+ 'paper',
+ 'money',
+ 'species',
+ 'series',
+ 'rain',
+ 'rice',
+ 'fish',
+ 'sheep',
+ 'moose',
+ 'deer',
+ 'news'
+];
+
+/**
+ * Pluralize function.
+ *
+ * @author TJ Holowaychuk (extracted from _ext.js_)
+ * @param {String} string to pluralize
+ * @api private
+ */
+
+function pluralize (str) {
+ var rule, found;
+ if (!~uncountables.indexOf(str.toLowerCase())){
+ found = rules.filter(function(rule){
+ return str.match(rule[0]);
+ });
+ if (found[0]) return str.replace(found[0][0], found[0][1]);
+ }
+ return str;
+};
+
+/**
+ * Add `once` to EventEmitter if absent
+ *
+ * @param {String} event name
+ * @param {Function} listener
+ * @api private
+ */
+
+var Events = EventEmitter;
+
+if (!('once' in EventEmitter.prototype)){
+
+ Events = function () {
+ EventEmitter.apply(this, arguments);
+ };
+
+ /**
+ * Inherit from EventEmitter.
+ */
+
+ Events.prototype.__proto__ = EventEmitter.prototype;
+
+ /**
+ * Add `once`.
+ */
+
+ Events.prototype.once = function (type, listener) {
+ var self = this;
+ self.on(type, function g(){
+ self.removeListener(type, g);
+ listener.apply(this, arguments);
+ });
+ };
+
+}
+
+exports.EventEmitter = Events;
+
+// Modified from node/lib/assert.js
+exports.deepEqual = function deepEqual (a, b) {
+ if (a === b) return true;
+
+ if (a instanceof Date && b instanceof Date)
+ return a.getTime() === b.getTime();
+
+ if (a instanceof ObjectId && b instanceof ObjectId) {
+ return a.toString() === b.toString();
+ }
+
+ if (typeof a !== 'object' && typeof b !== 'object')
+ return a == b;
+
+ if (a === null || b === null || a === undefined || b === undefined)
+ return false
+
+ if (a.prototype !== b.prototype) return false;
+
+ // Handle MongooseNumbers
+ if (a instanceof Number && b instanceof Number) {
+ return a.valueOf() === b.valueOf();
+ }
+
+ if (Buffer.isBuffer(a)) {
+ if (!Buffer.isBuffer(b)) return false;
+ if (a.length !== b.length) return false;
+ for (var i = 0, len = a.length; i < len; ++i) {
+ if (a[i] !== b[i]) return false;
+ }
+ return true;
+ }
+
+ if (isMongooseObject(a)) a = a.toObject();
+ if (isMongooseObject(b)) b = b.toObject();
+
+ try {
+ var ka = Object.keys(a),
+ kb = Object.keys(b),
+ key, i;
+ } catch (e) {//happens when one is a string literal and the other isn't
+ return false;
+ }
+
+ // having the same number of owned properties (keys incorporates
+ // hasOwnProperty)
+ if (ka.length != kb.length)
+ return false;
+
+ //the same set of keys (although not necessarily the same order),
+ ka.sort();
+ kb.sort();
+
+ //~~~cheap key test
+ for (i = ka.length - 1; i >= 0; i--) {
+ if (ka[i] != kb[i])
+ return false;
+ }
+
+ //equivalent values for every corresponding key, and
+ //~~~possibly expensive deep test
+ for (i = ka.length - 1; i >= 0; i--) {
+ key = ka[i];
+ if (!deepEqual(a[key], b[key])) return false;
+ }
+
+ return true;
+};
+
+/**
+ * Object clone with Mongoose natives support.
+ * Creates a minimal data Object.
+ * It does not clone empty Arrays, empty Objects,
+ * and undefined values.
+ * This makes the data payload sent to MongoDB as minimal
+ * as possible.
+ *
+ * @param {Object} object to clone
+ * @param {Object} options - minimize , retainKeyOrder
+ * @return {Object} cloned object
+ * @api private
+ */
+
+var clone = exports.clone = function clone (obj, options) {
+ if (obj === undefined || obj === null)
+ return obj;
+
+ if (Array.isArray(obj))
+ return cloneArray(obj, options);
+
+ if (isMongooseObject(obj)) {
+ if (options && options.json && 'function' === typeof obj.toJSON) {
+ return obj.toJSON(options);
+ } else {
+ return obj.toObject(options);
+ }
+ }
+
+ if ('Object' === obj.constructor.name)
+ return cloneObject(obj, options);
+
+ if ('Date' === obj.constructor.name || 'Function' === obj.constructor.name)
+ return new obj.constructor(+obj);
+
+ if ('RegExp' === obj.constructor.name)
+ return new RegExp(obj.source);
+
+ if (obj instanceof ObjectId)
+ return ObjectId.fromString(ObjectId.toString(obj));
+
+ if (obj.valueOf)
+ return obj.valueOf();
+};
+
+function cloneObject (obj, options) {
+ var retainKeyOrder = options && options.retainKeyOrder
+ , minimize = options && options.minimize
+ , ret = {}
+ , hasKeys
+ , keys
+ , val
+ , k
+ , i
+
+ if (retainKeyOrder) {
+ for (k in obj) {
+ val = clone(obj[k], options);
+
+ if (!minimize || ('undefined' !== typeof val)) {
+ hasKeys || (hasKeys = true);
+ ret[k] = val;
+ }
+ }
+ } else {
+ // faster
+
+ keys = Object.keys(obj);
+ i = keys.length;
+
+ while (i--) {
+ k = keys[i];
+ val = clone(obj[k], options);
+
+ if (!minimize || ('undefined' !== typeof val)) {
+ if (!hasKeys) hasKeys = true;
+ ret[k] = val;
+ }
+ }
+ }
+
+ return minimize
+ ? hasKeys && ret
+ : ret;
+};
+
+function cloneArray (arr, options) {
+ var ret = [];
+ for (var i = 0, l = arr.length; i < l; i++)
+ ret.push(clone(arr[i], options));
+ return ret;
+};
+
+/**
+ * Copies and merges options with defaults.
+ *
+ * @param {Object} defaults
+ * @param {Object} options
+ * @return {Object} (merged) object
+ * @api private
+ */
+
+exports.options = function (defaults, options) {
+ var keys = Object.keys(defaults)
+ , i = keys.length
+ , k ;
+
+ options = options || {};
+
+ while (i--) {
+ k = keys[i];
+ if (!(k in options)) {
+ options[k] = defaults[k];
+ }
+ }
+
+ return options;
+};
+
+/**
+ * Generates a random string
+ *
+ * @api private
+ */
+
+exports.random = function () {
+ return Math.random().toString().substr(3);
+};
+
+exports.inGroupsOf = function inGroupsOf (card, arr, fn) {
+ var group = [];
+ for (var i = 0, l = arr.length; i < l; i++) {
+ if (i && i % card === 0) {
+ fn.apply(this, group);
+ group.length = 0;
+ }
+ group.push(arr[i]);
+ }
+ fn.apply(this, group);
+};
+
+/**
+ * Merges `from` into `to` without overwriting
+ * existing properties of `to`.
+ *
+ * @param {Object} to
+ * @param {Object} from
+ */
+
+exports.merge = function merge (to, from) {
+ var keys = Object.keys(from)
+ , i = keys.length
+ , key
+
+ while (i--) {
+ key = keys[i];
+ if ('undefined' === typeof to[key]) {
+ to[key] = from[key];
+ } else {
+ merge(to[key], from[key]);
+ }
+ }
+};
+
+/**
+ * A faster Array.prototype.slice.call(arguments) alternative
+ */
+
+exports.args = function (args, slice, sliceEnd) {
+ var ret = [];
+ var start = slice || 0;
+ var end = 3 === arguments.length
+ ? sliceEnd
+ : args.length;
+
+ for (var i = start; i < end; ++i) {
+ ret[i - start] = args[i];
+ }
+
+ return ret;
+}
+
+/**
+ * process.nextTick helper.
+ *
+ * Wraps `callback` in a try/catch + nextTick.
+ *
+ * -native has a habit of state corruption
+ * when an error is immediately thrown from within
+ * a collection callback.
+ *
+ * @param {Function} callback
+ * @api private
+ */
+
+exports.tick = function tick (callback) {
+ if ('function' !== typeof callback) return;
+ return function () {
+ try {
+ callback.apply(this, arguments);
+ } catch (err) {
+ // only nextTick on err to get out of
+ // the event loop and avoid state corruption.
+ process.nextTick(function () {
+ throw err;
+ });
+ }
+ }
+}
+
+/**
+ * Returns if `v` is a mongoose object that has
+ * a `toObject()` method we can use. This is for
+ * compatibility with libs like Date.js which do
+ * foolish things to Natives.
+ */
+
+var isMongooseObject = exports.isMongooseObject = function (v) {
+ Document || (Document = require('./document'));
+ MongooseArray || (MongooseArray = require('./types').Array);
+ MongooseBuffer || (MongooseBuffer = require('./types').Buffer);
+
+ return v instanceof Document ||
+ v instanceof MongooseArray ||
+ v instanceof MongooseBuffer
+}
diff --git a/node_modules/mongoose/lib/virtualtype.js b/node_modules/mongoose/lib/virtualtype.js
new file mode 100644
index 0000000..5779df7
--- /dev/null
+++ b/node_modules/mongoose/lib/virtualtype.js
@@ -0,0 +1,74 @@
+/**
+ * VirtualType constructor
+ *
+ * This is what mongoose uses to define virtual attributes via
+ * `Schema.prototype.virtual`
+ *
+ * @api public
+ */
+
+function VirtualType (options) {
+ this.getters = [];
+ this.setters = [];
+ this.options = options || {};
+}
+
+/**
+ * Adds a getter
+ *
+ * @param {Function} fn
+ * @return {VirtualType} this
+ * @api public
+ */
+
+VirtualType.prototype.get = function (fn) {
+ this.getters.push(fn);
+ return this;
+};
+
+/**
+ * Adds a setter
+ *
+ * @param {Function} fn
+ * @return {VirtualType} this
+ * @api public
+ */
+
+VirtualType.prototype.set = function (fn) {
+ this.setters.push(fn);
+ return this;
+};
+
+/**
+ * Applies getters
+ *
+ * @param {Object} value
+ * @param {Object} scope
+ * @api public
+ */
+
+VirtualType.prototype.applyGetters = function (value, scope) {
+ var v = value;
+ for (var l = this.getters.length - 1; l >= 0; l--){
+ v = this.getters[l].call(scope, v);
+ }
+ return v;
+};
+
+/**
+ * Applies setters
+ *
+ * @param {Object} value
+ * @param {Object} scope
+ * @api public
+ */
+
+VirtualType.prototype.applySetters = function (value, scope) {
+ var v = value;
+ for (var l = this.setters.length - 1; l >= 0; l--){
+ this.setters[l].call(scope, v);
+ }
+ return v;
+};
+
+module.exports = VirtualType;